.. _stdlib_imgui_visual_aids: ======================================================================= Visual aids — tutorial-mode overlays, mouse trail, narration, key HUD ======================================================================= .. das:module:: imgui_visual_aids Tutorial-mode overlays — highlight rectangles, mouse-cursor sprite + trail, narration text, key HUD, click flash — painted over the live ImGui surface to guide the viewer through scripted recordings. Every overlay is opt-in and keyed off the boost registry's widget path, so highlighting ``MAIN_WIN/SETTINGS_TAB/RPS`` resolves to the exact rect the renderer drew. Painters are registered as end-of-frame hooks so the host's render loop is unchanged. Auto-highlight (``imgui_auto_highlight_on_command``) makes every accepted ``imgui_*`` command auto-flash its target — useful when recording with ``imgui_playwright`` so each programmatic action is visually narrated without explicit ``imgui_highlight`` calls. +++++++++ Constants +++++++++ .. _global-imgui_visual_aids-g_keycap_trace_max: .. das:attribute:: g_keycap_trace_max = 6 g_keycap_trace_max:int const .. _global-imgui_visual_aids-g_keycap_trace_fallback_lifetime_s: .. das:attribute:: g_keycap_trace_fallback_lifetime_s = 1f g_keycap_trace_fallback_lifetime_s:float const ++++++++++ Structures ++++++++++ .. _struct-imgui_visual_aids-HighlightArgs: .. das:attribute:: HighlightArgs struct HighlightArgs .. _struct-imgui_visual_aids-MouseTrailArgs: .. das:attribute:: MouseTrailArgs struct MouseTrailArgs .. _struct-imgui_visual_aids-NarrateArgs: .. das:attribute:: NarrateArgs struct NarrateArgs .. _struct-imgui_visual_aids-AutoHighlightArgs: .. das:attribute:: AutoHighlightArgs struct AutoHighlightArgs .. _struct-imgui_visual_aids-CursorSpriteArgs: .. das:attribute:: CursorSpriteArgs struct CursorSpriteArgs .. _struct-imgui_visual_aids-KeyHudArgs: .. das:attribute:: KeyHudArgs struct KeyHudArgs .. _struct-imgui_visual_aids-FocusRectArgs: .. das:attribute:: FocusRectArgs struct FocusRectArgs .. _struct-imgui_visual_aids-MemDebugArgs: .. das:attribute:: MemDebugArgs struct MemDebugArgs +++++++++++++++++ Highlight overlay +++++++++++++++++ * :ref:`highlight (target: string; frames: int = highlight_default_frames; color: uint = highlight_color) ` * :ref:`imgui_auto_highlight (input: JsonValue?) : JsonValue? ` * :ref:`imgui_highlight (input: JsonValue?) : JsonValue? ` .. _function-imgui_visual_aids_highlight_string_int_uint: .. das:function:: highlight(target: string; frames: int = highlight_default_frames; color: uint = highlight_color) Flash a colored rect around the named widget's bbox for ``frames`` ticks. ``target`` is a registry path or ``"0x"``. :Arguments: * **target** : string * **frames** : int * **color** : uint .. _function-imgui_visual_aids_imgui_auto_highlight_JsonValue_q_: .. das:function:: imgui_auto_highlight(input: JsonValue?) : JsonValue? ``[live_command]`` toggle for the ``imgui_auto_highlight_on_command`` flag. Arg: ``enabled``. :Arguments: * **input** : :ref:`JsonValue `? .. _function-imgui_visual_aids_imgui_highlight_JsonValue_q_: .. das:function:: imgui_highlight(input: JsonValue?) : JsonValue? ``[live_command]`` wrapper around :ref:`highlight `. Args: ``target``, ``frames``, ``color``. :Arguments: * **input** : :ref:`JsonValue `? +++++++++++ Mouse trail +++++++++++ * :ref:`imgui_mouse_trail (input: JsonValue?) : JsonValue? ` * :ref:`mouse_trail (enabled: bool; fade: float = -1f; color: uint = 0x0) ` .. _function-imgui_visual_aids_imgui_mouse_trail_JsonValue_q_: .. das:function:: imgui_mouse_trail(input: JsonValue?) : JsonValue? ``[live_command]`` wrapper around :ref:`mouse_trail `. Args: ``enabled``, ``fade``, ``color``. :Arguments: * **input** : :ref:`JsonValue `? .. _function-imgui_visual_aids_mouse_trail_bool_float_uint: .. das:function:: mouse_trail(enabled: bool; fade: float = -1f; color: uint = 0x0) Toggle the fading mouse-trail overlay; non-default ``fade`` / ``color`` override the module globals. Disabling clears the trail buffer. :Arguments: * **enabled** : bool * **fade** : float * **color** : uint +++++++++ Narration +++++++++ * :ref:`compute_connector_end (target_bbox: float4; banner_center: float2) : float2 ` * :ref:`compute_connector_start (anchor: float2; box_size: float2; widget_center: float2) : float2 ` * :ref:`compute_narrate_anchor (has_target: bool; widget_bbox: float4; box_size: float2; viewport: float2; edge_margin: float; gap: float; shadow: float2; hud_zone_h: float; other_bboxes: array\; avoid_bboxes: array\) : float2 ` * :ref:`imgui_narrate (input: JsonValue?) : JsonValue? ` * :ref:`narrate (text: string; target: string = ""; frames: int = narrate_default_frames; duration_s: float = -1f) ` * :ref:`narrate (text: string; targets: array\; frames: int = narrate_default_frames; duration_s: float = -1f) ` .. _function-imgui_visual_aids_compute_connector_end_float4_float2: .. das:function:: compute_connector_end(target_bbox: float4; banner_center: float2) : float2 Mirror of ``compute_connector_start`` on the target side: closest point on the target's bbox boundary to ``banner_center``. Same clamp-onto-rect trick — terminates the line on the target's edge (or corner) instead of inside it. :Arguments: * **target_bbox** : float4 * **banner_center** : float2 .. _function-imgui_visual_aids_compute_connector_start_float2_float2_float2: .. das:function:: compute_connector_start(anchor: float2; box_size: float2; widget_center: float2) : float2 Closest point on the post-it's boundary to ``widget_center`` (clamp-onto-rect). It's the edge midpoint when ``widget_center`` is directly outside one side; for offset/corner cases it walks to the nearest corner so the arrow points naturally at the target. :Arguments: * **anchor** : float2 * **box_size** : float2 * **widget_center** : float2 .. _function-imgui_visual_aids_compute_narrate_anchor_bool_float4_float2_float2_float_float_float2_float_array_ls_float4_gr__array_ls_float4_gr_: .. das:function:: compute_narrate_anchor(has_target: bool; widget_bbox: float4; box_size: float2; viewport: float2; edge_margin: float; gap: float; shadow: float2; hud_zone_h: float; other_bboxes: array; avoid_bboxes: array) : float2 Pick a post-it anchor (top-left) by scoring 4 viewport-clamped candidates (right/left/below/above): ``score_anchor`` adds 1 per incidental ``other_bboxes`` overlap and 1000 per anchor-target or ``avoid_bboxes`` overlap. Lowest score wins (ties by order right>left>below>above); a banner too big to place returns a bottom-left failsafe. :Arguments: * **has_target** : bool * **widget_bbox** : float4 * **box_size** : float2 * **viewport** : float2 * **edge_margin** : float * **gap** : float * **shadow** : float2 * **hud_zone_h** : float * **other_bboxes** : array * **avoid_bboxes** : array .. _function-imgui_visual_aids_imgui_narrate_JsonValue_q_: .. das:function:: imgui_narrate(input: JsonValue?) : JsonValue? ``[live_command]`` wrapper around :ref:`narrate `. Args: ``text``, ``target`` (single anchor) OR ``targets`` (list — first is the anchor, all hard-avoided), ``frames``, ``duration_s`` (wall-clock seconds; wins over ``frames``). :Arguments: * **input** : :ref:`JsonValue `? narrate ^^^^^^^ .. _function-imgui_visual_aids_narrate_string_string_int_float: .. das:function:: narrate(text: string; target: string = ""; frames: int = narrate_default_frames; duration_s: float = -1f) Pop a callout box with ``text``. Lingers ``frames`` render ticks, or ``duration_s > 0`` wall-clock seconds instead (needed when recording render fps != capture fps). A ``target`` that resolves to a widget bbox anchors the box beside it with a connector; else it floats top-left. :Arguments: * **text** : string * **target** : string * **frames** : int * **duration_s** : float .. _function-imgui_visual_aids_narrate_string_array_ls_string_gr__int_float: .. das:function:: narrate(text: string; targets: array; frames: int = narrate_default_frames; duration_s: float = -1f) +++ HUD +++ * :ref:`imgui_focus_rect (input: JsonValue?) : JsonValue? ` * :ref:`imgui_key_hud (input: JsonValue?) : JsonValue? ` .. _function-imgui_visual_aids_imgui_focus_rect_JsonValue_q_: .. das:function:: imgui_focus_rect(input: JsonValue?) : JsonValue? ``[live_command]`` toggle for the focus rectangle around ``io.active_widget`` — shows where typing lands. Arg: ``enabled``. :Arguments: * **input** : :ref:`JsonValue `? .. _function-imgui_visual_aids_imgui_key_hud_JsonValue_q_: .. das:function:: imgui_key_hud(input: JsonValue?) : JsonValue? ``[live_command]`` toggle for the bottom-center keycap HUD + Ctrl/Shift/Alt/Cmd modifier strip. Args: ``enabled``, ``show_modifiers``, ``keycap_fade_s`` (seconds a keycap lingers - bump it so a chord stays readable while a voice line names it). :Arguments: * **input** : :ref:`JsonValue `? +++++++++++++ Cursor sprite +++++++++++++ * :ref:`cursor_sprite (enabled: bool) ` * :ref:`imgui_cursor_sprite (input: JsonValue?) : JsonValue? ` .. _function-imgui_visual_aids_cursor_sprite_bool: .. das:function:: cursor_sprite(enabled: bool) Toggle the in-frame cursor sprite. Drawn on the ForegroundDrawList so APNG recordings show a visible pointer even when the OS hardware cursor isn't captured. :Arguments: * **enabled** : bool .. _function-imgui_visual_aids_imgui_cursor_sprite_JsonValue_q_: .. das:function:: imgui_cursor_sprite(input: JsonValue?) : JsonValue? ``[live_command]`` wrapper around :ref:`cursor_sprite `. Arg: ``enabled``. :Arguments: * **input** : :ref:`JsonValue `? ++++++++++++++ Override hooks ++++++++++++++ * :ref:`apply_synth_io_override () ` .. _function-imgui_visual_aids_apply_synth_io_override: .. das:function:: apply_synth_io_override() Per-frame synth IO for hand-rolled (non-harness) update loops — call between the backend's ``*_NewFrame()`` and ImGui's ``NewFrame()``. Drains the full synth pipeline (``advance_coroutines()`` then ``imgui_synth_tick()``), mirroring the harness so coroutine synth clicks work without it. ++++++++++++++++ Memory debugging ++++++++++++++++ * :ref:`imgui_memory_debug (input: JsonValue?) : JsonValue? ` .. _function-imgui_visual_aids_imgui_memory_debug_JsonValue_q_: .. das:function:: imgui_memory_debug(input: JsonValue?) : JsonValue? ``[live_command]`` toggle for :ref:`imgui_debug_memory ` — per-frame GC-pressure logging. Arg: ``enabled``. :Arguments: * **input** : :ref:`JsonValue `? +++++++++++++++ Color utilities +++++++++++++++ * :ref:`rgba (r: int; g: int; b: int; a: int) : uint ` .. _function-imgui_visual_aids_rgba_int_int_int_int: .. das:function:: rgba(r: int; g: int; b: int; a: int) : uint Pack R/G/B/A bytes into ImGui's IM_COL32 word order. Useful when configuring the tunable color globals by channel rather than hex literal. :Arguments: * **r** : int * **g** : int * **b** : int * **a** : int +++++++++++++++++ Serve / lifecycle +++++++++++++++++ * :ref:`visual_aids_init () ` .. _function-imgui_visual_aids_visual_aids_init: .. das:function:: visual_aids_init() ``[init]`` — registers the foreground-drawlist paint hook and the post-command auto-highlight hook. Runs once at module load.