Keyboard Help & Binding System¶
This document describes the interactive keyboard help overlay and the underlying AppBindingRegistry system.
Overview¶
The help system provides a modern, interactive visualization of the application's key bindings. It consists of two main parts:
AppBindingRegistry: A centralized data structure that stores all key metadata (key, modifiers, category, description).- Help Overlay UI: A dynamic keyboard layout renderer that uses the registry to highlight active keys and show their functionality. It features a Cyberpunk aesthetic using pre-rendered PNGs and procedural SDF (Signed Distance Field) effects.
Visual Design & Polish¶
The help overlay utilizes an advanced hybrid rendering approach defined in src/app_ui.c and shaders/ui.frag:
- Cyberpunk Textures: The base panel UI frame and individual keys are rendered using high-quality PNG textures (
kbd_panel_frame.pngandkbd_key_base.png). Unbound keys sit quietly in the background, while bound keys are tinted via shader according to their binding type constraint (Toggle, Cycle, Combo). - Procedural Neon Bloom: When a key is pressed, an intense, procedural SDF neon border glow is drawn directly by
ui.frag(Mode5.0). The intensity of the glow follows a mathematically precise exponential decay for a crisp, luminous look. - Responsive UI Scaling: The entire overlay scales dynamically based on the window height. A
ui_scalefactor is calculated relative to a reference resolution (1080p), ensuring the overlay remains perfectly proportioned and legible on any screen size (from 720p to 4K). - Scalable Text Rendering: Uses
ui_draw_text_scaled()to render Freetype glyphs with on-the-fly metric scaling (width, height, advance, and offsets). This allows text to scale perfectly with the UI shapes without requiring multiple font rasterization passes. - Spotlight Dimming & Hover Decay: Activating or hovering over a key smoothly dims the rest of the keyboard. To prevent flickering when the mouse passes over gaps between keys, a 150ms Hover Decay timer maintains the dimmed state for a smooth visual experience.
- Smart Modifier Highlighting: The overlay actively queries the binding registry to determine whether a combination of keys relies on a given modifier (e.g.
Shift). Pressing physical modifier keys alone, or paired carelessly with non-modifier keys, won't artificially light up the Shift key unless the active function strictly demands it.
Architecture¶
Centralized Registry¶
All bindings are defined in src/app_binding.c. The registry is owned by the main App struct and initialized during startup.
typedef struct {
int key; // GLFW_KEY_* constant
int mods; // GLFW_MOD_* bitmask
const char* action; // Short title (e.g., "Toggle Bloom")
const char* desc; // Detailed description
BindingCategory category;// Movement, Visuals, PostFX, System
BindingType type; // Toggle, Cycle, Action
} AppBinding;
The "Dry-Run" Capture¶
When the help overlay is visible (app->show_help == true), the key_callback in app_input.c enters a Dry-Run mode:
- It intercepts key presses.
- It updates
app->help_pressed_keyandapp->help_pressed_mods. - It prevents the actual command from executing, allowing the user to explore the keyboard safely.
Maintaining Bindings¶
Adding a New Binding¶
To add a new key binding to the help system:
- Open
src/app_binding.c. - Locate the
app_binding_registry_initfunction. - Use the
add_bindinghelper macro:
add_binding(GLFW_KEY_X, 0, "My Action", "Extra detail about what X does.",
BINDING_CAT_POSTFX, BINDING_TYPE_TOGGLE);
Modifiers Support¶
The system supports key combinations (e.g., Shift + Key). To add one:
add_binding(GLFW_KEY_Y, GLFW_MOD_SHIFT, "Toggle Probes", "...",
BINDING_CAT_VISUALS, BINDING_TYPE_TOGGLE);
Categories & Colors¶
The UI automatically color-codes keys based on their BindingType:
- Cyan (
BINDING_TYPE_TOGGLE): On/Off switches. - Green (
BINDING_TYPE_CYCLE): Actions that cycle through multiple states. - Orange/Yellow (
GLFW_MOD_SHIFT,GLFW_MOD_ALT): Combination keys. - Blue (
BINDING_TYPE_ACTION): One-shot actions (Reset, Screenshot, Exit).
Status Bar Integration¶
Some debug modes (like Bloom Debug) integrate directly with the Main Info Overlay (F1) to display the currently active stage or sub-level (mip), providing real-time feedback during navigation.
UI Customization¶
The keyboard layout is defined in include/app_ui.h and is centered automatically. You can adjust the visual parameters (size, padding, textures) via the KeyboardLayoutConfig and associated constants in include/app_ui.h.
The key positions and labels are stored in the KEY_LAYOUT_QWERTY array within include/app_ui.h. Each entry defines:
- The
keyhandled. - The
rowindex. - The
xPosrelative to the row start. - The
widthof the key (unit: square key width). - The
labeldisplayed on the key cap.