Concepts

Action System

DearScenario Player uses a unified Action system to route user input (keyboard shortcuts), UI interactions, and some network commands through a single dispatch pipeline. This ensures that pressing a key, clicking a button, or sending a remote command all trigger identical behavior.

Overview

Keyboard input ──┐
UI button click ─┤──→ ActionEvent ──→ ActionExecutor ──→ AppController
Network command ─┘     (action ID + params)     (dispatches to player/UI)

Every user-triggerable operation is identified by a string Action ID (e.g. player.toggle_pause, ui.toggle_debug). The ActionExecutor maps each Action ID to the corresponding IAppController method call, ensuring consistent execution regardless of the input source.

Action IDs

Actions are organized by namespace:

UI actions

Action IDDescription
ui.toggle_debugToggle debug panel visibility.
ui.close_debugClose the debug panel.
ui.show_exit_promptShow the Leave DearScenario Player prompt (Cancel / Minimize / Quit).
ui.close_exit_promptDismiss the Leave DearScenario Player prompt.
ui.toggle_idle_infoToggle idle screen info display.
ui.open_calibration_toolsOpen the calibration tools panel.
ui.open_mask_editorOpen the mask editor.

App actions

Action IDDescription
app.request_quitQuit the player process.
app.minimize_windowMinimize the window (keeps the player running).

Player actions

Action IDDescription
player.toggle_pauseToggle play/pause.
player.playStart or resume playback.
player.pausePause playback.
player.stopStop and unload media.
player.cueReturn loaded media to its logical start and enter ready.
player.seekSeek to absolute position.
player.seek_relativeSeek relative to current position.
player.volume_stepAdjust volume by a delta.
player.set_volumeSet absolute volume.
player.set_muteSet mute state.
player.toggle_loopToggle loop state.
player.set_loopSet loop state.
player.open_file_dialogOpen the file picker dialog (debug panel: Open media).
player.loadLoad media by source and leave it ready (debug panel: Reload media executes play_media).

Calibration actions

Action IDDescription
calibration.close_patternClose the calibration pattern.
calibration.set_pattern_typeSet the calibration pattern type.
calibration.set_grid_densitySet grid line density.
calibration.set_grayscale_stepsSet grayscale step count.
calibration.set_border_widthSet border width.
calibration.set_grid_colorSet grid color.

Mask actions

Action IDDescription
mask.set_dirtyMark mask state as modified.
mask.exit_screen_editExit fullscreen direct edit mode.

Debug actions

Action IDDescription

Shortcut contexts

The ShortcutManager routes key presses based on the current UI context. Contexts have a priority hierarchy — higher-priority contexts take precedence:

PriorityContextActive when
1 (highest)CalibrationA calibration pattern is displayed.
2MaskEditorFullscreen mask direct-edit mode is active.
3DebugUIdebug panel is visible.
4ExitPromptThe Leave DearScenario Player prompt is shown.
5PlaybackDebug UI is visible and media is loaded (playing/paused).
6IdleNo media loaded.
7 (lowest)GlobalAlways active.

When a key is pressed, the manager checks bindings from highest to lowest priority context. The first match wins. Playback shortcuts are intentionally limited to the Debug UI; Normal-mode exhibition playback is controlled through HTTP/OSC or the Web Console. If ImGui is capturing text input (e.g. a text field is focused), most keyboard shortcuts are suppressed.

Key chords

A KeyChord represents a key + modifier combination:

FormatExample
"F1"Single key
"space"Named key
"Ctrl+Shift+K"Key with modifiers
"Cmd+Shift+D"macOS variant

Modifiers: Ctrl, Shift, Alt, Cmd (macOS).

Trigger timing

TriggerWhen it fires
PressOn key down.
ReleaseOn key up.
RepeatWhile held (OS key repeat).

Synthetic input injection

The input_key command (maintenance-only) injects synthetic keyboard events through the same shortcut pipeline as real key presses:

{
  "cmd": "input_key",
  "params": {
    "chord": "F1",
    "action": "tap",
    "count": 1
  }
}

This is used for automated testing — injected events pass through context resolution, ImGui capture detection, and the temporary dev sequence logic, exactly as a real key press would.

See Keyboard Shortcuts for the default shortcut bindings.

Previous / Next