167 lines
5.9 KiB
GDScript
167 lines
5.9 KiB
GDScript
class_name DomainItem extends Control
|
|
|
|
## Custom control for individual domain rows in PanelDomainSelector
|
|
## Provides checkbox selection, domain label, and hover-revealed "Only" button
|
|
|
|
const DomainColorManager = preload("res://addons/loggie-console/scripts/domain_color_manager.gd")
|
|
|
|
# Signals
|
|
signal selection_changed(domain_name: String, is_selected: bool)
|
|
signal only_button_pressed(domain_name: String)
|
|
|
|
# UI Components - exported for scene tree assignment
|
|
@export var select_checkbox: CheckBox
|
|
@export var only_button: Button
|
|
@export var color_indicator: ColorRect
|
|
|
|
# Domain state
|
|
var _domain_name: String = ""
|
|
var _is_hovered: bool = false
|
|
var _color_manager: DomainColorManager
|
|
|
|
# UI Layout constants
|
|
const ITEM_MIN_WIDTH: int = 280
|
|
const ITEM_MIN_HEIGHT: int = 32
|
|
|
|
# Visibility constants for only button hover effect
|
|
const ONLY_BUTTON_ALPHA_HIDDEN: float = 0.0
|
|
const ONLY_BUTTON_ALPHA_VISIBLE: float = 1.0
|
|
|
|
## Initializes the domain item control with UI connections and hover behavior
|
|
##
|
|
## Sets up consistent sizing, signal connections for checkbox and button interactions,
|
|
## and configures mouse hover detection for the "Only" button visibility toggle.
|
|
## The only button starts hidden and becomes visible on hover with smooth alpha transition.
|
|
## Requires select_checkbox and only_button to be properly assigned via @export.
|
|
func _ready() -> void:
|
|
if not select_checkbox:
|
|
return
|
|
|
|
# Set minimum size for consistent layout
|
|
custom_minimum_size = Vector2(ITEM_MIN_WIDTH, ITEM_MIN_HEIGHT)
|
|
|
|
# Connect signals
|
|
select_checkbox.toggled.connect(_on_checkbox_toggled)
|
|
only_button.pressed.connect(_on_only_button_pressed)
|
|
|
|
# Setup hover detection on checkbox (which now contains the text)
|
|
select_checkbox.mouse_entered.connect(_on_mouse_entered)
|
|
select_checkbox.mouse_exited.connect(_on_mouse_exited)
|
|
|
|
# Also setup hover detection on the main control for complete coverage
|
|
mouse_entered.connect(_on_mouse_entered)
|
|
mouse_exited.connect(_on_mouse_exited)
|
|
|
|
|
|
# Initialize only button as hidden
|
|
only_button.modulate.a = ONLY_BUTTON_ALPHA_HIDDEN
|
|
only_button.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
|
|
## Set the domain color manager instance
|
|
func set_color_manager(color_manager: DomainColorManager) -> void:
|
|
_color_manager = color_manager
|
|
|
|
## Configures the domain item with a specific domain name and selection state
|
|
##
|
|
## Sets up the checkbox display text (shows "(default)" for empty domain names),
|
|
## configures tooltips for both checkbox and only button, and applies the initial
|
|
## selection state. This method should be called after the item is added to the scene tree.
|
|
##
|
|
## @param domain_name: The domain name to display and track
|
|
## @param is_selected: Whether the domain should start as selected
|
|
func setup_domain(domain_name: String, is_selected: bool = false) -> void:
|
|
_domain_name = domain_name
|
|
|
|
if select_checkbox:
|
|
var display_name = domain_name if not domain_name.is_empty() else "(default)"
|
|
|
|
# Update color indicator instead of modulating checkbox
|
|
if _color_manager and color_indicator:
|
|
var domain_color = _color_manager.get_domain_color(domain_name)
|
|
color_indicator.color = domain_color
|
|
|
|
select_checkbox.text = display_name
|
|
select_checkbox.tooltip_text = "Select/deselect domain: " + domain_name
|
|
select_checkbox.button_pressed = is_selected
|
|
|
|
if only_button:
|
|
only_button.text = "Only"
|
|
only_button.tooltip_text = "Select only this domain: " + domain_name
|
|
|
|
## Get the domain name for this item
|
|
func get_domain_name() -> String:
|
|
return _domain_name
|
|
|
|
## Updates the checkbox selection state without emitting signals
|
|
##
|
|
## Useful for programmatically setting the selection state during bulk operations
|
|
## like "Select All" or when loading from saved settings. Uses set_pressed_no_signal
|
|
## to avoid triggering selection_changed signals during these operations.
|
|
##
|
|
## @param is_selected: The new selection state for the checkbox
|
|
func set_selected(is_selected: bool) -> void:
|
|
if select_checkbox:
|
|
select_checkbox.set_pressed_no_signal(is_selected)
|
|
|
|
## Get current selection state
|
|
func is_selected() -> bool:
|
|
return select_checkbox.button_pressed if select_checkbox else false
|
|
|
|
## Private methods
|
|
|
|
func _on_checkbox_toggled(pressed: bool) -> void:
|
|
selection_changed.emit(_domain_name, pressed)
|
|
|
|
func _on_only_button_pressed() -> void:
|
|
only_button_pressed.emit(_domain_name)
|
|
|
|
|
|
func _on_mouse_entered() -> void:
|
|
_is_hovered = true
|
|
_set_only_button_visibility(true)
|
|
|
|
func _on_mouse_exited() -> void:
|
|
_is_hovered = false
|
|
_set_only_button_visibility(false)
|
|
|
|
## Controls the visibility and interaction of the "Only" button based on hover state
|
|
##
|
|
## Instantly toggles the button's alpha transparency and mouse filter to create
|
|
## a hover-reveal effect. When hidden, the button becomes completely transparent
|
|
## and ignores mouse input. When visible, it becomes fully opaque and interactive.
|
|
##
|
|
## @param show: Whether to show (true) or hide (false) the only button
|
|
func _set_only_button_visibility(show: bool) -> void:
|
|
if not only_button:
|
|
return
|
|
|
|
# Set visibility instantly - no animation
|
|
var target_alpha = ONLY_BUTTON_ALPHA_VISIBLE if show else ONLY_BUTTON_ALPHA_HIDDEN
|
|
var target_mouse_filter = Control.MOUSE_FILTER_PASS if show else Control.MOUSE_FILTER_IGNORE
|
|
|
|
only_button.modulate.a = target_alpha
|
|
only_button.mouse_filter = target_mouse_filter
|
|
|
|
func _gui_input(event: InputEvent) -> void:
|
|
# Handle keyboard navigation
|
|
if event is InputEventKey and event.pressed:
|
|
match event.keycode:
|
|
KEY_SPACE, KEY_ENTER:
|
|
if select_checkbox:
|
|
select_checkbox.button_pressed = not select_checkbox.button_pressed
|
|
_on_checkbox_toggled(select_checkbox.button_pressed)
|
|
accept_event()
|
|
KEY_O:
|
|
if event.ctrl_pressed: # Ctrl+O for "Only"
|
|
_on_only_button_pressed()
|
|
accept_event()
|
|
|
|
func _notification(what: int) -> void:
|
|
match what:
|
|
NOTIFICATION_FOCUS_ENTER:
|
|
# Add visual focus indication if needed
|
|
pass
|
|
NOTIFICATION_FOCUS_EXIT:
|
|
# Remove visual focus indication if needed
|
|
pass
|