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:
1 parent
5d305cb10f
commit
62220477c0
18 files changed
+1263
-67
No files matched your search
@@ -9862,3 +9862,93 @@ frequency 1/0.016182614 -> 61.795 Hz
|
||||
1h 1min 2s freq -> 0.000273075 Hz (超低频不显示成 0)
|
||||
5.123ps -> 5.123 ps
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2026-11-03 第二十七轮(本机 dev):重采样统计不被省略 + 筛选态组复选框只作用于筛选结果 + 新增「选区截取」
|
||||
|
||||
### 1. 重采样面板统计信息不再被省略成 `…`
|
||||
|
||||
根因有两个,**同时**存在才导致截断:
|
||||
|
||||
1. `EdgePanelWidth` 里数值列按**典型样例**(`1h 1min 2s(1.23456 GHz)`)估算宽度,
|
||||
而真实值(`16ms 182.614us(61.795 Hz)`)更长 ⇒ 绘制矩形不够宽。
|
||||
2. 文本超出矩形后被裁掉,表现出来就是尾部看不到。
|
||||
|
||||
修法:
|
||||
* 新增 `FormatIntervalWithFrequency(seconds)`(`PlotViewInternal.hpp`)作为
|
||||
`间隔(频率)` 文本的**唯一实现**,宽度计算与绘制都调它。
|
||||
* `EdgePanelWidth` 改为**逐信号实测** `FormatIntervalWithFrequency(maxInterval/minInterval)`
|
||||
的真实宽度,取最大值(并保留一个典型值作为无勾选信号时的下限)。
|
||||
* 面板宽度仍受 `min(width, 绘图区宽 - 8px)` 约束,但宽度基线已按真实文本撑开。
|
||||
|
||||
⚠️ 规则:**面板宽度计算与绘制必须共用同一个"生成显示文本"的函数**。
|
||||
用样例文本估宽是这次截断的直接原因。
|
||||
|
||||
### 2. 筛选状态下组复选框只作用于「筛选出来的信号」
|
||||
|
||||
用户要求:*不论是否筛选,这个复选框影响的都只有当前组名下显示的元素*。
|
||||
|
||||
* `TabConfig` 新增 `SetGroupVisibleSubset(groupIndex, mask)` /
|
||||
`GroupAllVisibleSubset(...)` / `GroupHasVisibleSubset(...)`:
|
||||
只读写 `mask` 为 true 的元素(= 通过筛选的信号),其余信号**可见性不变**。
|
||||
* `SignalPanel::BuildFilterMask(groupIndex, mask)`:未筛选时返回 false(调用方走整组语义),
|
||||
筛选时返回逐信号掩码。
|
||||
* `SignalPanelInteraction` 的组复选框:
|
||||
- 筛选态:`GroupAllVisibleSubset` 判定三态;全选时 `SetGroupVisibleSubset`(只勾筛选结果),
|
||||
取消时逐个 `SetVisible(false)`(也只动筛选结果);
|
||||
- 非筛选态:保持原 `SetGroupVisible`。
|
||||
* `SignalPanelPaint` 的复选框绘制与**行位图缓存键**都改用同一套子集判定
|
||||
(只改绘制不改缓存键 ⇒ 勾选后复选框不刷新)。
|
||||
* 效果:筛选结果全勾 ⇒ 该组复选框显示已勾选;被筛掉的信号不受影响。
|
||||
|
||||
### 3. 新增实验性功能「选区截取」(`EdgePanelKind::CLIP = 6`)
|
||||
|
||||
位置:「实验性功能」二级菜单里,位于「重采样」之下、「自由标记」**上方**,
|
||||
带 `√` 的切换项(`PLOT_CMD_LANE_CLIP = 14`)。
|
||||
|
||||
**面板**(`Lane::clip` / `clipItems` / `clipPanel` / `clipScroll`,沿用可滚动列表布局):
|
||||
* 逐信号一行:**信号色叠底条目栏 + 右侧复选框**,**不可展开**(用户明确要求);
|
||||
* 信号过多时内容区滚动(滚轮 / 拖动滑块);
|
||||
* 底部**两个不参与滚动**的按钮:「截取为新信号」与「原始信号截取」;
|
||||
* ⚠️ **未启用双光标**(`CursorMode != DOUBLE`)时:两个按钮为**空矩形**(不可点),
|
||||
面板内居中显示提示「请先启用「双光标」模式」。
|
||||
|
||||
**两个按钮的语义**:
|
||||
| 按钮 | 采样值 | 样式 | 内存 |
|
||||
| --- | --- | --- | --- |
|
||||
| 截取为新信号 | 区间内**原始数据,不烘焙** | **继承源信号整套调整** | 新轴 + 新信号 |
|
||||
| 原始信号截取 | 保留区间内,**区间外丢弃** | 不变(就地改写源信号) | `shrink_to_fit` 归还 |
|
||||
|
||||
* 新信号名 = `<源信号名> (AAAA - BBBB)`,AAAA/BBBB 是选区两端**显示时刻**,
|
||||
`FormatDecimalFixed(..., 3)` + `s`(如 `m_MOT_Current_DCom[0] (1.234s - 2.345s)`)。
|
||||
* 插入到源信号下方(`InsertSignalBelowSource`),沿用它新增的独立时间轴
|
||||
(`DataSet::AppendGroupAxis`)。
|
||||
* 破坏性截取走 `DataSet::ClipSignalRange(groupIndex, signalIndex, low, high)`:
|
||||
同时裁剪 `axes[signal.axisIndex].time` 与 `values`(按下标对齐),
|
||||
用「新建 + swap + `shrink_to_fit`」真正归还内存,随后重算
|
||||
`ComputeStats`(min/max/finiteCount/粗粒度包络)与轴的 `minTime/maxTime/monotonic`。
|
||||
⚠️ 调用前先 `PauseDerivedAsync()`,避免后台派生读到已释放的采样。
|
||||
|
||||
**⚠️⚠️ 时间轴偏移必须参与区间比较**:
|
||||
双光标给出的是**显示时刻**(`time + offsetTime`),而采样时刻是 `time`。
|
||||
`BuildClippedSignal` 逐点比较用 `time + offsetTime`;
|
||||
`ClipSignalInPlace` 把区间换算回采样时刻 `low - offsetTime` / `high - offsetTime`。
|
||||
(不换算 ⇒ 带时间轴偏移的信号会截错区间。)
|
||||
|
||||
**同步点(漏一处就会出现"拆网格后条目指错信号")**:
|
||||
`LaneCarry`(三处:结构体字段 / 采集 / 回填)、`SplitLane`(状态 + 条目过滤)、
|
||||
`PruneLaneSignalItems`、`RemapAfterSignalInsert`、`PurgeSignalFromLanes` 的 `purgeRefs`、
|
||||
`PanelSlotKey`(按钮矩形)、`CollectDebugBoxes`、`SceneContentHash`、
|
||||
`kEdgePanelKinds[]`、`kOrder[]`(错开序数)、`EdgePanelLayoutFor` 的 `enabled/open/collapsed/storedX/storedY`、
|
||||
`EDGE_PANEL_MOVE` 的 `switch (m_edgePanelDragKind)`、`m_pendingPanelClose` 的 `switch (kind)`、
|
||||
MEAN_SCROLL / 滚轮 / 悬停 / `SetLanePanelCollapsed` / `LanePanelCollapsed` / `QueryCursor`。
|
||||
|
||||
### 4. 教训(延续上一轮)
|
||||
|
||||
* 新增 `EdgePanelKind` 时**每个 `switch (kind)` 都要补分支**(本轮 CLIP 一次补齐了全部);
|
||||
用 `grep "EdgePanelKind::RESAMPLE"` 反查所有需要同步的位置最省事。
|
||||
* 多层三元表达式(`enabled/open/collapsed/storedX`)手工加一层极易多/少一个 `)`,
|
||||
本轮因此连续 3 次编译失败。**改这类表达式时先用 Python 数列数括号**,或改成查表。
|
||||
* `make clean` 在用户正开着 `Target.exe` 时会失败(文件被占用),
|
||||
改用"删 `Build/Release/*.o` + `make`"做全量重编译验证即可。
|
||||
Reference in new issue
Block a user