Make the rail reset zero the sensor in live and the display in replay
The replay view disabled a control whose display reset is exactly what an operator wants there, and the bare "Reset" hid that the live one zeroes the sensor tracker; the label, tooltip and status line now name the target, and Ctrl+R follows the view. Verified with the studio suite, ui_check (628 checks) and real-GL rail snapshots of both views.
This commit is contained in:
@@ -190,8 +190,6 @@ def _fake_packet(
|
||||
|
||||
nan = float("nan")
|
||||
blank = np.zeros((8, 8, 3), np.uint8) if frame is None else frame
|
||||
# A single tall sample makes it easy to prove decimation keeps peaks.
|
||||
fn_raw = 99.0 if frame_id == 700 else (9.0 + frame_id * 0.01)
|
||||
return SdkPacket(
|
||||
raw_frame=blank,
|
||||
processed_frame=blank,
|
||||
@@ -952,6 +950,26 @@ def main() -> int:
|
||||
window.toolbar.record_chip.toolTip() != "",
|
||||
"the record chip does not explain its state",
|
||||
)
|
||||
# The reset names its target where it is (the reported confusion was that 重置
|
||||
# read as "reset the charts" while it zeroes the *sensor*), and an idle live
|
||||
# view says in the tip that there is no session to zero yet rather than
|
||||
# leaving a dead button.
|
||||
check(
|
||||
window.toolbar.reset_target() == "sensor",
|
||||
f"{theme}: the live view's reset is not the sensor tracker's",
|
||||
)
|
||||
check(
|
||||
window.toolbar.btn_reset.text() == t("toolbar.reset_sensor"),
|
||||
f"{theme}: the reset does not say it zeroes the sensor: "
|
||||
f"{window.toolbar.btn_reset.text()!r}",
|
||||
)
|
||||
check(
|
||||
not window.toolbar.btn_reset.isEnabled()
|
||||
and window.toolbar.btn_reset.toolTip() == t("toolbar.reset_sensor_unavailable"),
|
||||
f"{theme}: the idle reset does not explain itself: "
|
||||
f"enabled={window.toolbar.btn_reset.isEnabled()} "
|
||||
f"{window.toolbar.btn_reset.toolTip()!r}",
|
||||
)
|
||||
check(
|
||||
not rail_squeezed(window),
|
||||
f"{theme}: the status rail squeezes {rail_squeezed(window)}",
|
||||
@@ -1079,6 +1097,63 @@ def main() -> int:
|
||||
app.processEvents()
|
||||
set_locale("zh_CN")
|
||||
|
||||
# The reset is now the rail's longest action label ("Reset sensor" / "Reset
|
||||
# display" against the old bare "Reset"), so it is the one to measure rather than
|
||||
# assume: the rail shares one line with the whole session state, 1280x720 is the
|
||||
# tightest window and English is the widest locale. Both views are measured,
|
||||
# because the label follows the view. The widths printed are what this check is
|
||||
# judging — the threshold is "no elision", not a number.
|
||||
for language in ("en_US", "zh_CN"):
|
||||
set_locale(language)
|
||||
app.setStyleSheet(build_qss("dark"))
|
||||
measured = StudioMainWindow(
|
||||
prefs={"language": language, "theme": "dark", "sensor_type": "finger"}
|
||||
)
|
||||
measured.resize(1280, 720)
|
||||
measured.show()
|
||||
for _ in range(3):
|
||||
app.processEvents()
|
||||
button = measured.toolbar.btn_reset
|
||||
live_width = button.sizeHint().width()
|
||||
check(
|
||||
button.text() == t("toolbar.reset_sensor"),
|
||||
f"{language}: the live reset reads {button.text()!r}",
|
||||
)
|
||||
check(
|
||||
button.width() >= button.sizeHint().width() - 1,
|
||||
f"{language} at 1280x720: the live reset is elided "
|
||||
f"({button.width()} < {button.sizeHint().width()})",
|
||||
)
|
||||
check(
|
||||
not rail_squeezed(measured),
|
||||
f"{language} at 1280x720 (live): the rail squeezes {rail_squeezed(measured)}",
|
||||
)
|
||||
measured.brand_bar.btn_playback.click()
|
||||
for _ in range(3):
|
||||
app.processEvents()
|
||||
replay_width = button.sizeHint().width()
|
||||
check(
|
||||
button.text() == t("toolbar.reset_display"),
|
||||
f"{language}: the replay reset reads {button.text()!r}",
|
||||
)
|
||||
check(
|
||||
button.width() >= button.sizeHint().width() - 1,
|
||||
f"{language} at 1280x720: the replay reset is elided "
|
||||
f"({button.width()} < {button.sizeHint().width()})",
|
||||
)
|
||||
check(
|
||||
not rail_squeezed(measured),
|
||||
f"{language} at 1280x720 (replay): the rail squeezes "
|
||||
f"{rail_squeezed(measured)}",
|
||||
)
|
||||
print(
|
||||
f" reset label at 1280x720, {language}: live {live_width}px, "
|
||||
f"replay {replay_width}px (button width {button.width()}px)"
|
||||
)
|
||||
measured.close()
|
||||
app.processEvents()
|
||||
set_locale("zh_CN")
|
||||
|
||||
# Exactly one *filled* action at a time: a red Stop dominating an otherwise
|
||||
# idle top area was the original complaint.
|
||||
app.setStyleSheet(build_qss("dark"))
|
||||
@@ -1162,6 +1237,22 @@ def main() -> int:
|
||||
and window.toolbar.btn_reset.isEnabled(),
|
||||
"pausing the transport did not leave a running, stoppable session",
|
||||
)
|
||||
# The paused session is where the two labels are easiest to get wrong: the
|
||||
# transport is unchecked ("paused", not "stopped"), so the reset must still name
|
||||
# the sensor tracker it can act on and keep the tip that says what happens.
|
||||
check(
|
||||
window.toolbar.reset_target() == "sensor"
|
||||
and window.toolbar.btn_reset.text() == t("toolbar.reset_sensor")
|
||||
and window.toolbar.btn_reset.toolTip() == t("toolbar.reset_sensor_tip"),
|
||||
f"the paused session's reset does not say what it does: "
|
||||
f"{window.toolbar.btn_reset.text()!r} / "
|
||||
f"{window.toolbar.btn_reset.toolTip()!r}",
|
||||
)
|
||||
check(
|
||||
window.act_reset.isEnabled() and window.act_reset.text() == t("menu.reset"),
|
||||
f"Ctrl+R does not follow the rail in a paused session: "
|
||||
f"{window.act_reset.text()!r}",
|
||||
)
|
||||
window.toolbar.btn_run.setChecked(True)
|
||||
app.processEvents()
|
||||
check(
|
||||
@@ -3217,11 +3308,80 @@ def main() -> int:
|
||||
# The replay view stops through the rail's own Stop button — the same control the
|
||||
# live view uses — because the transport is a play/pause toggle and "which one is
|
||||
# stuck?" is not a question to ask an operator in front of a frozen picture. The
|
||||
# tracker reset owns no device here, so it is disabled rather than repurposed.
|
||||
# tracker reset owns no device here, so the same button is the *display* reset and
|
||||
# says so: a control that cannot be used in the view the operator is working in is
|
||||
# the reported defect ("the reset button cannot be used in replay mode").
|
||||
check(
|
||||
not replay_window.toolbar.btn_reset.isEnabled(),
|
||||
"the replay view offers to zero a device tracker it has not got",
|
||||
replay_window.toolbar.reset_target() == "display"
|
||||
and replay_window.toolbar.btn_reset.isEnabled(),
|
||||
"the replay view does not offer its display reset",
|
||||
)
|
||||
check(
|
||||
replay_window.toolbar.btn_reset.text() == t("toolbar.reset_display")
|
||||
and replay_window.toolbar.btn_reset.toolTip() == t("toolbar.reset_display_tip"),
|
||||
f"the replay's reset does not say what it does: "
|
||||
f"{replay_window.toolbar.btn_reset.text()!r} / "
|
||||
f"{replay_window.toolbar.btn_reset.toolTip()!r}",
|
||||
)
|
||||
check(
|
||||
replay_window.act_reset.text() == t("menu.reset_display"),
|
||||
f"Ctrl+R is not named as the display reset in the replay: "
|
||||
f"{replay_window.act_reset.text()!r}",
|
||||
)
|
||||
# The display reset itself, on a browsed window and a moved playhead: the charts
|
||||
# go back to the recording's own framing, the replay starts over, and no device
|
||||
# worker is asked to zero anything — the window is armed with a controllable one
|
||||
# here, and its request counter has to stay at zero.
|
||||
replay_devices = _StuckWorker()
|
||||
kept = (
|
||||
replay_window._box_worker,
|
||||
replay_window._finger_worker,
|
||||
replay_window._ensure_workers,
|
||||
)
|
||||
replay_window._ensure_workers = lambda: None
|
||||
replay_window._box_worker = replay_devices
|
||||
replay_window._finger_worker = replay_devices
|
||||
try:
|
||||
replay_plots.set_window(0.2, 0.6)
|
||||
replay.set_position(replay.duration_s() * 0.5)
|
||||
app.processEvents()
|
||||
check(
|
||||
replay_plots.mode() == "browse" and replay.position() > 0.0,
|
||||
"the state the display reset has to undo was not set up",
|
||||
)
|
||||
replay_window.toolbar.btn_reset.click()
|
||||
app.processEvents()
|
||||
check(
|
||||
replay_devices.reset_requests == 0,
|
||||
"the replay's reset asked a device worker to zero the tracker",
|
||||
)
|
||||
check(
|
||||
replay.position() == 0.0 and replay_plots.cursor_time() == 0.0,
|
||||
f"the display reset did not start the replay over: "
|
||||
f"{replay.position()} / {replay_plots.cursor_time()}",
|
||||
)
|
||||
check(
|
||||
replay_plots.mode() == "browse" and replay_plots.window()[0] == 0.0,
|
||||
f"the display reset left the charts out of the recording's framing: "
|
||||
f"{replay_plots.mode()} {replay_plots.window()}",
|
||||
)
|
||||
check(
|
||||
all(int(curve.getData()[0].size) == 40 for curve in replay_plots.curves),
|
||||
"the display reset left the replay with blank charts: "
|
||||
f"{[curve.getData()[0] for curve in replay_plots.curves]}",
|
||||
)
|
||||
check(
|
||||
replay_window.statusBar().currentMessage() == t("status.reset_display"),
|
||||
f"the display reset did not say what it did: "
|
||||
f"{replay_window.statusBar().currentMessage()!r}",
|
||||
)
|
||||
finally:
|
||||
(
|
||||
replay_window._box_worker,
|
||||
replay_window._finger_worker,
|
||||
replay_window._ensure_workers,
|
||||
) = kept
|
||||
replay_devices.release()
|
||||
check(
|
||||
replay_window.toolbar.btn_stop.text() == t("toolbar.stop_label"),
|
||||
f"the replay's stop button is not labelled as one: "
|
||||
|
||||
Reference in New Issue
Block a user