257 lines
8.8 KiB
GDScript
257 lines
8.8 KiB
GDScript
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()
|