Files
stickman/docs/specs/phase_17b_use_spots_ui.md
T
ryan d8b1b1164b Add Use Spot Overlay and Target Capture Bar functionality
- Introduced `StageUseTargetCaptureBar` class for managing user interactions with props and their use spots.
- Implemented UI elements including buttons for changing props and canceling actions.
- Added `PropUseSpotData` class for validation and serialization of prop use spots.
- Created tests for validating use spot data migration, serialization, and rule matching.
- Ensured proper handling of edge cases in use spot data, including unique IDs and finite positions.
2026-10-13 11:23:44 -04:00

19 KiB
Raw Blame History

Phase 17b — Use spots: UI/UX specification

Status: Approved design; the core UI implementation is present and awaiting in-editor user verification. New rule authoring chooses one named Use spot; saved spot_scope = "any" rules remain supported for compatibility, with no new Any-spot authoring button. Source: Phase 17 — Props for Storytelling. Scope: Sandbox Stage EDIT, DIRECT, and PLAY presentation for Use spots on placed prop instances. This document defines the child-facing interaction, not the saved-data or reach-solver contracts.

Child flow

  1. In EDIT, the child selects one placed prop. The existing right-side card keeps the prop name in its fixed header. A new Use spots section explains Stickmen can touch these places without picking up the prop. The child presses + Add a spot, moves a hand-shaped preview over the chosen handle, button, or lever, and clicks. The placed pin appears on this copy of the prop. The child may name it, move it, or erase it from a large row in the card.
  2. In DIRECT, the child chooses a stickman and Use… from the same action entry points that offer Pick Up and Set Down. A capture bar below the top toolbar asks the child to choose a prop, then a spot on that prop. Hovering a spot shows its reach result beside the pin. A valid click records the exact prop and spot in the action; Change spot lets the child revise it. A blocked choice stays on screen with a short reason at the spot.
  3. In PLAY, a completed reach gives that spot a short visible pulse while the prop remains in place. A Used prop rule can react to one named spot. An attempted interaction that cannot finish shows a brief reason near the target and does not show the success pulse.

EDIT card and control layout

Existing StageInspectorPanel
├─ Fixed header: prop icon / selected prop name / ✕ Close
└─ ScrollContainer / VBoxContainer
   ├─ Existing prop role controls
   └─ Use spots section: VBoxContainer
      ├─ Heading / helper / empty-state label
      ├─ + Add a spot: Button
      └─ Spot rows: VBoxContainer
         └─ Number + Spot name: LineEdit / Move + Erase: FlowContainer
Stage overlay
├─ Visible selected-prop pins with number and name labels, plus ghost pin in EDIT
└─ Reach status beside the spot in DIRECT; no predicted approach or hand-path lines
DIRECT Use capture bar
├─ Step-aware prompt below the top toolbar and mode pill
└─ Change prop (after prop selection) + ✕ Cancel
  • Extend the existing selected-prop StageInspectorPanel body after the prop role controls. Keep its icon, selected prop name, fixed ✕ Close, body-only scroll, safe-rectangle fitting, dismissal behavior, and compact Settings reopen button. The card applies to a single selected placed prop. With multiple objects selected, keep the current Select one prop to change its settings. notice; do not add spots to all selections.
  • Use a styled Use spots heading, one short helper sentence, a full-width + Add a spot button, and a VBoxContainer of spot rows. The empty state says No Use spots yet. Add one where a stickman should reach. Rows show a stable number, the spot's editable name, and Move and Erase buttons. Each control has a pointer target of at least 44 × 44 logical pixels and uses the greater of that size and the applicable theme button_min_height. On a narrow card or larger font, the row wraps into a VBoxContainer with actions in a FlowContainer; it never clips the name or makes buttons smaller.
  • New names are Spot 1, Spot 2, and so on until edited. The child can enter a short name such as Button or Lever. A blank edited name returns to its existing fallback; duplicate names are allowed but every row and pin retains a visible number so identical names remain distinguishable. Existing numbers stay with their spots when another spot is erased. The name field has the visible label Spot name for keyboard and assistive use; pressing Enter or leaving the field saves the edit. Name changes update action and rule summaries without changing which spot they target.
  • Selecting a row emphasizes only that pin on the stage and scrolls or pans only enough to reveal it if off screen; it does not silently move the prop. The row's selected border and the pin's number match. The selected-row treatment follows stage_panels.choice states; the row's actions follow stage_panels.action. A spot row is an individual placed-instance control, not a reusable .prop asset setting.
  • + Add a spot and Move enter a focused stage-placement workflow. Keep the selected prop highlighted, show a cursor-attached pill (Click a place on this prop or Click the spot's new place), show a numbered pin ghost at the pointer, and provide a prominent ✕ Cancel control. A valid click commits one change and returns to the card. Clicking outside the selected prop gives Choose a place on this prop next to the cursor and keeps placement active. Cancel, Esc, or right-click returns to the card; canceling a move keeps the old position. A spot may sit over a transparent gap within the prop's artwork bounds when it represents a handle; the visible preview and selected prop outline make the intended owner clear. The current EDIT flow uses its existing placement prompt and Cancel control; for future EDIT capture work, use the shared capture-bar pattern in the Stage panel UI system spec, also referenced by AGENTS.md.
  • Erase opens a themed confirmation with the spot's name and number: Erase Button (spot 2)? with Keep spot and Erase spot buttons. If an action or rule names that spot, the dialog also says This spot is used in your story. Those steps will need a new spot. After a confirmed erase, affected action and rule editors display Choose a new spot instead of silently using another spot or the whole prop. An edited draft with a missing spot cannot be committed; PLAY reports the missing target without firing Used prop. Canceling the dialog leaves the spot and references intact.
  • Moving, naming, and erasing belong to the selected placement and mark the scene as changed. Moving or rotating the prop carries its pins with it. A prop-selection or mode change cancels an active Add/Move preview without committing it. The existing Objects here chooser remains available to select a prop covered by another object; once selected, its card rows also provide a reliable way to reach obscured pins.

Pin appearance and hit targets

  • A pin is a compact high-contrast outlined circle with its stable number and an adjacent labeled pill showing the spot name. Its pointer and touch hit region is at least 44 × 44 logical pixels at every stage zoom. Pin and label are both targetable. Color and number/text both carry meaning; do not depend on color alone.
  • EDIT pins appear for the selected prop and during Add/Move, then disappear when selection moves elsewhere. DIRECT pins appear only for the prop currently being targeted by a Use action or Used prop rule. PLAY hides authored pins except for the brief completion pulse and a short failure cue. This keeps the movie view clean and distinguishes Use spots from pickup grips.
  • Pin drawing sits above selected prop artwork and remains visible if a stickman or front-tier prop overlaps it. A pin has its own hit priority during the focused Use workflow; otherwise normal stage selection and the Objects here chooser continue to work. When nearby 44 px hit regions overlap, present named choices rather than guessing. The pin labels are the normal spot-selection affordance; do not add a second always-visible spot picker beside the prop.
  • Reusable pickup grip anchors are not shown or edited in this section. Use pins use a numbered outlined circle and adjacent name label; grip anchors keep their existing purpose and appearance. Child-facing copy says Use spot and Pick up in their respective workflows, never anchor or grip.

DIRECT Use action and feedback

  • Add Use… alongside the existing prop actions in the stickman action menu and Action Editor. In the editor, provide a large Choose prop and spot button; after selection, show Using: Button (spot 2) on Door with Change spot and the existing Done / ✕ Cancel pattern. A new Use action cannot be committed without both a valid prop and an exact spot. Canceling a change to an existing action preserves its previous target.
  • Stage capture uses the persistent StageUseTargetCaptureBar below the top toolbar and DIRECTING pill. It starts with Choose a prop to use and ✕ Cancel. After prop selection, the prompt becomes Choose a spot on the prop, with Change prop and ✕ Cancel. If the prop has no spots, the prompt explains This prop has no Use spots. Add one in EDIT. The compact dark rounded panel uses a DIRECT amber accent that follows the rounded left edge; its shared visual contract is in the Stage panel UI system spec. Changing the prop returns to the first step and preserves the action/rule draft. If the prop is covered, the existing Objects here chooser offers prop candidates.
  • Hovering a pin shows its reach result beside the spot, without approach or hand-path lines. The stickman remains in its authored position, so a line from a future pose would appear detached. Use DIRECT amber for capture, a green check plus Ready to use for a reachable preview, and a red warning plus a specific message at the pin for a known problem, such as Can't walk there, Too far to reach, or No room to stand. Validity uses a glyph and text as well as color.
  • A known invalid pin cannot be committed; the child can select another pin or change the prop without losing the action draft. If prior queued actions make the future actor position uncertain, show one amber ? beside the spot with We'll check when you play. and no guide lines. Allow the target to be recorded; PLAY rechecks and reports any failure. The preview is an aid, not a promise that later moving props or changed actions cannot affect the reach.
  • The capture bar's visible ✕ Cancel button is available throughout both capture steps, including rule targeting; Change prop appears after a prop is selected. Esc and right-click are optional shortcuts. Cancel returns to the invoking action or rule editor. When editing an existing target, the earlier target remains until a valid replacement is chosen and committed.

Used prop rule authoring

  • Add Used prop to the rule trigger choices. The rule builder first shows the acting stickman, then asks the child to choose a prop and one of its labeled Use spots. New rules always name one specific spot; there is no Any spot on this prop authoring button. The rule responds only after that Use reach completes. Renaming a spot updates the summary. A missing or erased referenced spot shows Choose a new spot in the rule editor and a visible needs-attention cue in the rules list; it never silently broadens the rule to another spot. Saved spot_scope = "any" rules remain supported for compatibility and are not offered as a new choice.
  • Draw rule links with a quiet gray dashed connector, a green ⚡ trigger badge, and a purple → action badge. This keeps rule links visually distinct from Use reach previews and leaves amber for uncertain reach.
  • Selecting a prop with no spots shows This prop has no Use spots. Add one in EDIT. and leaves rule target selection active. Rule spot choices do not run reach validation: they describe an event, rather than command a reach. The child can use Change prop to replace the target.
  • Rule dialogs remain popup workflows and receive SandboxTheme.control_theme() explicitly. Their layout may reuse the shared choice visuals and theme tokens where suitable, but the in-stage StageInspectorPanel shell is not imposed on a modal editor.

Theme and accessibility

  • Reuse StageInspectorPanel for card shell, header, scroll, and action styling. StagePanelToggleRow and StagePanelSwitchVisual are not needed because Use spots are a collection of named points, not On/Off settings. Extend stage_panels tokens for spot row spacing, pin size/hit radius, pin colors, hover/focus rings, name pill, and completion pulse. Keep shared shell, type, and action tokens as the source for sizes, fonts, and surfaces. Use SandboxTheme mode_colors.edit / mode_colors.direct and overlay valid/invalid colors; add named tokens for any new visual state in both the JSON contract and defaults during implementation.
  • All card controls, action/rule choices, overlap choices, confirmation buttons, and active Cancel controls meet the 44 × 44 logical-pixel minimum and applicable button_min_height. Dynamic rows wrap or scroll at larger fonts. Dialogs and popup windows explicitly use SandboxTheme.control_theme().
  • Keyboard users can Tab through Add, name, Move, Erase, Cancel, and Done. Space/Enter activates a focused button; Enter commits a name. A selected card row can invoke Move without drag and drop. Focus remains visible over selected styling. Overlap-choice popups remain keyboard-operable. A separate always-visible spot list is not part of the stage targeting UI; if keyboard-only stage target capture is required, it remains a follow-up accessibility gap.
  • If a prop or spot disappears before PLAY or while an action is queued, show Prop is gone or Use spot is gone at the action/actor and mark its queue entry for repair. No completion pulse or Used prop rule fires. If reach fails during PLAY, show a short reason at the prop; the child can return to DIRECT and use Change spot. Stopping PLAY restores the authored pin presentation and positions.
  • The completion cue is a short ring expanding from the used spot, fading after about 0.6 seconds. It signals the completed touch without suggesting an invented door, switch, or light effect. It follows the spot if the prop is moving, does not cover the movie with labels, and can repeat for a later successful interaction. Respect the project's reduced-animation behavior if provided; a brief static highlight can carry the same cue.

Proposed theme extensions

Token group Values to add or reuse
stage_panels.spots row_gap, pin_visual_size, pin_hit_size (minimum 44), pin_outline_width, focus_ring_width, name_pill_padding, pin_surface_color, pin_outline_color, completion_duration
stage_panels.shell, .type, .choice, .action Existing card geometry, section/body/helper fonts, selected/hover/focus surfaces, row and button minima; no copied parallel panel styles
mode_colors.edit, mode_colors.direct, overlays.valid, overlays.invalid Existing mode accents and preview state colors; neutral/uncertain state derives from a named Use-preview token if no existing token fits

The architecture spec may split the new token group into shared row and Use-preview subgroups where another consumer exists. New values must remain theme-owned, including fallback values.

Exact copy map

Context Child-facing copy
Card section Use spots · Stickmen can touch these places without picking up the prop. · + Add a spot
Empty card No Use spots yet. Add one where a stickman should reach.
Spot row Spot name · Spot 1 (editable fallback) · Move · Erase
EDIT capture Click a place on this prop · Click the spot's new place · Choose a place on this prop · ✕ Cancel
Erase dialog Erase Button (spot 2)? · This spot is used in your story. Those steps will need a new spot. · Keep spot · Erase spot
DIRECT action/editor Use… · Choose prop and spot · Using: Button (spot 2) on Door · Change spot · Done · ✕ Cancel
DIRECT capture bar Choose a prop to use · Choose a spot on the prop · Change prop · ✕ Cancel · This prop has no Use spots. Add one in EDIT.
Reach feedback Ready to use · Can't walk there · Too far to reach · No room to stand · We'll check when you play.
Rule editor Used prop · Choose prop · Choose a labeled spot · Choose a new spot
PLAY failure Prop is gone · Use spot is gone · Can't reach this spot

Acceptance criteria for UI review

  1. A child can add, name, move, erase, save, reload, and find at least two Use spots on one placed prop; a second copy of the same asset has independent spots. Moving the prop keeps its pins aligned with the artwork. Pickup grip editing and .prop asset controls are unchanged.
  2. The selected prop card remains usable on short or narrow stages and with enlarged fonts. Its header and Close stay visible, every spot row and action is reachable, and a covered prop's spots can be selected through Objects here and the card list.
  3. Add/Move capture shows the correct selected owner, a cursor ghost, a nearby instruction, and a visible Cancel. Invalid clicks leave the draft active; canceling Move restores the prior location. A visually compact pin still has a 44 × 44 hit target across zoom levels.
  4. A DIRECT Use action can target either of two named spots on the same prop. The per-spot preview identifies known blocked choices beside the target without drawing detached approach/reach paths, and lets the child correct them. Action Editor and stickman action menu agree on the target and support changing it.
  5. A Used prop rule names one specific spot and fires only after a completed interaction. A successful PLAY reach has a brief pulse; failures give local feedback and do not imitate completion.
  6. Deleting a referenced spot never silently retargets an action or broadens a rule. Repair prompts identify the missing target. Selection, focus, and valid/invalid states remain understandable without color alone, and pointer, touch, and keyboard users can complete the workflow.

Implementation and verification status

  • The core implementation is present: instance pins and labels, EDIT Add/Move capture, the DIRECT Use capture bar, per-spot preview status, Use actions, named-spot rule targeting, runtime completion/failure cues, and saved-scene persistence. The capture bar currently serves DIRECT Use and Use-related rule capture. EDIT spot placement retains its current instruction and Cancel control; future EDIT capture workflows should follow the shared bar pattern linked above.
  • This specification records the approved behavior and current presentation. The presence of implementation does not mean the visual details or runtime behavior have been verified in-editor. User verification remains pending.