分组折起热区与改名输入框修正 + 数据模型去冗余(单一名称)+ 新增 Components/Shared 组件 + 过时注释/命名大清理 + 二进制瘦身 25.6%
## 一、UI 交互修复(用户报告) ① 分组折起热区(用户要求):点分组**名称**不再折起,只有**折叠三角**或**「组X」标签** 才折起。RowPart 新增 GROUP_TITLE;RowHitPart() 为分组行判出三角 / 复选框 / 关闭 ✕ / 「组X」标签矩形 / 其余 BODY;OnLButtonDown 只在这两个热区调用 ToggleGroupFromRow()。 附带:双击「组X」不再进入改名(该区域现为折起热区),双击分组名仍可改名。 ② 分组改名输入框不再吞掉「N 项」:RowNameRect() 对分组行的右边界改为「项数左边缘 − 6*scale」; 新增 GroupLabelText()/GroupStatsText() 作为文本与宽度的唯一来源(PaintGroupRow 与 RowNameRect 共用),避免名称可用宽度与实际绘制文本漂移。 ## 二、数据模型去冗余(用户指出的重点) - SignalData / SignalGroup **只保留一个名称字段** name:删除 displayName、删除 Title() (31 处调用点改为直接用 name);DataSet::SetSignalDisplayName / SetGroupDisplayName → RenameSignal / RenameGroup,且**空串 / 纯空白一律拒绝**(名称不再有回退值)。 依据:信号靠 SignalRef 下标定位、从不按名字匹配 ⇒ 两个字段是同一语义的两份副本。 收益:每条信号 / 每个分组少一个 std::wstring(24B + 堆分配)与一条 Title() 分支。 - 删除 Application::m_loadingBytes(全仓既不读也不写的死成员,注释却称“用于展示体积”)。 ## 三、新增 Components/Shared 组件(通用 UI 控件) - 从 Utilities/PaintUtil.* 迁出全部「控件类」绘制/命中:图标(+ / ✕ / 三角)、复选框、 滑块(UiSliderRatioFromX / UiDrawSlider)、内联输入框(UiDrawEditField / UiDrawEditFieldContent / UiEditTextLeft / UiEditOffsetAt / UiEditFieldMouseDown / UiEditFieldMouseMove)、颜色样块(UiDrawSwatch / UiSwatchNeedsOutline)、 取值胶囊配色(UiInk / UiColorLuminance / UiContrastInk)。 - PaintUtil.* 只保留低层绘制原语(矩形 / 圆角 / 直线 / 批量实线 / 颜色混合 / 文本与测量)。 - 依赖方向固定:Components/* → Components/Shared → Utilities(不得反向,Utilities 不再含控件)。 - Makefile 与 .preflight/perf/build.ps1 已登记新目录;调用方改 include "UiControls.hpp"。 ## 四、过时注释 / 命名批量修正(承接上一轮未做完的部分) - 注释:文件下标→分组下标、文件内信号下标→组内信号下标、所属文件下标→所属分组下标; 措辞统一 文件分组→分组、移除该文件→移除该分组、打开 CSV 文件→打开数据文件 等一批。 - 文不对题的形参名:VisibleIndexRange(const TimeAxis& file,…) → axis; Application::LoadFileAsync(…, SignalGroup& file,…) → group。 - 函数名里的 File 语义(上一轮只改了 RowKind::FILE):PaintFileRow→PaintGroupRow、 FileCloseRect→GroupCloseRect、OpenFileMenu→OpenGroupMenu、FileGroupLabelWidth→GroupLabelWidth、 StyleEditField::FILE_NAME→GROUP_TITLE;局部变量 fileRow/fileHeight/isFile → groupRow/groupHeight/isGroup。 - 修复 DataModel.hpp 两处被压扁的注释块(/**<TAB><TAB>* @brief …)与 Application::NewTab 上方重复的文档块。 - ⚠️ 踩坑:GROUP_NAME 撞上 nb30.h(windows.h 引入)的 #define GROUP_NAME 0x80, 导致枚举编译失败,改名 GROUP_TITLE 解决。 ## 五、二进制瘦身:1 013 248 → 754 176 B(−25.6%,省 259 KB) - 真因不是 PlotView.cpp,而是 Resources/JustDataInspector.ico 里 **256×256@32bpp 以未压缩 BMP 存储的条目(270 376 B,占整包 27%)**。改为 PNG 存储(Vista+ 标准做法,观感零变化) ⇒ 该条目 270 376 → 11 280 B、整个 ico 302 430 → 43 334 B(小尺寸仍保留 BMP)。 - 实测结论:“拆分大文件 ⇒ 瘦身”不成立(同一批机器码仍要进二进制); -ffunction-sections/-fdata-sections/-Wl,--gc-sections 在本工程反而 +9 216 B(已回退)。 - ⚠️ .o 体积受节对齐/重定位表主导,判断“代码搬去哪了”要用 nm,不要看 .o 字节数。 ## 六、验证(全部离屏:SW_HIDE + 不注入真实输入 + 进程/线程 BELOW_NORMAL) - panelanim 156/156(连跑 5 次稳定;新增/更新:点分组名不折起也不滚动、扫掠定位「组X」热区、 筛选态与普通态折叠三角逐像素一致、改名输入框右边界早于项数文本);verify 49/49; datacheck 69/69(含“重命名写入唯一名称字段且空名被拒”);edgecheck 46/46。 - A/B:回退两处 UI 修复 ⇒ 10 项如实失败;恢复后全绿。 - make release / make debug 零警告。 ## 七、本轮未完成(已在报告与 agent_mem.md 中如实记录) - PlotView.cpp(13 695 行 / 544 KB)按功能拆分为多个协作文件:未执行。 前置改造是把第 13–888 行的匿名命名空间(~870 行常量与工具函数)改成具名命名空间并逐个 inline,再逐个文件搬移并反复验证;时间不足以安全完成,故主动不做(附可执行方案)。 - SignalPanel.cpp / Application.cpp / DataModel.cpp 的多文件化、Lane 抽出 LanePanelState、 SetStatusMessage 模态阻塞解耦:均未执行。 ## 八、文档 - 新增 Documents/refactor_report_2026-10-16.md(本轮详细报告); 删除 Documents/refactor_report_2026-10-15.md(有效内容已并入 agent_mem.md 与本报告)。 - Documents/agent_mem.md 新增 §9.37 与 §11.2 第 85–90 条;更新数据层架构摘要(单一名称字段); §12 历史附录加“时效声明”。
This commit is contained in:
1 parent
5831a0ea0d
commit
0871eb0cba
22 files changed
+1268
-1010
No files matched your search
+130
-6
@@ -1367,12 +1367,12 @@ GDI+ 抗锯齿逐段扫描这些**近竖直、满幅**的边,代价爆炸(
|
||||
* **新增 `TimeAxis`**:`{ name, time, minTime, maxTime, monotonic, finiteCount }`。
|
||||
* **`SignalData`**:删除 `rawHeader`(`name` 的副本)与 `unit`(由列名猜出、全仓无人使用);
|
||||
新增 **`axisIndex`** 指向所属时间轴 ⇒ 采样值与时间的对应关系**自包含**,不再需要「文件」。
|
||||
名字只剩两个且职责明确:`name`(源名称,永不改写)/ `displayName`(用户重命名)。
|
||||
* **`SignalGroup`(原 `DataFile`)**:`{ name(默认=源文件名), displayName, axes[], signals[] }`;
|
||||
⚠️ 名称字段**只有一个 `name`**(2026-10-16 起去掉 `displayName` 与 `Title()`,见 §9.37 / 第 87 条)。
|
||||
* **`SignalGroup`(原 `DataFile`)**:`{ name(默认=源文件名), axes[], signals[] }`;
|
||||
**删除** `filePath` / `fileName` / `time` / `timeColumnName` / `timeMonotonic` / `minTime` / `maxTime`。
|
||||
新增 `AxisOf(signal)` / `AxisAt(i)` / `TimeRange(low, high)`(多轴并集)。
|
||||
* **`SignalRef::fileIndex` → `groupIndex`**;`DataSet`:`AddGroup` / `RemoveGroup` / `GroupAt` / `GroupCount` /
|
||||
`Groups()` / `SetGroupDisplayName` / `RemapSelectionAfterGroupRemoval` + 新增 **`Axis(ref)`**。
|
||||
`Groups()` / **`RenameSignal` / `RenameGroup`** / `RemapSelectionAfterGroupRemoval` + 新增 **`Axis(ref)`**。
|
||||
* `TabConfig`:`SetGroupVisible` / `GroupHasVisible` / `GroupAllVisible` / `RemapAfterGroupRemoval`;
|
||||
`RowKind::GROUP`、`CMD_GROUP_*`。
|
||||
* **采样/统计 API 首参由 `const DataFile&` 改为 `const TimeAxis&`**:
|
||||
@@ -2091,7 +2091,7 @@ GDI+ 抗锯齿逐段扫描这些**近竖直、满幅**的边,代价爆炸(
|
||||
#### 三、筛选态折叠三角状态修正
|
||||
|
||||
- **用户报告**:筛选时分组行的小三角维持在了筛选前的状态,展开/折起都不变化。
|
||||
- **根因**:`PaintFileRow` 直接读 `m_tab->IsCollapsed(...)`(普通模式的折叠状态),
|
||||
- **根因**:`PaintGroupRow` 直接读 `m_tab->IsCollapsed(...)`(普通模式的折叠状态),
|
||||
而筛选模式用的是**独立**的 `m_filterCollapsed`(§9.35 二)⇒ 筛选里折叠时三角形不变。
|
||||
- **修法**:改为统一的 `IsGroupCollapsed(groupIndex)`(按当前模式分派)。
|
||||
- **验证**:离屏像素对比 —— 「筛选态折叠」与「普通态折叠」的组名行(含三角)**逐像素 0 差异**;
|
||||
@@ -2131,6 +2131,95 @@ GDI+ 抗锯齿逐段扫描这些**近竖直、满幅**的边,代价爆炸(
|
||||
|
||||
---
|
||||
|
||||
### 9.37 分组折起热区与改名输入框修正 + 数据模型去冗余(单一名称)+ `Components/Shared` 组件 + 二进制瘦身(本轮,本机)
|
||||
|
||||
> 本轮(用户 2026-10-16 第三轮,本机 = 另一台设备)。报告:
|
||||
> `Documents/refactor_report_2026-10-16.md`(已删除上一轮的 `refactor_report_2026-10-15.md`)。
|
||||
> 离屏验证:`panelanim` **156/156**、`verify` **49/49**、`datacheck` **69/69**、`edgecheck` **46/46**;
|
||||
> A/B **10 项如实失败**;`make release` / `make debug` 零警告。
|
||||
|
||||
#### 一、分组折起热区:只有折叠三角与「组X」标签可折起
|
||||
|
||||
- **需求**:点分组**名称**不折起;只有折叠三角或「组X」标签才折起。
|
||||
- **实现**:`RowPart` 新增 **`GROUP_TITLE`**;`RowHitPart()` 为分组行判
|
||||
三角 → 复选框 → 关闭 ✕ → **「组X」标签矩形(`checkRect.Right + 8*scale` 起,宽 `GroupLabelWidth`)**
|
||||
→ 否则 `BODY`;`OnLButtonDown` 仅在 `DISCLOSURE` / `GROUP_TITLE` 时调用 `ToggleGroupFromRow()`。
|
||||
- 附带:双击「组X」不再进入改名(该区域现为折起热区);双击分组名仍改名。
|
||||
|
||||
#### 二、分组改名输入框不再吞掉「N 项」
|
||||
|
||||
- **根因**:`RowNameRect()`(分组行)右边界原先到关闭 ✕ 左侧,把右侧项数文本也框了进去。
|
||||
- **实现**:右边界改为 `项数左边缘 − 6*scale`;新增 **`GroupLabelText(groupIndex)`** 与
|
||||
**`GroupStatsText(row)`** 作为“绘制 / 命中 / 宽度”的唯一文本来源(`PaintGroupRow` 与
|
||||
`RowNameRect` 共用),避免名称宽度与实际绘制文本漂移。
|
||||
|
||||
#### 三、`SignalData` / `SignalGroup` 只保留**一个**名称字段
|
||||
|
||||
- **依据**(用户):信号靠 `SignalRef` 下标定位、从不按名字匹配 ⇒ `name` + `displayName`
|
||||
是同一语义的两份副本。
|
||||
- **改动**:删除 `displayName`;`name` 成为唯一名称字段(重命名即写入它);
|
||||
**删除 `Title()`**(31 处调用点改为 `.name` / `->name`);
|
||||
`DataSet::SetSignalDisplayName` → **`RenameSignal`**、`SetGroupDisplayName` → **`RenameGroup`**。
|
||||
- ⚠️ **语义收紧**:`RenameSignal/RenameGroup` 对**空串 / 纯空白一律拒绝**(不再表示“恢复源名称”)
|
||||
—— 名称不再有回退值。
|
||||
- 另删除 `Application::m_loadingBytes`(**全仓既不读也不写**的死成员)。
|
||||
|
||||
#### 四、新增 `Components/Shared` 组件(通用 UI 控件)
|
||||
|
||||
```
|
||||
Components/Shared/Inc/UiControls.hpp
|
||||
Components/Shared/Src/UiControls.cpp
|
||||
```
|
||||
|
||||
- 从 `Utilities/PaintUtil.*` **迁出**全部“控件类”绘制/命中:图标(+ / ✕ / 三角)、复选框、
|
||||
滑块(`UiSliderRatioFromX` / `UiDrawSlider`)、内联输入框(`UiDrawEditField` /
|
||||
`UiDrawEditFieldContent` / `UiEditTextLeft` / `UiEditOffsetAt` / `UiEditFieldMouseDown` /
|
||||
`UiEditFieldMouseMove`)、颜色样块(`UiDrawSwatch` / `UiSwatchNeedsOutline`)、
|
||||
取值胶囊配色(`UiInk` / `UiColorLuminance` / `UiContrastInk`)。
|
||||
- `PaintUtil.*` 只保留**低层绘制原语**(矩形 / 圆角 / 直线 / 批量实线 / 颜色混合 / 文本与测量)。
|
||||
- ⚠️ **依赖方向固定**:`Components/* → Components/Shared → Utilities`;
|
||||
`Utilities` **不得**再包含任何控件代码(也不要 include `UiControls.hpp`)。
|
||||
- ⚠️ 新增组件目录必须同时登记进 `Makefile` 的 `CXX_INCLUDES_PATHS` / `CXX_SOURCES_PATHS`
|
||||
以及 `.preflight/perf/build.ps1` 的 `$includes` / `$srcDirs`。
|
||||
|
||||
#### 五、二进制瘦身:1 013 248 → **754 176 B(−25.6%)**
|
||||
|
||||
- **真因**是 **`Resources/JustDataInspector.ico` 的 256×256@32bpp 条目以未压缩 BMP 存储
|
||||
(270 376 B,占整包 27%)**,而不是 `PlotView.cpp`。改为 **PNG 存储**(Vista+ 标准做法,
|
||||
观感零变化)⇒ 该条目 270 376 → **11 280 B**、整个 ico 302 430 → **43 334 B**。
|
||||
- ⚠️ **拆分大文件不会减小机器码**(“拆分 ⇒ 瘦身”不成立);实测
|
||||
`-ffunction-sections -fdata-sections -Wl,--gc-sections` 在本工程**反而 +9 216 B**(已回退)。
|
||||
- ⚠️ `.o` 体积受节对齐/重定位表主导,**判断“代码搬去哪了”要看 `nm`,不要看 `.o` 字节数**。
|
||||
|
||||
#### 六、过时注释 / 命名批量修正(承接上一轮未做完的部分)
|
||||
|
||||
- 参数与成员注释:`文件下标`→`分组下标`、`文件内信号下标`→`组内信号下标`、`所属文件下标`→`所属分组下标`
|
||||
等一批;措辞统一 `文件分组`→`分组`、`移除该文件`→`移除该分组`、`打开 CSV 文件`→`打开数据文件` …;
|
||||
- **文不对题的形参名**:`VisibleIndexRange(const TimeAxis& file, …)` → `axis`;
|
||||
`Application::LoadFileAsync(…, SignalGroup& file, …)` → `group`;
|
||||
- **函数名里的 “File 语义”**(上一轮只改了 `RowKind::FILE`):`PaintFileRow`→`PaintGroupRow`、
|
||||
`FileCloseRect`→`GroupCloseRect`、`OpenFileMenu`→`OpenGroupMenu`、
|
||||
`FileGroupLabelWidth`→`GroupLabelWidth`、`StyleEditField::FILE_NAME`→`GROUP_TITLE`;
|
||||
局部变量 `fileRow/fileHeight/isFile` → `groupRow/groupHeight/isGroup`;
|
||||
- 修复 `DataModel.hpp` 两处被压扁的注释块(`/**\t\t * @brief …`)与 `Application::NewTab`
|
||||
上方重复的文档块;
|
||||
- ⚠️⚠️ **新增标识符前必须确认不是 Windows 头里的宏**:本轮 `GROUP_NAME` 撞上
|
||||
`nb30.h`(由 `windows.h` 引入)的 `#define GROUP_NAME 0x80`,导致枚举编译失败,改名
|
||||
`GROUP_TITLE` 解决。同类高风险名:`GROUP_NAME`、`TIME`、`SMALL`、`NEAR`、`FAR`、`IGNORE`。
|
||||
|
||||
#### 七、本轮**未**完成(诚实记录,勿误以为已完成)
|
||||
|
||||
1. **`PlotView.cpp`(13 695 行 / 544 KB)按功能拆分**:未执行。前置改造是把第 13–888 行的
|
||||
匿名命名空间(~870 行常量与工具函数)改成具名命名空间并**逐个 `inline`**,
|
||||
再做 5 个协作文件的搬移;必须“搬一类 → 编译 → 跑四套探针”反复迭代,本轮时间不足以安全完成。
|
||||
⚠️ 切勿草率动手 —— 它会直接影响 `Paint()` 分支顺序与图层/装饰缓存不变量(见 §11.2)。
|
||||
2. `SignalPanel.cpp`(145 KB)/ `Application.cpp`(104 KB)/ `DataModel.cpp`(88 KB)的多文件化:
|
||||
未执行。三者中 **`SignalPanel.cpp` 的辅助区只有 ~60 行,是性价比最高的下一个拆分入口**。
|
||||
3. `Lane` 抽出 `LanePanelState`(内聚性重构):未执行。
|
||||
4. `SetStatusMessage(..., isError)` 的模态阻塞解耦:未执行(需要用户拍板提示样式)。
|
||||
|
||||
---
|
||||
|
||||
## 10. 变更日志(本文件维护记录)
|
||||
|
||||
| 日期 | 设备/模型 | 摘要 |
|
||||
@@ -2180,6 +2269,7 @@ GDI+ 抗锯齿逐段扫描这些**近竖直、满幅**的边,代价爆炸(
|
||||
| 2026-10-15 | DeepSeek-V4.1-Flash(**起源设备**) | **信号面板滚动条跟随 / 工具栏连点丢状态 / 图层网格线步长 / 多网格单点自适应 / 单点信号拖拽(详见 §9.32)**。① **滚动条"卡住"**:`Application::WM_MOUSEMOVE` 的 `plotOnlyMove` 只看 `inPlot && m_mouseOverPlot`,拖滚动条进绘图区后判定"只影响绘图区"⇒ 面板滚动值变了却不重绘;修法:新增 `draggingNonPlot`(正在拖非绘图区组件时一律完整失效)。② **工具栏丢点击**:窗口类带 `CS_DBLCLKS` ⇒ 快速第二次按下被合成 `WM_LBUTTONDBLCLK` 而工具栏没处理(**按下丢失**);且 `HandleMouseMove` 只要不在工具栏上就 `OnMouseLeave()` ⇒ 清掉 `m_pressedIndex`(按住划出再回按钮松手无效);两处都已修。③ **网格线错位/丢失/闪烁**:`PaintLane` 的竖向主刻步长取自 `Tab().ViewMin/ViewMax`,而渲染信号图层时该区间已被改成**宽窗口**(≈2×)⇒ 图层辅助线步长 2×、位置与前台不同、判重判据也错位;修法:新增 `m_renderTimeStep`,由 `RenderLaneLayerRegion` 用**前台跨度**算好传入。④ **多网格单点「适应视图」**:新增 `FitSinglePointLanes()`(左右边界 = 最左/最右数据点 ± **一个网格小格**;逐网格 Y 自适应、各留**一个 Y 小格**;全部点同刻 ⇒ 跨度 1s 居中;单值网格 ⇒ Y 跨度 1 居中)。⑤ **单点信号**:`HitTestSignal` 新增单点分支 + 环状光晕 + 可拖拽换网格(悬停**不改光标**,按下后才改)。验证:离屏 `.preflight/check` **67/67 通过**(连跑 3 次稳定);**A/B** 回退六处修复 ⇒ **17 项如实失败**(含 [C] 辅助线 49px vs 25px、20 vs 40 条、最大偏移 539px);`make release` 零警告、链接通过。 |
|
||||
| 2026-10-16 | DeepSeek-V4.1-Flash(**另一台设备**) | **分组折起/展开动画 + 筛选态可折起(项数按筛选计数)+ 悬浮组名可交互与"先滚动再折起" + 「适应视图」与「Y 轴自适应」彻底同源(详见 §9.35)**。① **折起动画**:`SignalPanel::m_groupAnims` + `GroupRowScale()` —— 每行速度倍率 `1 + 1.2×ordinal/(行数−1)`(**离组名越远越快收尽**)叠加 ease-out cubic(末段减速),总时长 `clamp(115+14×行数, 140, 300)` ms;`BuildRows` 输出**非整行高**,低于 0.75 逻辑 px 的行不再产生;宿主 `WM_TIMER` 同时驱动滚动与折起动画(`Render` 判定改为二者取或);新增 `SetRowClip/ClearRowClip` 把行内容裁到本行(否则垂直居中文本溢出到相邻行)。② **筛选态折起**:筛选模式改用**独立**的 `m_filterCollapsed`(默认展开,不污染普通列表),`ListRow::displayCount` 承载"该组内符合筛选条件的个数",筛选文本/清空/数据变化即清空。③ **悬浮组名可交互**:根因是 `HitRow` 只按滚动偏移映射行 ⇒ 点击穿透到下层;修法:`HitRow` 先用 `StickyGroupRowIndex()`+`StickyGroupRowTop()` 判定悬浮行矩形并临时用 `m_rowYOverrideActive` + 新的 `RowHitPart()` 算行内区域,并跳过高度为 0 的行;新增 `ToggleGroupFromRow()`:正悬浮时 `StartScrollAnimationTo(行内容偏移, groupIndex)`(挂起请求 `m_pendingGroupToggle`),滚动到位后才启动折起动画。④ **单点信号上两种自适应不一致**:`FitSinglePointCluster` 曾另算"半径留白 + 跨度 1"且把 `fitYToSelection` 置回 false ⇒ 点「适应视图」既改区间又**关掉 Y 轴自适应**;修法:单点簇只负责时间轴(居中 + 一大格 1s),**逐网格幅值轴与常规路径/Y 轴自适应完全同源**(`fitYToSelection` → `AutoRangeLaneToView`,否则 `autoRange=true`,再接 `ApplySinglePointValueMargins`),且**绝不改写** `fitYToSelection`。验证:新增离屏探针 `.preflight/perf/panelanim_main.cpp`(真实 `Application` + `SW_HIDE`)**94/94 通过**(连跑 3 次稳定;覆盖折起/展开的分帧过渡、单调收敛、越靠下越矮、末态精确无残留、筛选计数与独立折起状态、悬浮四个可交互区域全部命中且下层行仍可点、点击后"先滚动到位再折起"、真实 MF4 单点信号两种自适应逐位一致/往返稳定);**A/B** 三组(回退绘图区修复 / 禁用悬浮命中优先 / 动画时长置 0)分别 **4 / 13 / 8 项如实失败**;既有 `verify` **49/49**(顺带修正 4 条与远端新规则不符的过期断言)、`datacheck` **69/69**、`edgecheck` **46/46**;`make release` 零警告。 |
|
||||
| 2026-10-16 | DeepSeek-V4.1-Flash(**另一台设备**) | **动画改「抽拉卷尺」式刚性平移 + 筛选态折叠三角修正 + 样式区「目标」行绘制/布局修正(详见 §9.36)**。① **动画重做**(推翻上一轮的“按行缩放”):整组信号作为**刚性整体**平移,**行高永不变**、只维护一个逐行平移量 `m_rowShift` ⇒ 动画期间**无需重建行集合**(流畅关键);收起时逐条被组名栏吞掉、展开时逐条冒出;中途反向点击**从当前位移续接**不跳变;时长 `clamp(115+6×行数, 150, 320)` ms。② **藏进组名栏的裁剪**:信号行越过组名的**绘制**下边界即裁掉,且除 GDI 裁剪外**必须用 `g.SetClip(..., CombineModeIntersect)` 同时收紧 GDI+ 裁剪**(否则行内色块/复选框/徽标画到组名栏上)。③ **悬浮组名折起改为“一边滚动一边收起”**(推翻“先滚动到位再折起”):`scrollSynced` 让滚动与平移按同一进度推进 ⇒ 组名屏幕位置恒定;结束时滚动偏移恰好落在“组名正好在最上方”,并且**无跳变**;旧 `m_pendingGroupToggle` 机制删除。④ **筛选态折叠三角**:`PaintFileRow` 改读 `IsGroupCollapsed()`(筛选模式用的是独立的 `m_filterCollapsed`),修复“三角维持筛选前状态”。⑤ **「目标」行**:`PaintTargetRow` 误用列表裁剪版 `PaintRowText` ⇒ 名称与 GX 文本被完全裁掉(改用 `UiText`);GX 标签改为**右对齐到内容列右边缘**、名称无标签时占满内容列;`EditFieldRect()` 对目标行只返回名称矩形(否则改名输入框把 GX 标签包进去)。验证:离屏探针 `.preflight/perf/panelanim_main.cpp` **147/147 通过**(连跑 3 次稳定;含逐帧断言组名栏像素零变化、`m_rowsDirty` 恒 false、滚动单调且恰好落位、筛选/普通态折叠三角逐像素 0 差异、目标行文本像素存在与两端对齐);**A/B** 五组(回退筛选三角+非刚性平移 / 回退目标行绘制与布局 / 关闭同步滚动 / 去掉 GDI+ 收紧裁剪 / 不续接位移)分别 **4 / 6 / 6 / 2 / 1 项如实失败**;`verify` **49/49**、`datacheck` **69/69**、`edgecheck` **46/46**;`make clean && make all` 零警告。 |
|
||||
| 2026-10-16 | DeepSeek-V4.1-Flash(**另一台设备**) | **分组折起热区与改名输入框修正 + 数据模型去冗余(单一名称)+ 新增 `Components/Shared` 组件 + 过时注释/命名大清理 + 二进制瘦身 25.6%(详见 §9.37 与本轮报告 `Documents/refactor_report_2026-10-16.md`)**。① **折起热区**(用户要求):点分组**名称**不再折起,只有**折叠三角**或**「组X」标签**(新增 `RowPart::GROUP_TITLE`)才折起。② **分组改名输入框不再吞掉「N 项」**:`RowNameRect` 右边界改为项数左缘;新增 `GroupLabelText`/`GroupStatsText` 作为文本与宽度的唯一来源。③ **`SignalData`/`SignalGroup` 只留一个名称字段**:删除 `displayName` 与 `Title()`(31 处改用 `name`),`SetSignalDisplayName`/`SetGroupDisplayName` → **`RenameSignal`/`RenameGroup`**(空名一律拒绝);删除死成员 `Application::m_loadingBytes`。④ **新增 `Components/Shared`**(用户要求):从 `PaintUtil` 迁出全部**控件**(图标/复选框/滑块/内联输入框/颜色样块/取值胶囊配色)到 `UiControls.hpp/.cpp`,`PaintUtil` 只留低层原语;依赖方向固定 `Components/* → Components/Shared → Utilities`。⑤ **过时注释/命名**:`文件下标`→`分组下标`、`文件分组`→`分组` 等一批;形参名 `file`→`axis`/`group`;`PaintFileRow`→`PaintGroupRow`、`FileCloseRect`→`GroupCloseRect`、`OpenFileMenu`→`OpenGroupMenu`、`FileGroupLabelWidth`→`GroupLabelWidth`、`StyleEditField::FILE_NAME`→`GROUP_TITLE`;修复 `DataModel.hpp` 两处被压扁的注释块与 `NewTab` 重复文档块。⑥ **二进制瘦身**:真因是 **ICO 里 256×256 未压缩 BMP 条目(270 KB,占整包 27%)**,改为 **PNG 存储**(观感零变化)⇒ `Target.exe` **1 013 248 → 754 176 B(−25.6%)**;实测“拆分大文件不减小机器码”、`--gc-sections` 反而 +9 KB(已回退)。验证:`panelanim` **156/156**、`verify` **49/49**、`datacheck` **69/69**、`edgecheck` **46/46**;**A/B** 回退两处 UI 修复 **10 项如实失败**;`make release`/`make debug` 零警告。⚠️ **未完成(已如实记录)**:`PlotView.cpp`(13.7 K 行)与其它大文件的多文件化拆分、`LanePanelState` 抽取、模态提示解耦。 |
|
||||
|
||||
---
|
||||
|
||||
@@ -2505,7 +2595,7 @@ GDI+ 抗锯齿逐段扫描这些**近竖直、满幅**的边,代价爆炸(
|
||||
筛选只是临时子集视图,不该污染普通列表的布局选择;筛选文本变化 / 清空筛选 / 数据变化时
|
||||
一律清空它以及进行中的折起动画(行数与分组可见性都变了)。
|
||||
组名后方的项数必须按当前模式显示:普通 = 信号总数,筛选 = 该组内**符合筛选条件**的个数
|
||||
(`ListRow::displayCount`,在 `BuildRows` 里填好;`PaintFileRow` 只读它)。
|
||||
(`ListRow::displayCount`,在 `BuildRows` 里填好;`PaintGroupRow` 只读它)。
|
||||
⚠️ 推论:**所有“读取折起状态”的地方都必须用 `IsGroupCollapsed()`(按模式分派)**,
|
||||
不能直接读 `m_tab->IsCollapsed()` —— 否则筛选态折叠时**折叠三角不会变**
|
||||
(用户 2026-10-16 报告;已用“筛选态 vs 普通态折叠后组名行逐像素 0 差异”锁定)。
|
||||
@@ -2530,8 +2620,36 @@ GDI+ 抗锯齿逐段扫描这些**近竖直、满幅**的边,代价爆炸(
|
||||
**无 GX 标签时名称可用宽度 = 整个内容列**(因此更宽,仍左对齐)。
|
||||
⚠️ `EditFieldRect()` 对 `m_editRow < 0` 必须返回 `m_targetNameRect`(**只管名称那一块**),
|
||||
不能返回内容列全宽 —— 否则改名输入框会把 GX 标签包进去(用户报告)。
|
||||
84. ⚠️ **筛选态的折叠三角必须用 `IsGroupCollapsed()`**(见第 79 条推论):`PaintFileRow` 直接读
|
||||
84. ⚠️ **筛选态的折叠三角必须用 `IsGroupCollapsed()`**(见第 79 条推论):`PaintGroupRow` 直接读
|
||||
`m_tab->IsCollapsed()` 时,筛选模式里折叠/展开三角**不会变化**(用户 2026-10-16 报告)。
|
||||
85. ⚠️ **分组折起的热区只有两处**(用户 2026-10-16 第三轮要求):**折叠三角**(`RowPart::DISCLOSURE`)
|
||||
与**「组X」标签**(`RowPart::GROUP_TITLE`)。点击分组**名称本体**(`BODY`)**不得折起**
|
||||
(也不要触发滚动)。`RowHitPart()` 必须为分组行判出 `GROUP_TITLE`(标签矩形从
|
||||
`checkRect.Right + 8*scale` 起、宽 `GroupLabelWidth(row)`);`OnLButtonDown` 只在
|
||||
这两个区域调用 `ToggleGroupFromRow()`。
|
||||
86. ⚠️ **分组改名输入框不得覆盖右侧的「N 项」计数**(用户 2026-10-16 报告):
|
||||
`RowNameRect()` 对分组行的右边界 = `项数左边缘 − 6*scale`。
|
||||
✓ 项数文本与它的宽度必须走**同一个来源** `GroupStatsText(row)`(`GroupLabelText(groupIndex)`
|
||||
同理),否则“名称可用宽度”与“实际绘制文本”会漂移。
|
||||
87. ⚠️ **`SignalData` / `SignalGroup` 只有一个名称字段 `name`**(用户 2026-10-16 明确要求):
|
||||
它既是加载时的列名 / 通道名,也是用户重命名写入的地方;**不要再引入 `displayName`
|
||||
或 `Title()` 之类的第二份副本**(信号靠 `SignalRef` 下标定位,从不按名字匹配)。
|
||||
`RenameSignal(group, signal, name)` / `RenameGroup(group, name)` 对**空串 / 纯空白一律拒绝**
|
||||
(名称不再有“回退值”)。
|
||||
88. ⚠️ **通用 UI 控件属于 `Components/Shared`**(用户 2026-10-16 要求建此组件):
|
||||
图标 / 复选框 / 滑块 / 内联输入框 / 颜色样块 / 取值胶囊配色都在
|
||||
`Components/Shared/Inc/UiControls.hpp`;`Utilities/PaintUtil.*` **只保留低层绘制原语**。
|
||||
依赖方向固定 `Components/* → Components/Shared → Utilities`,**不得反向**。
|
||||
新增组件目录要同时登记 `Makefile`(`CXX_INCLUDES_PATHS` / `CXX_SOURCES_PATHS`)与
|
||||
`.preflight/perf/build.ps1`。
|
||||
89. ⚠️⚠️ **新增标识符前必须确认不是 Windows 头里的宏**:`windows.h` 会引入 `nb30.h` 的
|
||||
`#define GROUP_NAME 0x80` ⇒ 用它做枚举成员会编译失败(“expected identifier before numeric
|
||||
constant”)。同类高风险名:`GROUP_NAME`、`TIME`、`SMALL`、`NEAR`、`FAR`、`IGNORE`、`DELETE`。
|
||||
90. ⚠️ **二进制体积的真正大头是 ICO 里未压缩的 256×256 条目**(本轮实测占整包 27%):
|
||||
应把它按 **PNG** 存储(Vista+ 标准,观感零变化),小尺寸保留 BMP。
|
||||
⚠️ **拆分大文件不会减小机器码**;“拆分 ⇒ 瘦身”不成立。
|
||||
⚠️ `-ffunction-sections/-fdata-sections/--gc-sections` 在本工程**反而增大 9 KB**(已回退)。
|
||||
⚠️ `.o` 字节数受节对齐/重定位表主导,**判断“代码搬去哪了”要用 `nm`,不要看 `.o` 大小**。
|
||||
71. ⚠️ **`FitAll()` 在没有任何可见信号时不得置位 `Tab().ViewInitialized()`**:
|
||||
否则用户先连点几次「适应视图」(此时无信号被勾选)再勾选第一个信号,
|
||||
`Application::SynchronizeView` 会**跳过初次自适应**,视界停在“无信号”那次的整段范围上,
|
||||
@@ -2579,6 +2697,12 @@ GDI+ 抗锯齿逐段扫描这些**近竖直、满幅**的边,代价爆炸(
|
||||
|
||||
## 12. 起源设备详细工程记忆(原文附录)
|
||||
|
||||
> ⚠️⚠️ **时效声明**:本节是**历史原文**,成文于数据层大重构与后续多轮修改**之前**。
|
||||
> 其中出现的 `DataFile` / `fileName` / `SignalData::displayName` / `Title()` /
|
||||
> `SetSignalDisplayName` / `SetFileDisplayName` / `PaintFileRow` / `FileCloseRect` /
|
||||
> `FileGroupLabelWidth` 等**符号已全部更名或删除**,请勿照抄。
|
||||
> 现行约定一律以 **§1–§11** 为准(§11.2 是硬约束权威清单)。
|
||||
|
||||
> 以下为起源设备(本机)Agent 的**详细工程记忆原文**,与 §1–§10 同处**一个记忆文件**(不再另建文件)。
|
||||
> ⚠️ 其它设备更新本文件时**请保留本节**;可继续在本节之后追加。
|
||||
|
||||
|
||||
Reference in new issue
Block a user