mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-18 22:42:37 +00:00
The gesture ladder proved the TARGET — a complex closed profile, exact in vertices, lengths, arcs
and symmetry, voids correctly attributed. It proved it by arming every tool with a letter key,
which leaves the goal's own MECHANISM untested: the design logic pivots on right-click, and the
verbs offered are supposed to adapt to the element under the cursor. 47 of 86 Design-tab verbs
have a GUI action and no shortcut, so a key-driven ladder cannot reach more than half of them.
scripts/offer-ladder.py drives the menu. It asserts nothing from pixels: show_offer_menu emits an
[OFFER] trace from the same loop that builds the rows (behind the existing SNAPORCA_KEYTRACE), so
what the ladder reads cannot drift from what the user is shown, and the expected row set is
predicted by parsing DesignOffer.hpp rather than transcribed by hand. 25 properties, four rungs:
what each element type offers, that the menu equals the table for four selections AND that the
four differ, a 120 x 80 profile authored entirely through the menu, and a tool with no keyboard
route at all driven from the only door it has.
Two real defects, both found by it, both fixed here:
snaporca-ghcz (P1) — right-click was a black hole while any draw tool was armed. Every draw case
ended with `if (evt.RightDown()) { m_points.clear(); return true; }` and returned true even with
nothing to abandon; on_mouse records that in m_right_consumed and DesignCanvas suppresses the
offer whenever it is set. Measured: with Line armed, two right-clicks in a row produced no menu
and no tool change; only Escape freed it. Same rule snaporca-xmh6 wrote for the selection —
clearing nothing is not a gesture terminator. One shared right_abandon() now consumes the click
only when an anchor was really down; 16 sites, plus Polyline/BSpline (which end a chain, correct
only when there IS one) and Point (which has no anchor at all).
snaporca-lnri (P2) — right-clicking a sketch point offered the empty vocabulary. select_at_screen
tests hit_test_point first and records the hit in m_point_sel, but the offer counts m_selection
only, so a Point entity could never reach the entity branch and SkPoint was unreachable by
construction. A Point IS its own handle, so it is selected as an entity; other entities keep the
handle pick, since a line's endpoint is a drag target, not a vocabulary.
Offer ladder 25/25, gesture ladder 93/93 (no regression), both on the rig. The offer ladder joins
scripts/ladder-all.sh as the fifth rung.
snaporca-ghcz snaporca-lnri
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MrMzTpAf78U4NG2M8jfvHY
61 lines
2.8 KiB
Bash
Executable File
61 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Every ladder, in one command, as the gate before a push that touched the Design tab.
|
|
#
|
|
# WHY A SCRIPT AND NOT CI. Three of the four rungs need a running application with an OpenGL
|
|
# canvas and synthetic input; GitHub's runners have neither. So the gate is local and explicit:
|
|
# run this, read the last line, and do not push a red one. The kernel suite is the only part CI
|
|
# can carry, and it already does.
|
|
#
|
|
# scripts/ladder-all.sh # kernel + engine + corpus (every 20th) + gestures + offer
|
|
# FULL=1 scripts/ladder-all.sh # corpus over ALL 997 sheets (~25 min)
|
|
# SKIP_GUI=1 scripts/ladder-all.sh # kernel only, for a machine with no rig
|
|
#
|
|
# The rig container is expected to be up with the app running and SNAPORCA_MCP set; bring it up
|
|
# with scripts/gui-session.sh inside it. The corpus lives at /corpus in that container.
|
|
set -uo pipefail
|
|
cd "$(dirname "$0")/.."
|
|
|
|
C="${C:-snaporca-gui}"
|
|
CORPUS="${CORPUS:-/corpus}"
|
|
STEP="${STEP:-20}"
|
|
[ -n "${FULL:-}" ] && STEP=1
|
|
fail=0
|
|
|
|
step() {
|
|
local name="$1"; shift
|
|
echo
|
|
echo "=== $name ==="
|
|
if "$@"; then echo "--- $name OK"; else echo "--- $name FAILED"; fail=1; fi
|
|
}
|
|
|
|
run_in_rig() { # copy the script in fresh, then run it there
|
|
docker cp "$1" "$C:/tmp/$(basename "$1")" >/dev/null || return 1
|
|
shift
|
|
docker exec "$C" python3 "$@"
|
|
}
|
|
|
|
step "kernel suite" scripts/kernel-test.sh --vol "${KVOL:-snaporca_kerneltest}"
|
|
|
|
if [ -z "${SKIP_GUI:-}" ]; then
|
|
step "engine ladder (rungs 1-8, scripted geometry)" \
|
|
run_in_rig scripts/sketch-ladder.py /tmp/sketch-ladder.py
|
|
step "corpus rung (real drawings, every ${STEP}th)" \
|
|
run_in_rig scripts/ladder-corpus.py /tmp/ladder-corpus.py --corpus "$CORPUS" --step "$STEP"
|
|
step "corpus scale rung (the heaviest sheets)" \
|
|
run_in_rig scripts/ladder-corpus.py /tmp/ladder-corpus.py --corpus "$CORPUS" --scale
|
|
step "gesture ladder (mouse and keyboard)" \
|
|
run_in_rig scripts/gui-ladder.py /tmp/gui-ladder.py
|
|
# The offer ladder needs TWO extra things the others do not: the app must have been launched
|
|
# with SNAPORCA_KEYTRACE=1 (its [OFFER] lines are the whole instrument), and it reads the
|
|
# generated offer table to predict what each selection should show — which is not in the
|
|
# container's own baked source tree, so it is copied in beside the script — /tmp, where
|
|
# run_in_rig puts the script, is one of the paths the ladder looks in.
|
|
docker cp src/slic3r/GUI/CAD/DesignOffer.hpp "$C:/tmp/DesignOffer.hpp" >/dev/null
|
|
step "offer ladder (right-click, the menu, the verbs behind it)" \
|
|
run_in_rig scripts/offer-ladder.py /tmp/offer-ladder.py
|
|
fi
|
|
|
|
echo
|
|
if [ "$fail" -eq 0 ]; then echo "ALL LADDERS HELD"; else echo "AT LEAST ONE LADDER FAILED"; fi
|
|
exit "$fail"
|