Files
car-os/addons/loggie-console/scripts/components/domain_selector.gd
T

257 lines
8.8 KiB
GDScript
Raw Normal View History

2026-07-04 18:22:23 -06:00
class_name DomainSelector extends MenuButton
## Standalone domain selector component for filtering log messages by domain
## Provides clean interface with proper signal-based communication
const LoggieConsoleSettings = preload("res://addons/loggie-console/resources/loggie_console_settings.gd")
const DomainColorManager = preload("res://addons/loggie-console/scripts/domain_color_manager.gd")
# Signals
signal domains_changed(enabled_domains: Array[String])
# Properties
var _enabled_domains: Array[String] = []
var _all_domains: Array[String] = []
var _domain_popup: PopupMenu
var _color_manager: DomainColorManager
# Constants
const ALL_ITEM_ID = 0
const SEPARATOR_ID = 1
const DOMAIN_ID_OFFSET = 2
func _ready() -> void:
_domain_popup = get_popup()
_domain_popup.id_pressed.connect(_on_domain_selected)
_initialize_empty_state()
## Set the domain color manager instance
func set_color_manager(color_manager: DomainColorManager) -> void:
_color_manager = color_manager
## Initialize the selector with available domains
func set_domains(domains: Array[String]) -> void:
_all_domains = domains.duplicate()
_enabled_domains = domains.duplicate()
_rebuild_popup()
_update_button_text()
domains_changed.emit(_enabled_domains)
## Initialize the selector with all domains, but only enable selected ones
## Console domains appear normally but are unselected by default
func set_domains_with_console_unselected(all_domains: Array[String], enabled_domains: Array[String], console_domains: Array[String]) -> void:
_all_domains = all_domains.duplicate()
_enabled_domains = enabled_domains.duplicate()
_rebuild_popup_with_console_unselected(console_domains)
_update_button_text()
domains_changed.emit(_enabled_domains)
## Add a new domain to the selector (for dynamic discovery)
func add_domain(domain_name: String) -> void:
if domain_name.is_empty() or _all_domains.has(domain_name):
return
_all_domains.append(domain_name)
_enabled_domains.append(domain_name)
# Add new item to popup with color icon
var display_name = _get_domain_display_name(domain_name)
var color_icon = _create_domain_color_icon(domain_name)
var item_id = _get_domain_item_id(_all_domains.size() - 1)
_domain_popup.add_check_item(display_name, item_id)
_domain_popup.set_item_icon(item_id, color_icon)
_domain_popup.set_item_checked(item_id, true)
_update_all_checkbox()
_update_button_text()
domains_changed.emit(_enabled_domains)
## Get currently enabled domains
func get_enabled_domains() -> Array[String]:
return _enabled_domains.duplicate()
## Check if a domain is enabled
func is_domain_enabled(domain_name: String) -> bool:
return _enabled_domains.has(domain_name)
## Private methods
## Create colored icon for domain display in popup
func _create_domain_color_icon(domain_name: String, size: int = 12) -> ImageTexture:
var color: Color = Color.WHITE # Default color
if _color_manager:
color = _color_manager.get_domain_color(domain_name)
# Create a small colored square image
var image = Image.create(size, size, false, Image.FORMAT_RGBA8)
image.fill(color)
# Convert to texture
var texture: ImageTexture = ImageTexture.create_from_image(image)
return texture
## Get display name for domain (without color formatting)
func _get_domain_display_name(domain_name: String) -> String:
return domain_name if not domain_name.is_empty() else "(default)"
func _initialize_empty_state() -> void:
_domain_popup.clear()
_domain_popup.add_item("No domains available")
_domain_popup.set_item_disabled(0, true)
text = "Domains: None"
func _rebuild_popup() -> void:
_domain_popup.clear()
# Add "All" toggle
_domain_popup.add_check_item("All", ALL_ITEM_ID)
_domain_popup.set_item_checked(ALL_ITEM_ID, _enabled_domains.size() == _all_domains.size())
# Add separator
_domain_popup.add_separator()
# Add individual domain items with color icons
for i in range(_all_domains.size()):
var domain_name = _all_domains[i]
var display_name = _get_domain_display_name(domain_name)
var color_icon = _create_domain_color_icon(domain_name)
var item_id = _get_domain_item_id(i)
_domain_popup.add_check_item(display_name, item_id)
_domain_popup.set_item_icon(item_id, color_icon)
_domain_popup.set_item_checked(item_id, _enabled_domains.has(domain_name))
## Builds popup with console domain unselected by default (no separator)
func _rebuild_popup_with_console_unselected(console_domains: Array[String]) -> void:
_domain_popup.clear()
# Add "All" toggle (only for non-console domains)
_domain_popup.add_check_item("All", ALL_ITEM_ID)
var non_console_domains = []
for domain in _all_domains:
if not console_domains.has(domain):
non_console_domains.append(domain)
_domain_popup.set_item_checked(ALL_ITEM_ID, _enabled_domains.size() == non_console_domains.size())
# Add separator
_domain_popup.add_separator()
# Add all domain items in order with color icons
for i in range(_all_domains.size()):
var domain_name = _all_domains[i]
var display_name: String
# Use friendly name for console domain
if console_domains.has(domain_name):
display_name = "LoggieConsole" # Simplified name for console domain
else:
display_name = domain_name if not domain_name.is_empty() else "(default)"
# Create color icon for the domain
var color_icon = _create_domain_color_icon(domain_name)
var item_id = _get_domain_item_id(i)
_domain_popup.add_check_item(display_name, item_id)
_domain_popup.set_item_icon(item_id, color_icon)
_domain_popup.set_item_checked(item_id, _enabled_domains.has(domain_name))
func _on_domain_selected(id: int) -> void:
if id == ALL_ITEM_ID:
_toggle_all_domains()
else:
_toggle_individual_domain(id)
_update_all_checkbox()
_update_button_text()
domains_changed.emit(_enabled_domains)
func _toggle_all_domains() -> void:
var current_all_state = _domain_popup.is_item_checked(ALL_ITEM_ID)
var new_all_state = not current_all_state
# Update all checkbox
_domain_popup.set_item_checked(ALL_ITEM_ID, new_all_state)
# Update all domain checkboxes and enabled list
_enabled_domains.clear()
for i in range(_all_domains.size()):
var item_id = _get_domain_item_id(i)
_domain_popup.set_item_checked(item_id, new_all_state)
if new_all_state:
_enabled_domains.append(_all_domains[i])
func _toggle_individual_domain(id: int) -> void:
var domain_index = _get_domain_index_from_id(id)
if domain_index < 0 or domain_index >= _all_domains.size():
Loggie.msg("Invalid domain index %d for ID %d" % [domain_index, id]).domain(LoggieConsoleConstants.DOMAIN).warn()
return
var domain_name = _all_domains[domain_index]
var current_state = _domain_popup.is_item_checked(id)
var new_state = not current_state
# Update checkbox
_domain_popup.set_item_checked(id, new_state)
# Update enabled domains list
if new_state and not _enabled_domains.has(domain_name):
_enabled_domains.append(domain_name)
elif not new_state and _enabled_domains.has(domain_name):
_enabled_domains.erase(domain_name)
func _update_all_checkbox() -> void:
var all_enabled = _enabled_domains.size() == _all_domains.size()
_domain_popup.set_item_checked(ALL_ITEM_ID, all_enabled)
func _update_button_text() -> void:
var enabled_count = _enabled_domains.size()
var total_count = _all_domains.size()
if total_count == 0:
text = "Domains: None"
elif enabled_count == total_count:
text = "Domains: All"
elif enabled_count == 0:
text = "Domains: None"
elif enabled_count == 1:
var domain_name = _enabled_domains[0]
var display_name = _get_domain_display_name(domain_name)
text = "Domains: " + display_name
else:
text = "Domains: %d selected" % enabled_count
func _get_domain_item_id(domain_index: int) -> int:
return DOMAIN_ID_OFFSET + domain_index
func _get_domain_index_from_id(item_id: int) -> int:
return item_id - DOMAIN_ID_OFFSET
## Saves current domain selection state to persistent settings
## Param settings: The settings resource to populate with current domain state
func save_settings_to_resource(settings: LoggieConsoleSettings) -> void:
settings.enabled_domains = _enabled_domains.duplicate()
settings.all_known_domains = _all_domains.duplicate()
## Loads domain selection state from persistent settings and rebuilds UI
## Automatically validates that enabled domains still exist in the known domains list
## Param settings: The settings resource containing saved domain state
func load_settings_from_resource(settings: LoggieConsoleSettings) -> void:
_all_domains = settings.all_known_domains.duplicate()
_enabled_domains = settings.enabled_domains.duplicate()
# Remove any enabled domains that no longer exist in all_domains
var valid_enabled_domains: Array[String] = []
for domain in _enabled_domains:
if _all_domains.has(domain):
valid_enabled_domains.append(domain)
_enabled_domains = valid_enabled_domains
# Rebuild UI to reflect loaded state
if _all_domains.size() > 0:
_rebuild_popup()
_update_button_text()
else:
_initialize_empty_state()