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.
126 lines
4.1 KiB
GDScript
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
|