diff --git a/apps/studio/config/locales/en_US.json b/apps/studio/config/locales/en_US.json index dbdf1ea..66dfdf5 100644 --- a/apps/studio/config/locales/en_US.json +++ b/apps/studio/config/locales/en_US.json @@ -38,7 +38,7 @@ "plot_settings": "Plot settings…", "rotate_arrows": "Rotate arrows 90°", "recompute": "Analyze video", - "recompute_tip": "On: serve a stored analysis result for this video, or run the pass if there is none. Off: leave analysis and read the recording’s own forces.csv when it has one. To change profile, calibration or reference frame use Analysis ▸ Analysis setup…", + "recompute_tip": "Use a result if there is one; otherwise analyse. Change settings in Analysis setup.", "analysis_setup": "Analysis setup…", "analysis_setup_tip": "Choose the profile, calibration and reference frame for this video, then run (or re-run) the analysis pass.", "run": "Run / Stop", @@ -78,8 +78,8 @@ "reset_defaults": "Reset to defaults", "plot_orientation_group": "Finger 2D presentation (2D only; the 3D view keeps the design frame)", "plot_orientation": "Orientation", - "plot_orientation_tip": "How the finger's 2D canvas (the unrolled domain) is presented. The 180° default is derived from the unroll map and the design frame: the canvas's +x is the frame's +X and its screen up is −Z, while the 3D default view puts −X right and +Z up, so both axes are reversed and a half turn is what makes the arrows agree left-to-right. Display only — the record and the stored arrays are untouched", - "plot_orientation_note": "Affects the 2D finger canvas only: the stored flow, valid mask and recorded data keep the domain's own orientation. The 3D view is not affected (its frame is the design export's)", + "plot_orientation_tip": "Affects the 2D view only; default rotation is 180°.", + "plot_orientation_note": "Affects the 2D view only; default rotation is 180°.", "orientation_identity": "As drawn (no rotation)", "orientation_rotate180": "Rotate 180° (default)", "orientation_mirror_h": "Mirror horizontally", @@ -89,7 +89,7 @@ "filter_preset_tip": "A ready-made combination; editing any value below switches to Custom", "filter_preset_custom": "Custom", "filter_flow_ema": "Flow EMA α", - "filter_flow_ema_tip": "Temporal smoothing of the optical flow. 1.00 = off. It changes what is *measured* (contact statistics and forces along with it), so two recordings with different α are not comparable — only use it when the flow jitter really has to go", + "filter_flow_ema_tip": "1.00 is off. Changing it changes the measured force.", "filter_median": "Median window", "filter_median_tip": "Sliding-median window over the force readings (samples). 1 = off. Removes single-sample spikes at the cost of about half a window of delay", "filter_lowpass": "Low-pass cutoff", @@ -116,7 +116,7 @@ "choose_video": "Choose a recorded video…", "choose_video_tip": "Open a recorded video: the 2D panel plays it and the charts read the forces.csv beside it", "recompute": "Analyze video…", - "recompute_tip": "Serve a stored analysis result for this video, or run the pass if there is none. The 2D panel can then draw arrows and depth; the charts may show force from the result. Stop cancels a pass that is still running. To change profile, calibration or reference frame use Analysis ▸ Analysis setup…", + "recompute_tip": "Use a result if there is one; otherwise analyse. Change settings in Analysis setup.", "replay_view_only": "Open a recording from the History replay view", "preview": "Preview", "preview_stop": "Stop preview", @@ -143,7 +143,7 @@ "reset_display": "Reset display", "reset_display_tip": "Clear the accumulated display: the curves, cursor and value cards go back to their defaults and the replay returns to the start of the recording. There is no device session in this view, so nothing of the device is touched; the 3D camera is View ▸ Reset views (F8).", "pause": "⏸ Pause", - "pause_tip": "Pause the computation and the display (F7): no flow, depth or contact is computed, the picture holds its last frame, and the device stays connected for an immediate resume. A recording that spans a pause has a gap.", + "pause_tip": "Pause computation; the picture holds and the device stays connected (F7).", "resume_tip": "Resume the computation and the display (F7), from the newest frame.", "resume_label": "▶ Resume", "resume_label_tip": "Resume the computation and the display (F7): it carries on from the newest frame with the device still connected.", @@ -210,8 +210,8 @@ "view_mode_tip": "Image display mode while running", "arrow_settings_tip": "Finger 2D presentation (orientation; display only)", "replay_pipeline": "Recorded video (raw camera image)", - "replay_pipeline_tip": "Replay shows the recorded raw camera image with no live arrow overlay; to get arrows and depth from analysis, use View → Analyze video", - "replay_raw_note": "No analysis result yet. Opening a recording runs analysis, or choose Analyze video… above.", + "replay_pipeline_tip": "This is the recorded camera image. For arrows and depth use Analysis ▸ Analyze video.", + "replay_raw_note": "No analysis result yet; use Analysis ▸ Analyze video.", "frame_missing_note": "This frame carries no {fields}: there is nothing for this view to draw", "field_flow": "flow", "field_depth": "depth", @@ -222,9 +222,8 @@ "arrow_empty_tip": "The deformation arrow image appears here while running or previewing", "arrow_render_failed": "Flow arrows could not be drawn for this frame\nTry another view, or reload the video", "arrow_capture_unavailable": "The captured frame is not available for this overlay\nThe raw camera view is still one selection away", - "depth_unavailable": "No depth data for this frame\n(not a depth of zero, and no silent fallback to the processed image)", + "depth_unavailable": "No depth data for this frame", "depth_scale": "Depth scale {low} – {high}", - "depth_empty": "This frame's depth is all zeros (0 of {pixels} px non-zero): the ramp's low colour is a real zero response, not missing data", "arrow_scale": "Arrows: displacement ×{factor}", "arrow_scale_tip": "Display magnification of the relative displacement: the arrows are drawn from the algorithm output of the captured image, with the measured displacement multiplied by this factor and capped at 0.8 of the grid spacing (a capped arrow no longer shows its true factor).", "arrow_pipeline": "Captured image → algorithm output", @@ -246,9 +245,9 @@ "mesh3d_unavailable_gl_reason": "3D is not available on this machine: {reason}\nMeasuring, recording and the charts work as usual.", "mesh3d_settings_tip": "3D display settings (view, housing, colour scale, frame rate)", "mesh3d_reset_tip": "Reset view: back to the framing the scene itself uses", - "replay_analysis_running": "this recording is being analysed: there are no arrows or depth to draw until it finishes. Progress and Cancel are on the analysis panel.", - "replay_analysis_failed": "there is no analysis result to draw: {reason}. Only the raw camera image can be shown here; once that is dealt with, Analyze video runs the pass again by hand.", - "replay_analysis_unavailable": "This video has no analysis setup. Choose Analyze video… above to select one and generate results." + "replay_analysis_running": "Analysing; arrows and depth appear when it finishes.", + "replay_analysis_failed": "Analysis failed: {reason}.", + "replay_analysis_unavailable": "No analysis setup yet; use Analysis ▸ Analyze video." }, "chart": { "fn": "FN", @@ -267,7 +266,7 @@ "mode_replay": "Replaying a recording (browsing)", "mode_replay_tip": "The charts read the open recording; capture and recording continue", "mode_recomputed": "Recomputed from this video (browsing)", - "mode_recomputed_tip": "The charts read the force the analysis pass recomputed from this video and stored in its result. This is not the recorded forces.csv — no device measured these numbers", + "mode_recomputed_tip": "Curves come from this analysis, not forces.csv.", "mode_no_trace": "No force trace — {reason}", "mode_no_trace_tip": "There is nothing to plot, and the reason is a fact about the input rather than a loading state", "trace_not_analysed": "this video has not been analysed yet", @@ -280,10 +279,7 @@ "box_zoom_tip": "Switch to rubber-band zoom (drag a region on the chart)", "settings": "Chart settings", "settings_tip": "Time window, axis ranges, and the acquisition filters (screen and record use the same data)", - "selection": "Selection {duration}s / {samples} samples — {detail}", "selection_summary": "Selection {duration}s / {samples} samples", - "selection_detail": "mean {mean} · σ {std}", - "selection_peak_tip": "The large number is the selection's peak; the line under it is its mean", "selection_empty": "No valid samples in the selection", "value_unavailable": "n/a", "value_unavailable_tip": "No curve is loaded for {channel}, so it has no value in this unit (raw counts are never shown in its place)", @@ -298,7 +294,7 @@ "video_filter": "Recorded video (*.mp4 *.avi *.mov *.mkv);;All files (*)", "no_video": "This recording has no usable video segment", "open_failed": "Could not open that recording: {error}", - "not_a_recording": "“{name}” is not a recording: its folder has no forces.csv (a recording is the video plus forces.csv and session.json). Replay needs a recording; to just watch this video, open it as a video or use Analysis ▸ Analyze video.", + "not_a_recording": "No forces.csv beside it; cannot open as a recording.", "video_only_opened": "Opened “{name}”; no analysis result yet. Choose Analyze video… above to generate one.", "video_only_notice": "This video has no recording beside it (no forces.csv): it plays, but the force charts and the recording details are empty.", "video_only_panel": "This is not a recording, and this video cannot be decoded (no forces.csv beside it, and it does not read as playable video)\nYou can still try Analysis ▸ Analyze video", @@ -325,7 +321,7 @@ }, "video_analysis": { "title": "Analyse this video", - "video": "{name} — {frames} frames at {fps} fps ({seconds} s). It has no recording beside it (no forces.csv, no frames.csv), so the pass will work from a frame index generated for it.", + "video": "{name} — {frames} frames at {fps} fps", "profile": "Processing profile", "calibration": "Calibration", "calibration_default": "Profile default — {name}", @@ -487,7 +483,7 @@ "run_failed": "Run failed: {error}", "filters_saved": "Filter settings saved: {describe} (applies to the next session)", "rail_camera_fps": "camera {fps}", - "capture_slow": "The camera delivers less than the configured frame rate: {detail}. The recording keeps the real rate. This is a capture-side (camera/driver) matter that software cannot change: use a camera that really does deliver 30 fps — after checking that the cable or port is not slowing this one down — and measure again.", + "capture_slow": "Camera frame rate is below the configured value: {detail}.", "video_ended": "Video ended", "camera_disconnected": "Camera disconnected", "reset_ok": "Sensor tracker reset", @@ -510,7 +506,7 @@ "deform_tip": "Display-only magnification of the measured deformation. It changes the picture and nothing else: the recorded data, the calibration and the camera are not touched.", "deform_unavailable": "This data source provides no 3D displacement: the pane can only colour the surface, so exaggeration is unavailable.", "field": "Colour by", - "field_tip": "Which quantity colours the surface: the depth response (the chain's relative deformation response, unitless) or the optical-flow magnitude (the tracker's pixel displacement). Neither is a length in millimetres — both are approximate. When the chosen one cannot be drawn for a frame, the other is used and the line below says so.", + "field_tip": "Colour the surface by depth or optical flow.", "field_depth": "Depth response", "field_flow": "Optical flow magnitude", "field_substituted": "This frame shows {shown}, not the chosen {chosen}.", @@ -537,7 +533,7 @@ "max_fps_tip": "How many frames per second the 3D view draws. A display budget only: the camera and the recording are unaffected, and a dropped frame here is never a dropped sample.", "reset_view": "Reset view", "settings_title": "3D display settings", - "settings_hint": "Per-frame adaptive applies to both the 2D depth view and the 3D surface. Every other item affects the 3D display only. Measuring, recording and the charts are untouched, and each change applies at once.", + "settings_hint": "Per-frame adaptive applies to both 2D and 3D.", "legend": "{quantity} [{unit}] · {quality}", "legend_none": "No measurement on screen — the surface model is shown uncoloured", "quality_calibrated": "calibrated", diff --git a/apps/studio/config/locales/zh_CN.json b/apps/studio/config/locales/zh_CN.json index 5a49f25..8f491ed 100644 --- a/apps/studio/config/locales/zh_CN.json +++ b/apps/studio/config/locales/zh_CN.json @@ -38,7 +38,7 @@ "plot_settings": "绘图设置…", "rotate_arrows": "旋转箭头图 90°", "recompute": "分析视频", - "recompute_tip": "打开:有兼容的分析结果就直接用,没有就跑一遍分析。关闭:离开分析,有 forces.csv 时曲线读录制值。要改配置、标定或参考帧请用「分析 ▸ 分析设置…」。", + "recompute_tip": "有结果就用,没有就分析。改配置用分析设置。", "analysis_setup": "分析设置…", "analysis_setup_tip": "为这段视频选择配置、标定与参考帧,然后跑(或重跑)分析。", "run": "运行 / 停止", @@ -78,8 +78,8 @@ "reset_defaults": "恢复默认", "plot_orientation_group": "手指 2D 显示方向(只影响 2D 画面;3D 视图仍用设计坐标系)", "plot_orientation": "方向", - "plot_orientation_tip": "手指 2D 画布(展开域)的显示方向。默认 180° 是按展开图与设计坐标系推导出来的:画布的 +x 是设计系的 +X、屏幕向上是 −Z,与 3D 默认视图的 −X / +Z 正好都相反,因此需要旋转 180° 才能使箭头方向与 3D 视图一致。。只影响显示,不改变记录与存储的数组", - "plot_orientation_note": "只影响 2D 手指画布的显示:存储的光流、有效掩膜与录制数据始终保持域本身的朝向。3D 视图不受影响(它的坐标系是设计导出坐标系)", + "plot_orientation_tip": "只影响 2D 画面,默认旋转 180°。", + "plot_orientation_note": "只影响 2D 画面,默认旋转 180°。", "orientation_identity": "原始(不旋转)", "orientation_rotate180": "旋转 180°(默认)", "orientation_mirror_h": "水平镜像", @@ -89,7 +89,7 @@ "filter_preset_tip": "选择一档现成的滤波组合;改下面任一数值会变成“自定义”", "filter_preset_custom": "自定义", "filter_flow_ema": "光流 EMA α", - "filter_flow_ema_tip": "光流的时间平滑。1.00 = 关。它改变的是“测量本身”(接触统计与力值都会变),两个 α 不同的录制不可比 —— 只有确实需要压光流抖动时才调", + "filter_flow_ema_tip": "1.00 为关闭。改它会改变测到的力。", "filter_median": "中值窗口", "filter_median_tip": "力读数的滑动中值窗口(采样数)。1 = 关。去掉单点尖峰,代价是约半个窗口的延迟", "filter_lowpass": "低通截止", @@ -116,7 +116,7 @@ "choose_video": "选择录制视频…", "choose_video_tip": "打开一段录制的视频:2D 面板放视频,曲线读同目录的 forces.csv(原始记录值)", "recompute": "分析视频…", - "recompute_tip": "有兼容的分析结果就直接用,没有就跑一遍分析:2D 面板可画箭头与深度,曲线可读结果中的力。分析进行中可随时「停止」。要改配置、标定或参考帧请用「分析 ▸ 分析设置…」。", + "recompute_tip": "有结果就用,没有就分析。改配置用分析设置。", "replay_view_only": "请在「历史回放」视图里打开录像", "preview": "预览", "preview_stop": "停止预览", @@ -143,7 +143,7 @@ "reset_display": "复位显示", "reset_display_tip": "清空累积的显示:曲线、游标与数字卡恢复默认,回放回到录像开头。本视图没有设备会话,不会改动设备;三维视角请用「视图 → 复位视图」(F8)。", "pause": "⏸ 暂停", - "pause_tip": "暂停计算与显示(F7):不再做光流/深度/接触计算,画面停在最后一帧,设备保持连接,随时可继续。跨过暂停的记录会有一段空档。", + "pause_tip": "暂停计算,画面停住,设备保持连接(F7)。", "resume_tip": "继续计算与显示(F7),从最新一帧接着跑。", "resume_label": "▶ 继续", "resume_label_tip": "继续计算与显示(F7):从最新一帧接着跑,设备保持连接。", @@ -210,8 +210,8 @@ "view_mode_tip": "运行时的图像显示模式", "arrow_settings_tip": "手指 2D 显示方向(只影响画面)", "replay_pipeline": "录制视频(原始相机图像)", - "replay_pipeline_tip": "回放显示的是录制下来的原始相机图像,不含实时箭头叠加;要看分析得到的箭头与深度请用「视图 → 分析视频」", - "replay_raw_note": "尚无分析结果。打开录像会自动分析,或点顶部「分析视频…」。", + "replay_pipeline_tip": "这是录下的相机画面。箭头和深度用分析 ▸ 分析视频。", + "replay_raw_note": "尚无分析结果,请用分析 ▸ 分析视频。", "frame_missing_note": "本帧没有{fields}:这个视图这一帧没有数据可画", "field_flow": "光流", "field_depth": "深度", @@ -222,9 +222,8 @@ "arrow_empty_tip": "运行或预览后在此显示形变箭头图", "arrow_render_failed": "本帧无法绘制形变箭头\n请换一种视图,或重新加载视频", "arrow_capture_unavailable": "当前无法取得采集图像用于叠加\n原始相机画面仍可在同一选择器中查看", - "depth_unavailable": "本帧没有深度数据\n(不是深度为零,也未回退显示普通形变图)", + "depth_unavailable": "本帧没有深度数据", "depth_scale": "深度色标 {low} – {high}", - "depth_empty": "本帧深度全为 0({pixels} px 中 0 个非零):色标最低颜色是真实的零响应,不是缺数据", "arrow_scale": "箭头按位移放大 ×{factor}", "arrow_scale_tip": "相对位移的显示放大倍率:箭头由原始采集图像经算法输出,长度按测量位移放大后绘制,上限为网格间距的 0.8 倍;触顶的箭头不再呈现真实倍率。", "arrow_pipeline": "原始图像 → 算法输出", @@ -246,9 +245,9 @@ "mesh3d_unavailable_gl_reason": "本机无法使用三维显示:{reason}\n采集、记录与力曲线照常工作。", "mesh3d_settings_tip": "三维显示设置(视角、外壳、色标、显示频率)", "mesh3d_reset_tip": "复位视角:回到场景自带的取景", - "replay_analysis_running": "正在分析这个录像:跑完之前这里没有箭头/深度可画,进度与取消在分析面板上。", - "replay_analysis_failed": "没有可画的分析结果:{reason}。这里只能显示原始相机图像;处理完之后可以点「分析视频」再跑一遍。", - "replay_analysis_unavailable": "视频尚无分析配置。点顶部「分析视频…」选择配置并生成结果。" + "replay_analysis_running": "正在分析,完成后显示箭头与深度。", + "replay_analysis_failed": "分析失败:{reason}。", + "replay_analysis_unavailable": "尚无分析配置,请用分析 ▸ 分析视频。" }, "chart": { "fn": "FN", @@ -267,7 +266,7 @@ "mode_replay": "回放录制(浏览)", "mode_replay_tip": "曲线读的是打开的录制;回放期间采集与记录继续", "mode_recomputed": "从这段视频重算(浏览)", - "mode_recomputed_tip": "曲线读的是分析过程从这段视频重算、并存入结果的力。这不是记录的 forces.csv——没有任何设备测过这些数字", + "mode_recomputed_tip": "曲线来自这次分析,不是 forces.csv。", "mode_no_trace": "没有力曲线 — {reason}", "mode_no_trace_tip": "没有可画的东西,而原因是输入本身的事实,不是一种加载状态", "trace_not_analysed": "这段视频还没有分析过", @@ -280,10 +279,7 @@ "box_zoom_tip": "切换为框选放大(拖动图表框选区域)", "settings": "曲线图设置", "settings_tip": "时间窗口、纵轴量程,以及采集端滤波(界面与记录用同一份数据)", - "selection": "选区 {duration}s / {samples} 点 — {detail}", "selection_summary": "选区 {duration}s / {samples} 点", - "selection_detail": "均值 {mean} · σ {std}", - "selection_peak_tip": "上方大号数字是选区的峰值;均值为选区均值", "selection_empty": "选区无有效样本", "value_unavailable": "不可用", "value_unavailable_tip": "{channel} 轴未加载标定曲线,因此没有该单位的数值(不会以原始值替代)", @@ -298,7 +294,7 @@ "video_filter": "录制的视频 (*.mp4 *.avi *.mov *.mkv);;所有文件 (*)", "no_video": "这段录制没有可用的视频分段", "open_failed": "无法打开该录制: {error}", - "not_a_recording": "「{name}」不是一条记录:同目录没有 forces.csv(一条记录 = 录像 + forces.csv + session.json)。回放需要记录;只想看这段视频请直接打开视频,或用「分析视频」。", + "not_a_recording": "旁边没有 forces.csv,不能当记录打开。", "video_only_opened": "已打开「{name}」;尚无分析结果。点顶部「分析视频…」生成。", "video_only_notice": "这段视频没有配套记录(同目录无 forces.csv):可以播放,但力曲线与记录信息为空。", "video_only_panel": "这不是一条记录,而且无法解码这段视频(没有 forces.csv,也不像可播放的视频文件)\n可以试试 分析 ▸ 分析视频", @@ -325,7 +321,7 @@ }, "video_analysis": { "title": "分析这段视频", - "video": "{name} — {frames} 帧 @ {fps} fps({seconds} 秒)。它旁边没有录制(没有 forces.csv、没有 frames.csv),因此这一遍会按为它生成的帧索引来跑。", + "video": "{name} — {frames} 帧 @ {fps} fps", "profile": "处理配置", "calibration": "标定", "calibration_default": "配置默认 — {name}", @@ -487,7 +483,7 @@ "run_failed": "启动失败: {error}", "filters_saved": "滤波设置已保存:{describe}(下次采集生效)", "rail_camera_fps": "摄像头 {fps}", - "capture_slow": "摄像头交付的帧率低于配置值:{detail}。记录会按实际帧率保存。这是采集端(摄像头/驱动)的问题,软件改不了:换一个真正能达到 30 fps 的摄像头,或先确认线材/端口没有把它降速,然后再测。", + "capture_slow": "摄像头帧率低于配置:{detail}。", "video_ended": "视频已结束", "camera_disconnected": "摄像机已断开", "reset_ok": "传感器追踪器已重置", @@ -510,7 +506,7 @@ "deform_tip": "只放大画面上的形变显示。它只改图像:记录的数据、标定与算法相机都不受影响。", "deform_unavailable": "当前数据源未提供三维位移:本面板只有光流幅值的曲面着色,形变放大不可用。", "field": "颜色来源", - "field_tip": "三维表面用哪个量上色:深度响应(链路的相对形变响应,无量纲)或光流幅值(追踪器的像素位移大小)。两者都不是毫米,都是近似量;选中的那个若在这一帧画不出来,会自动改用另一个,并在这行下面说明。", + "field_tip": "用深度或光流给表面着色。", "field_depth": "深度响应", "field_flow": "光流幅值", "field_substituted": "这一帧画的是 {shown},不是所选的 {chosen}。", @@ -537,7 +533,7 @@ "max_fps_tip": "三维视图每秒绘制多少帧。这只是显示预算:摄像头与记录不受影响,这里丢的帧永远不会变成丢的样本。", "reset_view": "复位视角", "settings_title": "三维显示设置", - "settings_hint": "「每帧自适应」同时作用于二维深度图和三维表面;其余项只影响三维显示。采集、记录与力曲线不受影响,改完立即生效。", + "settings_hint": "每帧自适应同时作用于二维和三维。", "legend": "{quantity} [{unit}] · {quality}", "legend_none": "屏幕上没有测量值 — 仅显示不着色的表面模型", "quality_calibrated": "已标定", diff --git a/apps/studio/src/orisys_studio/frame_view.py b/apps/studio/src/orisys_studio/frame_view.py index 08576f3..0f2a707 100644 --- a/apps/studio/src/orisys_studio/frame_view.py +++ b/apps/studio/src/orisys_studio/frame_view.py @@ -161,25 +161,19 @@ class FrameView: panel.set_shared_depth_scale(span) def depth_scale_text(self, frame: ImageFrame | None = None) -> str: - """The colour scale, plus — when the frame's depth is exactly zero — why it is flat. + """The colour scale for the depth now on screen. - A depth view of an all-zero map is a flat island in the ramp's low colour, which - looks the same as a broken view. The frame knows which it is: the pass stored the - channel, its non-zero count and its range, so "0 of 84,000 pixels" can be said - instead of leaving the operator to wonder. It is not the same statement as - ``panels.depth_unavailable``, which is for a frame that carries no depth at all. + ``frame`` is kept so callers can pass the painted frame; the label is + the latched / adaptive / fixed span. A frame with no depth channel is + handled by ``panels.depth_unavailable``. """ + _ = frame span = self.active_depth_span() - text = "" if span is None else t( + if span is None: + return "" + return t( "panels.depth_scale", low=f"{span[0]:.3f}", high=f"{span[1]:.3f}" ) - if frame is None or frame.depth is None: - return text - array = np.asarray(frame.depth) - if array.size and not bool(np.any(array)): - empty = t("panels.depth_empty", pixels=int(array.size)) - return f"{text} · {empty}" if text else empty - return text def latched_domain_mask(self, frame: ImageFrame): """The 2D domain boundary to draw, latched for the session. diff --git a/apps/studio/tests/test_replay_analysis.py b/apps/studio/tests/test_replay_analysis.py index 87e7c28..78995e1 100644 --- a/apps/studio/tests/test_replay_analysis.py +++ b/apps/studio/tests/test_replay_analysis.py @@ -1527,17 +1527,18 @@ def test_the_nothing_to_draw_line_names_the_action_that_produces_a_result(): assert seen["zh_CN"] != seen["en_US"] -def test_the_empty_depth_note_is_not_the_missing_depth_note(): - """Both locales keep the two apart: a flat map is a reading, an absent one is not.""" +def test_depth_unavailable_is_a_short_absent_note(): + """Both locales say the frame has no depth, without explaining zero vs absent.""" from orisys_app_shared.i18n import set_locale try: for locale in ("zh_CN", "en_US"): set_locale(locale) - empty = t("panels.depth_empty", pixels=84000) absent = t("panels.depth_unavailable") - assert "84000" in empty or "84,000" in empty, empty - assert empty != absent + assert absent + assert "\n" not in absent, absent + scale = t("panels.depth_scale", low="0.000", high="1.000") + assert scale != absent finally: set_locale("zh_CN") diff --git a/apps/studio/tests/test_replay_wiring.py b/apps/studio/tests/test_replay_wiring.py index 804372d..ae38501 100644 --- a/apps/studio/tests/test_replay_wiring.py +++ b/apps/studio/tests/test_replay_wiring.py @@ -345,9 +345,9 @@ def test_the_operator_sees_the_cached_views_over_the_recording( # The depth view is the stored map, drawn through the window's own backend. This # result's map is exactly zero on every frame it holds — the box chain's depth is - # flat on this footage, which the panel has its own sentence for — and it is still a - # stored array of the result's own shape, so the pixels are checked against it rather - # than against a flat placeholder. + # flat on this footage — and it is still a stored array of the result's own shape, + # so the pixels are checked against it rather than against a flat placeholder. + # The colour-scale caption names the range only. _set_mode(window, DEPTH) target = active_frame assert target.depth is not None and target.depth_nonzero == 0 @@ -365,9 +365,9 @@ def test_the_operator_sees_the_cached_views_over_the_recording( "the depth view's pixels are not depth_map_to_bgr of the stored frame" ) assert not np.array_equal(shown, arrows_bgr), "the depth view drew the arrow view" - assert t("panels.depth_empty", pixels=int(target.depth.size)) in ( - window.arrow_panel.depth_scale_label.text() - ), "an exactly-zero depth map is not stated as such" + assert window.arrow_panel.depth_scale_label.text() == ( + window.frame_view.depth_scale_text(target) + ), "the depth caption is not the colour-scale range" # …and the recording's own picture is still reachable, at the same cursor. _set_mode(window, RECORDED)