- What: 新增 apps/studio/src/orisys_studio/replay_controller.py:回放视图的**策略** (哪些入口能打开视频、transport 何时是播放何时是采集、从视频重算对面板与采集 管线做什么)从 app_window 搬进 ReplayController,共 30 个公开方法。replay.py 仍是 **引擎**(reader / 游标 / 异步深度重算),本模块是它外面的状态机。 它直接驱动的对象只有五个:toolbar 的回放控件、曲线图(时间轴)、2D 面板、三维面板的 来源标签、五个菜单项;其余依赖用 ReplayHost Protocol 写明(状态栏、轨道、视图切换、 显示单位、2D 唯一入口 _show_image_frame、采集管线 _start_run/_stop_run)——这些是 窗口级操作,所以留在窗口,并由 Protocol 把边界写清楚,而不是让控制器伸手进"上帝对象"。 - What: 播放时钟与定时器(33 ms)、_recompute_running、入口校验、菜单启用与提示、 重算开关的全部规则都随之上移;窗口侧保留过渡 shim(_load_recording / _load_replay_video / _render_replay_frame / _start_playback / _pause_playback / _on_play_shortcut / _stop_replay_activity / _replay_owns_image / _can_recompute / _play_timer / _recompute_running)供 tests、tools/ui_check.py、tools/ui_snapshot.py 继续驱动窗口。 窗口内部调用点(_apply_view_preset、_update_run_enabled、_sync_menu_checks、_on_run_toggled、 _on_stop_shortcut、_on_reset、菜单与工具栏连线)改为直接调用 self.replay_ctl.*。 删除窗口里已搬走的 _on_browse_video、_on_replay_position、_on_recording_changed、 _wire_replay、_on_recompute_toggled 等,以及随之为空的导入(time、QFileDialog、 SOURCE_REPLAY、PLAYBACK_TICK_MS)。顺带删掉一个从未接线的死方法 _on_replay_unit_toggled(与 _on_chart_unit_toggle 重复,无人调用)。 - What: 新增 apps/studio/tests/test_replay_controller.py:8 个用例,用假的 host/engine/ panel 直接测策略——播放在末尾从头开始、零长录制不播、playhead 跟墙钟并在末尾停下、 重算开关打开时 transport 启动管线而非播放、2D 面板归属、裸视频被接受/在实时视图被拒、 无标定录制回落到 raw、回放入口只在回放视图存在。 - Fix: 重算结束的 flag 由它自己的所有者清除(transport 暂停、开关关闭、stop_activity 三条路径),不再依赖窗口的 _stop_run 顺手清;效果是"重算结束后停止按钮正确变为不可用", test_ui_smoke 里那个"手动补状态"的注释随之删除。 - Why: 回放是 app_window 的第二个独立变更驱动:录制格式变一次是引擎的事,操作员流程 变一次不该动 2500 行窗口。搬完之后回放策略可单独阅读、单独测,窗口只剩装配与转发。 - Verification: pytest shared/tests apps/studio/tests(offscreen)611 passed / 0 failed / 15 skipped(原 603 + 新增 8);apps/studio/tools/ui_check.py 587 项检查 0 失败; .repro/locale_check.py 0 缺失。行为等价(搬运 + 一层转发)。 - Not in this change: C1 视图排列、C2 显示偏好、标定交互仍未拆分;docs 的行数/方法数 指标待全部切片落定后统一刷新。真机 GL 冒烟仍无法复跑(本机创建不出 GL 上下文, eglError 3005),13 例跳过、probe 用例按机器实况失败,与本次改动无关。
orisys-app
Desktop applications that consume the Orisys SDK.
| App | Status |
|---|---|
apps/studio |
Scaffold shell (theme / locale / prefs / logging) |
apps/internal |
Stub for future calibration & automated testing |
Layout
shared/— common paths, prefs, theme, i18n, loggingapps/studio/config/— locales, default prefs, editablesensors/copiesapps/studio/outputs/— generated logs and calibration exports (gitignored)build/— Windows PyInstaller packaging (build/studio/build.ps1)
Run (studio shell)
cd D:\repo\orisys-app
python -m pip install -e .\shared -e .\apps\studio
python .\apps\studio\run.py
Or without install:
$env:PYTHONPATH = "D:\repo\orisys-app\shared\src;D:\repo\orisys-app\apps\studio\src"
python D:\repo\orisys-app\apps\studio\run.py
Local orisys SDK
orisys_app_shared.force imports orisys.calibration at module scope, so the
studio app cannot start against an SDK build that predates that module
(the published 0.5.2 wheel does not include it). When working from a repo
checkout, install the SDK from source instead of from an index:
python -m pip install .\..\orisys-sdk # same checkout that built this app
If a pip build is blocked by the environment, the equivalent manual install is
to copy orisys-sdk/src/orisys/**/*.py over site-packages/orisys/ and delete
the stale __init__.cp310-win_amd64.pyd (an extension module shadows the
package __init__.py, which hides sibling modules such as calibration.py).
Verifying UI changes
Both tools render the real main window with the offscreen Qt platform — no display, camera or sensor hardware required:
python .\apps\studio\tools\ui_check.py # layout/theme assertions
python .\apps\studio\tools\ui_snapshot.py --theme light --demo `
--sensor finger --panels cal,3d --size 1600x900 --out shot.png
ui_check.py needs only the runtime dependencies. The pytest suite in
shared/tests and apps/studio/tests covers the same ground plus locale and
preference-schema parity:
pip install pytest
python -m pytest
On Windows the offscreen platform finds no fonts unless QT_QPA_FONTDIR points
at C:\Windows\Fonts; both tools set it automatically.
ui_check.py also runs the palette rules (WCAG contrast, colour separation,
ramp monotonicity) that guard the brand tokens; see
apps/studio/docs/ui-palette.md for the
colour system, its relationship to the UI design spec, and every deliberate
deviation from it.
ui_check.py includes a record channel section as well; see
apps/studio/docs/record-channel.md for
why recording and calibration sampling no longer hang off the UI refresh timer,
and for the data-reliability fixes that came with it.
Branding
Window / EXE icon: shared/resources/branding/logo.png
Top bar / About: shared/resources/branding/logo_topbar.png
Dark mode is the default. Logos currently sit on a black tile; a transparent (or light) variant may be needed for polished light mode later.
Versioning
- Studio app version (
orisys_studio.__version__) — shown in Help → About and used for releases. - Shared package version (
orisys_app_shared.__version__) — internal library version. - Shared API (
orisys_app_shared.API_VERSION) — compatibility tag. Studio declaresREQUIRES_SHARED_API; startup logs a warning on mismatch.
Deferred
Run/Stop pipeline, arrow/force plots, units, calibration capture, Open3D finger mesh, sync-from-wheel for config/sensors, PyInstaller packaging, and the internal app.