feat(clip): 新增「选区截取」实验性功能 + 筛选态组复选框只作用于筛选结果 + 重采样统计不被省略

一、重采样面板统计信息不再被省略为 `…`
   - 根因:EdgePanelWidth 里数值列按"典型样例"(1h 1min 2s(1.23456 GHz))估宽,
     真实文本(16ms 182.614us(61.795 Hz))更长 => 绘制矩形不够宽 => 尾部被裁。
   - 新增 FormatIntervalWithFrequency() 作为「间隔(频率)」文本的唯一实现,
     宽度计算与绘制共用它;EdgePanelWidth 改为逐信号实测真实文本宽度取最大值。

二、筛选状态下组复选框只作用于「筛选出来的信号」
   - TabConfig 新增 SetGroupVisibleSubset / GroupAllVisibleSubset / GroupHasVisibleSubset,
     只读写掩码内元素,未通过筛选的信号可见性保持不变。
   - SignalPanel::BuildFilterMask 提供逐信号掩码(未筛选时返回 false,走整组语义)。
   - 组复选框的点击、绘制、行位图缓存键三处统一改用子集判定
     (只改绘制不改缓存键会导致勾选后复选框不刷新)。

三、新增实验性功能「选区截取」(EdgePanelKind::CLIP = 6,PLOT_CMD_LANE_CLIP = 14)
   - 菜单位置:实验性功能二级菜单,「重采样」之下、「自由标记」上方,带勾选。
   - 面板:逐信号一行(信号色叠底条目栏 + 右侧复选框,不可展开),内容可滚动;
     底部两个不滚动的按钮「截取为新信号」与「原始信号截取」;
     未启用双光标时两个按钮为空矩形并给出提示。
   - 截取为新信号:区间内原始数据(不烘焙)+ 继承源信号整套调整,
     名称为 <源信号名> (AAAA - BBBB)(显示时刻、保留三位小数、带 s),插入源信号下方,
     使用 AppendGroupAxis 新建的独立时间轴。
   - 原始信号截取:DataSet::ClipSignalRange 就地裁剪时间轴与采样,
     用新建+swap+shrink_to_fit 真正归还内存,并重算统计与轴的 minTime/maxTime/monotonic。
     调用前先 PauseDerivedAsync() 避免后台派生读到已释放采样。
   - 时间轴偏移参与区间比较:双光标是显示时刻(time+offsetTime),
     BuildClippedSignal 比较时加偏移,ClipSignalInPlace 换算回采样时刻(low-offsetTime)。
   - 同步点已全部补齐:LaneCarry(三处)/SplitLane/PruneLaneSignalItems/RemapAfterSignalInsert/
     purgeRefs/PanelSlotKey/CollectDebugBoxes/SceneContentHash/kEdgePanelKinds/kOrder/
     EdgePanelLayoutFor/EDGE_PANEL_MOVE/m_pendingPanelClose/MEAN_SCROLL/滚轮/悬停/
     SetLanePanelCollapsed/LanePanelCollapsed/QueryCursor。

make release 零 warning,产物 860,160 B。
This commit is contained in:
DeepSeek V4.1 Flash committed 2026-11-03 16:04:48 +08:00
1 parent 5d305cb10f
commit 62220477c0
18 files changed
+1263 -67

No files matched your search

@@ -337,6 +337,41 @@ namespace jdi
*/
bool BuildResampledSignal(int groupIndex, int signalIndex, double interval);
/**
* @brief 「选区截取 → 截取为新信号」:按 `[begin, end]` 区间截取出**新信号**。
*
* 语义(用户 2026-11-03 明确要求):
* * 采样值 = 源信号在该区间内的**原始数据**(不烘焙任何调整);
* * 名称 = `<源信号名> (AAAA - BBBB)`,其中 AAAA / BBBB 是选区左右端时刻,
* 以秒为单位、**保留三位小数**并带 `s` 单位(如 `(1.234s - 2.345s)`);
* * 插入到源信号下方,并**继承源信号的整套调整**(公式/系数/偏移/镜像/绝对值)。
*
* @param [IN] groupIndex 源信号所属分组下标。
* @param [IN] signalIndex 源信号下标。
* @param [IN] begin 选区左端(显示时刻,秒)。
* @param [IN] end 选区右端(显示时刻,秒)。
* @return 构建并插入成功返回 true。
*/
bool BuildClippedSignal(int groupIndex, int signalIndex, double begin, double end);
/**
* @brief 「选区截取 → 原始信号截取」:**破坏性**丢弃 `[begin, end]` 之外的采样。
*
* 与 `BuildClippedSignal` 不同,这里直接改写源信号的采样数据与所属时间轴:
* * 保留区间内的采样,区间外的采样与对应时间全部丢弃并释放(`shrink_to_fit`);
* * 名称不变,也不新增信号;
* * 重算统计(min/max/finiteCount/粗粒度包络)。
*
* ⚠️ 该操作**不可撤销**,因此面板按钮语义上等价于"就地截断原始信号"。
*
* @param [IN] groupIndex 分组下标。
* @param [IN] signalIndex 信号下标。
* @param [IN] begin 选区左端(显示时刻,秒)。
* @param [IN] end 选区右端(显示时刻,秒)。
* @return 成功返回 true。
*/
bool ClipSignalInPlace(int groupIndex, int signalIndex, double begin, double end);
/**
* @brief 把一条信号插入到「源信号」的下方,并同步各标签页的引用与可见性。
*