Palette Overlay UI
Relevant source files
Purpose and Scope
Section titled “Purpose and Scope”This page documents the TajsModPaletteOverlay class, which implements the visual interface for the command palette system. It covers UI construction, display modes, search integration, and input handling. For the command registration and execution system that powers this UI, see Command Definitions and Registry. For the overall command palette architecture, see Command Palette System.
Architecture Overview
Section titled “Architecture Overview”The TajsModPaletteOverlay extends CanvasLayer and provides a modal overlay with search capabilities, results display, and keyboard/mouse navigation. It operates in three distinct modes: normal command palette, node picker (for wire-drop feature), and group picker (for jump-to-group navigation).
| Component | Type | Purpose |
|---|---|---|
TajsModPaletteOverlay | CanvasLayer | Root container at z-layer 100 |
background | ColorRect | Semi-transparent backdrop for modal behavior |
panel | PanelContainer | Centered main UI panel (600×500px) |
search_input | LineEdit | Fuzzy search text field |
results_container | VBoxContainer | Scrollable list of command/item results |
breadcrumb_label | Label | Navigation path display in footer |
_onboarding_hint | Control | First-time user guidance panel |
Sources: extensions/scripts/palette/palette_overlay.gd L1-L72
UI Component Hierarchy
Section titled “UI Component Hierarchy”flowchart TD Overlay["TajsModPaletteOverlay<br>(CanvasLayer layer=100)"] Background["background<br>(ColorRect)"] Panel["panel<br>(PanelContainer)"] VBox["VBoxContainer"] Header["Header<br>(MarginContainer)"] SearchHBox["HBoxContainer"] SearchIcon["🔍 Label"] SearchInput["search_input<br>(LineEdit)"] ResultsScroll["results_scroll<br>(ScrollContainer)"] ResultsContainer["results_container<br>(VBoxContainer)"] OnboardingHint["_onboarding_hint<br>(PanelContainer)"] NoResults["no_results_label<br>(Label)"] ResultRow1["Result Row 1"] ResultRow2["Result Row 2"] ResultRowN["Result Row N"] Footer["Footer<br>(PanelContainer)"] FooterHBox["HBoxContainer"] Breadcrumb["breadcrumb_label<br>(Label)"] HintLabel["Hint Label"] Overlay --> Background Overlay --> Panel Panel --> VBox VBox --> Header VBox --> ResultsScroll VBox --> Footer Header --> SearchHBox SearchHBox --> SearchIcon SearchHBox --> SearchInput ResultsScroll --> ResultsContainer ResultsContainer --> OnboardingHint ResultsContainer --> NoResults ResultsContainer --> ResultRow1 ResultsContainer --> ResultRow2 ResultsContainer --> ResultRowN Footer --> FooterHBox FooterHBox --> Breadcrumb FooterHBox --> HintLabel
Sources: extensions/scripts/palette/palette_overlay.gd L96-L171
extensions/scripts/palette/palette_overlay.gd L174-L212
extensions/scripts/palette/palette_overlay.gd L215-L247
Display Modes
Section titled “Display Modes”The overlay operates in three mutually exclusive modes, controlled by boolean flags:
| Mode | Flag | Trigger | Purpose |
|---|---|---|---|
| Normal | Default state | MMB or toggle_palette() | Browse and execute commands from registry |
| Node Picker | _picker_mode = true | Wire dropped on empty canvas | Display compatible nodes for connection |
| Group Picker | _group_picker_mode = true | ”Jump to Group” command | List all node groups for navigation |
Mode State Machine
Section titled “Mode State Machine”stateDiagram-v2
[*] --> Closed : "show_palette()"
Closed --> Normal : "show_palette()"
Closed --> NodePicker : "hide_palette()or node_selected"
Closed --> GroupPicker : "show_group_picker()"
Normal --> Closed : "show_palette()"
Normal --> NodePicker : "hide_palette()or node_selected"
Normal --> GroupPicker : "show_group_picker()"
NodePicker --> Closed : "hide_palette()or node_selected"
NodePicker --> Normal : "show_palette()"
GroupPicker --> Closed : "show_group_picker()"
GroupPicker --> Normal : "show_group_picker()"
Closed --> [*] : "hide_palette()or node_selected"
Sources: extensions/scripts/palette/palette_overlay.gd L38-L46
extensions/scripts/palette/palette_overlay.gd L335-L398
Normal Mode Implementation
Section titled “Normal Mode Implementation”In normal mode, the overlay displays commands from the registry, organized by categories with breadcrumb navigation.
flowchart TD ShowPalette["show_palette()"] Refresh["context.refresh()"] ShowHome["_show_home_screen()"] DisplayItems["_display_items()"] CreateRows["_create_result_row()"] UpdateSelection["_update_selection()"] ShowPalette --> Refresh Refresh --> ShowHome ShowHome --> DisplayItems DisplayItems --> CreateRows CreateRows --> UpdateSelection
The home screen displays:
- Favorites (if configured via
palette_config.get_favorites()) - Recent commands (up to 5, via
palette_config.get_recents()) - Root categories (from
registry.get_root_items())
Sources: extensions/scripts/palette/palette_overlay.gd L335-L368
extensions/scripts/palette/palette_overlay.gd L627-L673
Node Picker Mode Implementation
Section titled “Node Picker Mode Implementation”Node picker mode is activated when a wire is dropped on empty canvas space. It filters and displays nodes compatible with the wire’s origin pin.
flowchart TD WireDrop["Wire dropped<br>on empty canvas"] Controller["PaletteController<br>identifies compatible nodes"] ShowPicker["show_node_picker(<br>compatible_nodes,<br>origin_info,<br>spawn_position)"] SetState["Set _picker_mode = true<br>Store origin_info<br>Store spawn_position"] DisplayPicker["_display_picker_nodes()"] CreateItems["Convert node data<br>to display format"] UserSelect["User selects node"] EmitSignal["emit node_selected<br>(node_id, position, origin_info)"] SpawnAndConnect["Controller spawns<br>and connects node"] WireDrop --> Controller Controller --> ShowPicker ShowPicker --> SetState SetState --> DisplayPicker DisplayPicker --> CreateItems CreateItems --> UserSelect UserSelect --> EmitSignal EmitSignal --> SpawnAndConnect
Key state stored during node picker mode:
_picker_origin_info: Dictionary containing wire connection details (is_output, pin type)_picker_spawn_position: Vector2 for where to create the new node_picker_nodes: Array of compatible node definitions
Sources: extensions/scripts/palette/palette_overlay.gd L401-L428
extensions/scripts/palette/palette_overlay.gd L432-L463
extensions/scripts/palette/palette_overlay.gd L1018-L1031
Group Picker Mode Implementation
Section titled “Group Picker Mode Implementation”Group picker mode displays all node groups on the desktop for quick camera navigation.
flowchart TD JumpCmd["Jump to Group command"] GetGroups["goto_group_manager<br>.get_all_groups()"] ShowGroupPicker["show_group_picker(<br>groups,<br>goto_group_manager)"] SetState["Set _group_picker_mode = true<br>Store groups array<br>Store manager reference"] DisplayGroups["_display_group_picker()"] FormatItems["Format groups<br>with names and icons"] UserSelect["User selects group"] EmitSignal["emit group_selected(group)"] Navigate["goto_group_manager<br>.navigate_to_group()"] JumpCmd --> GetGroups GetGroups --> ShowGroupPicker ShowGroupPicker --> SetState SetState --> DisplayGroups DisplayGroups --> FormatItems FormatItems --> UserSelect UserSelect --> EmitSignal EmitSignal --> Navigate
Sources: extensions/scripts/palette/palette_overlay.gd L500-L533
extensions/scripts/palette/palette_overlay.gd L537-L587
extensions/scripts/palette/default_commands.gd L162-L193
Search and Filtering System
Section titled “Search and Filtering System”The overlay uses a debounced search system with mode-specific filtering logic.
Search Pipeline
Section titled “Search Pipeline”flowchart TD Input["User types in<br>search_input"] OnChange["_on_search_changed()"] StartTimer["Start _debounce_timer<br>(30ms)"] Timeout["Timer timeout"] PerformSearch["_perform_search()"] ModeCheck["Check mode"] NormalSearch["FuzzySearch.search()<br>on all commands"] PickerFilter["_filter_picker_nodes()"] GroupFilter["_filter_group_picker()"] Display["Display filtered results"] Input --> OnChange OnChange --> StartTimer StartTimer --> Timeout Timeout --> PerformSearch PerformSearch --> ModeCheck ModeCheck --> NormalSearch ModeCheck --> PickerFilter ModeCheck --> GroupFilter NormalSearch --> Display PickerFilter --> Display GroupFilter --> Display
Sources: extensions/scripts/palette/palette_overlay.gd L323-L328
extensions/scripts/palette/palette_overlay.gd L856-L889
Fuzzy Search Integration
Section titled “Fuzzy Search Integration”In normal mode, search delegates to FuzzySearch.search() for intelligent matching:
| Search Feature | Implementation |
|---|---|
| Algorithm | Uses FuzzySearch preload from fuzzy_search.gd |
| Input | Query string, all executable commands, context, max results |
| Scoring | Keywords, title matching, category relevance |
| Filtering | Respects can_run() and tools visibility from context |
| Max Results | 10 items (MAX_VISIBLE_ITEMS) |
Sources: extensions/scripts/palette/palette_overlay.gd L11
extensions/scripts/palette/palette_overlay.gd L881-L889
Mode-Specific Filtering
Section titled “Mode-Specific Filtering”Node Picker Filtering (_filter_picker_nodes):
- Searches node
name,description, andcategoryfields - Case-insensitive substring matching
- No fuzzy scoring (exact substring required)
Group Picker Filtering (_filter_group_picker):
- Retrieves group names via
goto_group_manager.get_group_name() - Fallback to
get_window_name()orcustom_nameproperty - Case-insensitive substring matching
Sources: extensions/scripts/palette/palette_overlay.gd L477-L493
extensions/scripts/palette/palette_overlay.gd L596-L620
Result Row Construction
Section titled “Result Row Construction”Each result item is rendered as a styled PanelContainer with dynamic content based on the item’s properties.
Row Component Structure
Section titled “Row Component Structure”flowchart TD Row["PanelContainer<br>(50px height)"] Margin["MarginContainer<br>(12px margins)"] HBox["HBoxContainer"] Indicator["Favorite ★<br>or Recent ⏱"] Icon["TextureRect<br>(24×24px)"] Title["Label<br>(18pt font)"] Path["Category path<br>(12pt gray)"] Arrow["→ indicator"] Badge["[SAFE/OPT-IN]<br>(12pt colored)"] Row --> Margin Margin --> HBox HBox --> Indicator HBox --> Icon HBox --> Title HBox --> Path HBox --> Arrow HBox --> Badge
Row Creation Logic
Section titled “Row Creation Logic”The _create_result_row() method builds each row with conditional elements:
| Element | Condition | Appearance |
|---|---|---|
| Favorite star | item._is_favorite == true | ★ (yellow, 16pt) |
| Recent clock | item._is_recent == true | ⏱ (gray, 14pt) |
| Icon | item.icon_path exists and loadable | 24×24px texture |
| Title | Always shown | Dynamic via get_title() callable or title field |
| Category path | Not empty and at home screen | ”Cat1 > Cat2” format |
| Arrow indicator | item.is_category == true | → symbol |
| Badge | Always shown | [SAFE], [OPT-IN], or [GAMEPLAY] |
Dynamic Title Support: Commands can provide a get_title callable that returns the current title, enabling dynamic labels like “Wire Drop Menu [ON]” that reflect real-time state.
Sources: extensions/scripts/palette/palette_overlay.gd L725-L819
Selection and Styling
Section titled “Selection and Styling”The _update_selection() method applies visual feedback to the selected row:
flowchart TD UpdateSel["_update_selection()"] Loop["For each row in _result_items"] Check["i == _selected_index?"] Selected["bg_color = COLOR_SELECTED<br>border = 1px blue<br>border_color = rgba(0.4,0.6,0.8,0.6)"] Unselected["bg_color = rgba(0.1,0.12,0.16,0.3)<br>border = 0px"] Scroll["results_scroll.ensure_control_visible()"] UpdateSel --> Loop Loop --> Check Check --> Selected Check --> Unselected Selected --> Scroll Unselected --> Loop
Sources: extensions/scripts/palette/palette_overlay.gd L822-L842
Navigation and Input Handling
Section titled “Navigation and Input Handling”Keyboard Shortcuts
Section titled “Keyboard Shortcuts”The overlay implements comprehensive keyboard navigation in _on_search_input():
| Key | Action | Implementation |
|---|---|---|
| Escape | Close palette | hide_palette() |
| Enter | Execute selected item | _execute_selected() |
| ↑ | Previous item | _select_previous() |
| ↓ | Next item | _select_next() |
| → or Tab | Enter category | _enter_category() |
| ← or Backspace | Go back | _go_back() if search is empty |
| Ctrl+F | Toggle favorite | _toggle_favorite_selected() |
| Ctrl+A | Select all text | search_input.select_all() |
Sources: extensions/scripts/palette/palette_overlay.gd L896-L940
Mouse Input
Section titled “Mouse Input”Background clicks: Clicking the dimmed background closes the palette via _on_background_input().
Row interaction:
- Hover: Sets
_selected_indexvia_on_item_hover() - Click: Executes item via
_on_item_click()
Mouse button navigation:
- X1 (back button):
_go_back() - X2 (forward button):
_enter_category()
Sources: extensions/scripts/palette/palette_overlay.gd L943-L964
Category Navigation with History
Section titled “Category Navigation with History”The overlay maintains forward/backward history stacks for breadcrumb-style navigation:
flowchart TD EnterCat["_enter_category()"] PushBack["Push _current_path<br>to _history_back"] ClearFwd["Clear _history_forward"] Navigate["Append category to path<br>Show new category"] GoBack["_go_back()"] CheckBack["_history_back<br>empty?"] PopLevel["Pop from _current_path"] PopHistory["Pop from _history_back"] PushFwd["Push to _history_forward"] ShowCat["Show category or home"] EnterCat --> PushBack PushBack --> ClearFwd ClearFwd --> Navigate GoBack --> CheckBack CheckBack --> PopLevel CheckBack --> PopHistory PopHistory --> PushFwd PopLevel --> PushFwd PushFwd --> ShowCat
Sources: extensions/scripts/palette/palette_overlay.gd L1050-L1088
Execution Flow
Section titled “Execution Flow”Command Execution
Section titled “Command Execution”sequenceDiagram
participant User
participant TajsModPaletteOverlay
participant TajsModCommandRegistry
participant TajsModPaletteConfig
participant TajsModContextProvider
User->>TajsModPaletteOverlay: Press Enter on selected item
TajsModPaletteOverlay->>TajsModPaletteOverlay: _execute_selected()
loop [keep_open ==
TajsModPaletteOverlay->>TajsModPaletteOverlay: _enter_category()
TajsModPaletteOverlay->>TajsModCommandRegistry: run(command_id, context)
TajsModCommandRegistry->>TajsModContextProvider: Validate can_run()
TajsModContextProvider-->>TajsModCommandRegistry: true
TajsModCommandRegistry->>TajsModCommandRegistry: Execute command.run(ctx)
TajsModCommandRegistry-->>TajsModPaletteOverlay: true
TajsModPaletteOverlay->>TajsModPaletteConfig: add_recent(command_id)
TajsModPaletteOverlay->>TajsModPaletteOverlay: emit command_executed
TajsModPaletteOverlay->>TajsModPaletteOverlay: hide_palette()
TajsModPaletteOverlay->>TajsModPaletteOverlay: emit node_selected(node_id, position, origin_info)
TajsModPaletteOverlay->>TajsModPaletteOverlay: hide_palette()
TajsModPaletteOverlay->>TajsModPaletteOverlay: emit group_selected(group)
TajsModPaletteOverlay->>TajsModPaletteOverlay: hide_palette()
end
Sources: extensions/scripts/palette/palette_overlay.gd L981-L1048
State Management
Section titled “State Management”Core State Variables
Section titled “Core State Variables”| Variable | Type | Purpose |
|---|---|---|
_is_open | bool | Whether palette is currently visible |
_current_path | Array[String] | Current category breadcrumb path |
_displayed_items | Array[Dictionary] | Items currently shown in results |
_selected_index | int | Index of highlighted result row |
_result_items | Array[Control] | UI node references for result rows |
_history_back | Array | Navigation history for back button |
_history_forward | Array | Navigation history for forward button |
Mode-Specific State
Section titled “Mode-Specific State”Node Picker State:
_picker_mode: bool flag_picker_origin_info: Dictionary withis_output, pin type_picker_spawn_position: Vector2 for node creation_picker_nodes: Array[Dictionary] of compatible node definitions
Group Picker State:
_group_picker_mode: bool flag_group_picker_groups: Array of group node references"goto_group_manager"metadata: Reference toGotoGroupManagerinstance
Sources: extensions/scripts/palette/palette_overlay.gd L27-L46
Styling and Theming
Section titled “Styling and Theming”Color Palette
Section titled “Color Palette”The overlay defines semantic colors as class constants:
| Constant | Value | Usage |
|---|---|---|
COLOR_BG_DIM | rgba(0,0,0,0.6) | Modal background overlay |
COLOR_SELECTED | rgba(0.2,0.4,0.6,0.8) | Selected result row highlight |
COLOR_HOVER | rgba(0.15,0.25,0.35,0.5) | Row hover state |
COLOR_BADGE_SAFE | rgb(0.3,0.7,0.4) | [SAFE] badge (green) |
COLOR_BADGE_OPTIN | rgb(0.85,0.65,0.2) | [OPT-IN] badge (orange) |
COLOR_BADGE_GAMEPLAY | rgb(0.8,0.3,0.3) | [GAMEPLAY] badge (red) |
COLOR_TEXT_SHADOW | rgba(0,0,0,0.8) | Text shadow/outline |
COLOR_TEXT_GLOW | rgba(0.4,0.65,1.0,0.5) | Text outline glow effect |
Sources: extensions/scripts/palette/palette_overlay.gd L54-L62
Panel Styling
Section titled “Panel Styling”The main panel uses StyleBoxFlat with rounded corners and shadow:
Background: rgba(0.08, 0.1, 0.14, 0.95)Border: 2px rgba(0.3, 0.5, 0.7, 0.6)Corner Radius: 12px (all corners)Shadow: 10px rgba(0, 0, 0, 0.5)Theme Integration: If res://themes/main.tres exists, it is applied to the panel for consistent font rendering with the base game.
Sources: extensions/scripts/palette/palette_overlay.gd L96-L134
Text Styling
Section titled “Text Styling”The _apply_text_style() helper applies outline-based glow effects:
# Glow effect via outlineoutline_size: 5font_outline_color: COLOR_TEXT_GLOW (for glowing labels)Applied to:
- Command titles (with glow)
- Category paths (shadow only, no glow)
- Breadcrumbs (shadow only)
Sources: extensions/scripts/palette/palette_overlay.gd L89-L94
Onboarding System
Section titled “Onboarding System”The overlay includes a first-time user hint panel that displays keyboard shortcuts and features.
Onboarding Flow
Section titled “Onboarding Flow”flowchart TD ShowPalette["show_palette()"] CheckOnboard["palette_config<br>.is_onboarded()?"] ShowHint["Display _onboarding_hint"] HideHint["Hide _onboarding_hint"] UserDismiss["User clicks 'Got it!'"] SetFlag["palette_config<br>.set_onboarded(true)"] ShowPalette --> CheckOnboard CheckOnboard --> ShowHint CheckOnboard --> HideHint ShowHint --> UserDismiss UserDismiss --> SetFlag
Manual Trigger: The “Palette Help” command can re-display the hint via show_onboarding_hint().
Hint Content:
- MMB (Middle Mouse) to open/close
- ↑↓ navigate, Enter select, Esc close
- Ctrl+F toggle favorite
- Wire drop → Node Picker feature
Sources: extensions/scripts/palette/palette_overlay.gd L250-L321
extensions/scripts/palette/palette_overlay.gd L355-L361
extensions/scripts/palette/default_commands.gd L878-L890
Signals
Section titled “Signals”The overlay emits three signals for communication with the controller layer:
| Signal | Parameters | Purpose |
|---|---|---|
command_executed | command_id: String | Notify that a command was run |
node_selected | window_id: String, spawn_pos: Vector2, origin_info: Dictionary | Request node spawn in picker mode |
group_selected | group | Request navigation to group in group picker mode |
closed | None | Notify that palette was hidden |
Sources: extensions/scripts/palette/palette_overlay.gd L64-L67
Lifecycle Methods
Section titled “Lifecycle Methods”| Method | Called By | Purpose |
|---|---|---|
_init() | Godot | Set layer = 100, name node |
_ready() | Godot | Build UI, setup debounce timer |
setup() | PaletteController | Inject dependencies (registry, context, config) |
show_palette() | PaletteController | Display in normal mode |
hide_palette() | User input or command execution | Close and reset state |
toggle_palette() | Input handler | Open/close based on current state |
Sources: extensions/scripts/palette/palette_overlay.gd L70-L87