StreamOverlay/lib/UI/line_edit_with_buttons.gd
Mario Steele 790695b9b5 Updated LineEditWithButtons
Added missing toggle for left button and right button. Fixed right
button icon setter.
Added dups of the stylebox for the line edit, as well as storing
original left and right content margins.
Updated resize to add to the content margins for left and right,
depending on if we are creating a left button, or right button.
Ensure that Button is a true flat button, with StyleBoxEmpty.
Added to spacer and container the mouse filter ignore, so that the text
field doesn't get covered by invisible controls.
2026-02-28 02:44:29 -06:00

126 lines
4.1 KiB
GDScript

@tool
extends LineEdit
class_name LineEditWithButtons
signal left_button_pressed()
signal left_button_toggled()
signal right_button_pressed()
signal right_button_toggled()
static var _empty_sb = StyleBoxEmpty.new()
@export_subgroup("Left Icon")
@export var left: Texture2D:
set(value):
left = value
if not is_node_ready(): return
if _left_btn and value == null:
_left_btn.queue_free()
return
if not _left_btn and value:
_left_btn = _create_button_icon(value)
_left_btn.toggle_mode = left_is_toggle
_left_btn.pressed.connect(left_button_pressed.emit)
_left_btn.toggled.connect(left_button_toggled.emit)
return
_left_btn.icon = value
@export var left_is_toggle: bool = false
@export_subgroup("Right Icon")
@export var right: Texture2D:
set(value):
right = value
if not is_node_ready(): return
if _right_btn and value == null:
_right_btn.queue_free()
return
if not _right_btn and value:
_right_btn = _create_button_icon(value)
_right_btn.toggle_mode = right_is_toggle
_right_btn.pressed.connect(right_button_pressed.emit)
_right_btn.toggled.connect(right_button_toggled.emit)
return
_right_btn.icon = value
@export var right_is_toggle: bool = false
var _left_btn: Button
var _right_btn: Button
var _container: HBoxContainer
var _spacer: Control
var _nsb: StyleBox
var _rosb: StyleBox
var _fsb: StyleBox
var _nsb_orig_left: float
var _nsb_orig_right: float
var _rosb_orig_left: float
var _rosb_orig_right: float
var _fsb_orig_left: float
var _fsb_orig_right: float
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
_container = HBoxContainer.new()
_spacer = Control.new()
_spacer.mouse_filter = Control.MOUSE_FILTER_IGNORE
_spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL
_container.mouse_filter = Control.MOUSE_FILTER_IGNORE
_container.add_child(_spacer)
add_child(_container)
if left != null:
_left_btn = _create_button_icon(left)
_left_btn.toggle_mode = left_is_toggle
_left_btn.pressed.connect(left_button_pressed.emit)
_left_btn.toggled.connect(left_button_toggled.emit)
if right != null:
_right_btn = _create_button_icon(right, -1)
_right_btn.toggle_mode = right_is_toggle
_right_btn.pressed.connect(right_button_pressed.emit)
_right_btn.toggled.connect(right_button_toggled.emit)
_nsb = get_theme_stylebox(&"normal").duplicate(true)
_rosb = get_theme_stylebox(&"read_only").duplicate(true)
_fsb = get_theme_stylebox(&"focus").duplicate(true)
_nsb_orig_left = _nsb.content_margin_left
_nsb_orig_right = _nsb.content_margin_right
_rosb_orig_left = _rosb.content_margin_left
_rosb_orig_right = _rosb.content_margin_right
_fsb_orig_left = _fsb.content_margin_left
_fsb_orig_right = _fsb.content_margin_right
add_theme_stylebox_override(&"normal", _nsb)
add_theme_stylebox_override(&"read_only", _rosb)
add_theme_stylebox_override(&"focus", _fsb)
item_rect_changed.connect(_handle_resize)
func _create_button_icon(icon_texture: Texture2D, pos: int = 0) -> Button:
var btn = Button.new()
btn.icon = icon_texture
btn.flat = true
btn.icon_alignment = HORIZONTAL_ALIGNMENT_CENTER
btn.vertical_icon_alignment = VERTICAL_ALIGNMENT_CENTER
btn.expand_icon = true
btn.custom_minimum_size = Vector2(0, size.y)
btn.ready.connect(func(): btn.icon = icon_texture)
btn.add_theme_stylebox_override(&"normal", _empty_sb)
btn.add_theme_stylebox_override(&"pressed", _empty_sb)
btn.add_theme_stylebox_override(&"hover", _empty_sb)
btn.add_theme_stylebox_override(&"disabled", _empty_sb)
btn.add_theme_stylebox_override(&"focus", _empty_sb)
_container.add_child(btn)
_container.move_child(btn, pos)
return btn
func _handle_resize() -> void:
_container.size = size
if _left_btn:
_left_btn.custom_minimum_size = Vector2(size.y, size.y)
_fsb.content_margin_left = _fsb_orig_left + size.y
_rosb.content_margin_left = _rosb_orig_left + size.y
_nsb.content_margin_left = _nsb_orig_left + size.y
if _right_btn:
_right_btn.custom_minimum_size = Vector2(size.y, size.y)
_fsb.content_margin_right = _fsb_orig_right + size.y
_rosb.content_margin_right = _rosb_orig_right + size.y
_nsb.content_margin_right = _nsb_orig_right + size.y