预览曲线按面板高亮 + 统计数字不再卡在“统计中…” + 中心轴面板改表格 + 默认主题 Light + 标签页 DPI 修复 + 布局边界幽灵元素
一、预览曲线悬停高亮(只开弱峰+中心轴时无反应;三个全开时总亮均值曲线)
根因:PaintLaneDerivedOverlays 里只有 MEAN 分支传 highlight,且悬停状态没有记录面板种类。
修法:新增 m_meanRowHoverKind,高亮条件 = 悬停行 == 本行 && 面板种类 == 本曲线来源;
条目栏强调色同样按种类门控;悬停种类进入面板缓存键。
二、统计数字松手后停在“统计中…”
根因:交互期间面板缓存键被冻结(为拖动跟手),冻结期满后没有重绘请求(鼠标已停、
统计也已完成),最后一次绘制仍是冻结帧。
修法:记录 m_panelKeysFrozen 并公开 PanelRefreshPending();Render 末尾把它并入
滚动动画定时器的武装条件 ⇒ 空闲后自动补一帧真实数字,随后停表。
三、「中心轴边沿计数」面板改为表格
表头固定:信号名 / 上升沿计数 / 下降沿计数;每行底色 = 该信号配色(未勾选的行普通底色),
三列与表头严格对齐,内容可滚动,单击行展开两行参数滑块。
- EdgePanelLayout 新增 tableHeader / tableColumns[3];EdgePanelLayoutFor 新增 centerTable 分支;
- 新增 EdgeCenterTableHeader() / EdgeCountCellText();EnsureEdgeCenterItem 默认 collapsed;
- PanelSlotKey 的 CENTER 分支改为按 item 判断并混合计数(表格已没有 rowStats)。
四、默认主题改为 Light(Application、ThemeFor/ThemeName 默认分支、CurrentTheme 兜底)。
五、标签页文本在 DPI 切换后被省略
根因:标签宽度恰好等于“内边距+文本+间距+关闭按钮”,无任何余量;TabItemWidget 缓存了
Configure 时的 scale 并用它反推可用文本宽度,而 TabBar::SetScale 不重建控件树
⇒ 125%→100% 后可用宽度少约 4.5px ⇒ 吃掉末字。
修法:SetScale 变化时重建控件树;并把文本可用矩形改由 ArrangeWidgets 统一下发
(SetState 增加 textRect 参数),绘制侧不再自行反推。
六、布局边界里的幽灵元素
- 新增 SignalPanel::HasStyleTarget();BuildBoxes 与 QueryCursor 在无样式目标时
不再上报/响应色块、样式、调整、线宽、透明度等控件;
- Paint 的“无网格”分支显式清空 m_legendHits / m_cursorLabelRects / m_cursorSpanRect /
m_freeMarkerHits / m_panelSlots / m_panelOrder(关闭整个分组后不再残留边界框);
- 浮动面板之上的滚动条 / 回到最上方 / 内联输入框改为按可见性上报几何。
验证(离屏探针,SW_HIDE + 合成消息,不占用鼠标键盘屏幕)
.preflight/p21.exe 9/9 .preflight/p22.exe 14/14 .preflight/p23.exe 7/7
.preflight/p20 系列(9/11/5)全部回归通过
make release / make debug 零 warning;Release 813,568 B
This commit is contained in:
1 parent
7a6fcd68e2
commit
8de8a8fb85
14 files changed
+934
-141
No files matched your search
@@ -9186,3 +9186,127 @@ make release / make debug 零 warning
|
||||
取像素做 A/B 时要**避开圆角 8px**,否则会误报 7 个像素。
|
||||
- ⚠️ `git diff --numstat` 出现整文件级别的增删时要先怀疑行尾/BOM 被 PowerShell 改掉;
|
||||
本轮所有写回都用 `[System.IO.File]::WriteAllText(... UTF8Encoding($false))`。
|
||||
|
||||
---
|
||||
|
||||
## 2026-11-02 第二十一轮(本机):预览曲线按面板高亮 + 统计数字"卡在统计中" + 中心轴面板改表格 + 默认主题 Light + 标签页 DPI + 布局边界幽灵元素
|
||||
|
||||
> 六件事,用户逐条报告。全部用离屏探针验证(`.preflight/p21`、`p22`、`p23`,`SW_HIDE` + 合成消息,
|
||||
> 不占用鼠标/键盘/屏幕);`p20`(第二十轮的探针)回归全绿。
|
||||
|
||||
### 1. ⭐⭐ 预览曲线悬停高亮:只认「鼠标所在的那个面板」
|
||||
|
||||
现象:只开「弱峰调整 + 中心轴边沿计数」时,悬停信号条目栏**毫无反应**;三个实验性功能全开时,
|
||||
悬停**任何一个**面板都只看到「均值滤波」那条曲线被高亮。
|
||||
|
||||
根因(`PaintLaneDerivedOverlays`):三条曲线的绘制分支里**只有 MEAN 分支传了 `highlight`**,
|
||||
CENTER 分支压根没传(默认 false);而悬停状态只记录了 `(lane, ref)`,**没有记录面板种类** ——
|
||||
同一条信号在三个面板里各有一行,无法区分"该高亮哪一条"。
|
||||
|
||||
修法:
|
||||
* 新增 `m_meanRowHoverKind`(`EdgePanelKind`),`OnMouseMove` 与 `(lane, ref)` 一起维护;
|
||||
* 每条曲线的高亮条件 = `悬停行 == 本行 && 悬停面板种类 == 本曲线的面板种类`;
|
||||
* 条目栏的强调色叠加同样加上 `m_meanRowHoverKind == kind`(否则悬停一个面板会把其它面板的
|
||||
同名行一起点亮);
|
||||
* 面板缓存键(`PanelGlobalKey`)混入悬停种类(它直接改变面板像素)。
|
||||
|
||||
### 2. ⭐⭐ 统计数字"松手后永远停在统计中…"
|
||||
|
||||
现象:按住横向光标快速拖动、并在**鼠标继续快速移动时**松开左键 ⇒ 面板一直显示"统计中…",
|
||||
直到鼠标移到面板上或做别的操作才更新(中心轴面板拖参数滑块后松手同理)。
|
||||
|
||||
根因:交互期间(拖拽 / 鼠标 140ms 内移动过)面板缓存键被**冻结**(`InputIsInteractive()`),
|
||||
面板直接贴上一帧像素 —— 这是第十九轮为"拖动跟手"刻意做的。但**冻结结束后没有任何重绘请求**:
|
||||
鼠标停了就没有 `WM_MOUSEMOVE`,统计也早已完成(不会再 `RequestEdgeScanFrame`)⇒
|
||||
最后一次绘制仍是冻结帧,界面上永远停在旧文字。
|
||||
|
||||
修法(补一帧):
|
||||
* `PanelGlobalKey()` 里记录 `m_panelKeysFrozen = interactivePanelKey`(`mutable`);
|
||||
* 新增公开查询 `PlotView::PanelRefreshPending()`;
|
||||
* `Application::Render` 末尾:`PanelRefreshPending()` 为真时也保持 `kScrollTimerId` 定时器,
|
||||
`WM_TIMER` 走既有的"只失效绘图区"分支 ⇒ 冻结窗口结束后的下一帧按最新数字重画面板,
|
||||
之后 `m_panelKeysFrozen` 变假、定时器自动停。
|
||||
|
||||
### 3. 「中心轴边沿计数」面板改为**表格**
|
||||
|
||||
表头固定不滚动:**信号名 | 上升沿计数 | 下降沿计数**;下面每条可见信号一行,行底色 = 该信号的
|
||||
配色(未勾选的行用普通底色 + 空复选框,表示"尚未参与统计"),三列与表头严格对齐;内容超高时
|
||||
右侧出现滚动条;单击行(非复选框)展开该信号自己的两行参数滑块(均值点数 / 迭代次数)。
|
||||
|
||||
实现要点:
|
||||
* `EdgePanelLayout` 新增 `tableHeader` + `tableColumns[3]`(`TableColumn{left,width}`);
|
||||
* `EdgePanelLayoutFor` 新增 `centerTable` 分支(CENTER 不再走 `listStyle`);
|
||||
* 新增 `EdgeCenterTableHeader(col)` / `EdgeCountCellText(value, complete)`(单元格只写数字,
|
||||
未算完时追加 `…`);
|
||||
* `Lane::EnsureEdgeCenterItem` 新建条目时 **`collapsed = true`**(表格行默认收起参数滑块);
|
||||
* `PanelSlotKey` 的 CENTER 分支**不能再按 `rowStats` 门控**(表格没有 rowStats 了)——
|
||||
改为"凡 `FindEdgeCenterItem != nullptr` 的行都把 (rising, falling, complete) 混进键",
|
||||
否则数字变化不会让键变化、面板永远停在"统计中…";
|
||||
* 表格复用原有的 `rowHeaders/rowChecks/rowTriangles/rowNameRects/rowLevel*/rowIter*`,
|
||||
因此**交互代码不用改**(勾选切换、整行展开收起、滑块拖动、滚动条 / 滚轮全部沿用)。
|
||||
|
||||
### 4. 默认主题改为 **Light**
|
||||
|
||||
`Application::m_themeKind = ThemeKind::LIGHT`;`ThemeFor()` 的 `default`、`ThemeName()` 的
|
||||
`default`、`CurrentTheme()` / `SetCurrentTheme(nullptr)` 的兜底也一并改为 `kLight`
|
||||
(避免"宿主未设置时回落到 Solarised Light"的不一致)。
|
||||
|
||||
### 5. 标签页文本在 DPI 切换后被省略
|
||||
|
||||
现象:主屏 125% 打开,拖到 100% 副屏后「视图 1」变成「视图…」,双击改名再取消就恢复正常。
|
||||
|
||||
根因:标签宽度恰好等于 `2*pad + 文本 + gap + close`(**没有任何余量**),而
|
||||
`TabItemWidget` 在 `Configure({fonts, theme, scale})` 时**缓存了当时的 scale**,绘制时用它
|
||||
从 `closeRect` 反推"可用文本宽度"。`TabBar::SetScale` 只改自己的 `m_scale`、**不重建控件树**
|
||||
⇒ DPI 切换后控件仍用旧缩放扣边距(`14*1.25` vs `14*1.0`、`6*1.25` vs `6*1.0`)⇒
|
||||
可用宽度比实测文本窄约 4.5px ⇒ `UiEllipsize` 吃掉末字。双击改名会走到重建路径,于是"又好了"。
|
||||
|
||||
修法(两层):
|
||||
* `TabBar::SetScale` 在缩放**真的变化**时 `RebuildWidgets()`(与 `Toolbar::SetScale` 的
|
||||
`m_treeDirty = true` 同一思路);
|
||||
* 更根本的一层:**文本可用矩形改由 `TabBar::ArrangeWidgets` 统一下发**
|
||||
(`TabItemWidget::SetState(..., textRect)`),绘制侧不再自己反推 —— 几何单一来源,
|
||||
以后不会再被"缩放/取整"这类差异咬到。
|
||||
|
||||
### 6. 布局边界里的"幽灵元素"
|
||||
|
||||
* ⭐ **样式区控件在未选中信号时也上报几何、也接受光标**:`LayoutStyleControls()` 无条件算出
|
||||
色块/样式/调整/线宽/透明度等矩形,而绘制在"没有目标"时只画占位文字。
|
||||
`OnLButtonDown` 与 `OnMouseMove` 早已按 `StyleOf(SelectedRef())` 门控,
|
||||
但 **`BuildBoxes` 与 `QueryCursor` 没有** ⇒ 打开「显示布局边界」能看到整排控件框,
|
||||
鼠标掠过「系数/偏移 | 镜像 | 绝对值」还会变手型。
|
||||
修法:新增 `SignalPanel::HasStyleTarget()`(与绘制/命中同一判据),
|
||||
`BuildBoxes` 只在有目标时登记这些控件(「目标」行本体总是登记),
|
||||
`QueryCursor` 同样只在有目标时给手型。
|
||||
* ⭐ **关闭整个分组后残留大量边界框**:`Paint` 在 `m_lanes.empty()` 时直接 return,
|
||||
`PaintLaneLegend / PaintCursor / PaintFreeMarker` 都不跑 ⇒
|
||||
`m_legendHits / m_cursorLabelRects / m_cursorSpanRect / m_freeMarkerHits / m_panelSlots`
|
||||
里的**旧矩形**一直留着(布局边界继续画、命中测试也会命中已不存在的元素)。
|
||||
修法:空分支里显式清空这些几何并清 `m_panelOrder`。
|
||||
* 浮动面板之上的叠加层(滚动条 / 回到最上方 / 内联输入框)以前**无条件上报**矩形
|
||||
(即使没画)⇒ 现在按 `m_scrollBarVisible` / `BackToTopVisible()` / `m_editTarget != NONE`
|
||||
门控。
|
||||
|
||||
### 7. 验证
|
||||
|
||||
```
|
||||
p21.exe 9/9 无幽灵样式区框、空样式区无手型;选中信号后框与手型恢复;
|
||||
关闭分组后 lanes=0、legendHits=0、绘图区内只剩 4 个真实元素框
|
||||
p22.exe 14/14 默认主题 = Light;表格表头存在/列不重叠/内容在表头之下;
|
||||
行底色 = 信号配色;交互帧冻结 ⇒ 空闲窗口后自动解冻(宿主补帧);
|
||||
悬停 CENTER 行高亮中心轴曲线且种类记为 CENTER;悬停 PEAK 面板记为 PEAK;
|
||||
**DPI 往返(96→120→96)后标签文本墨迹宽度 38 vs 实测 40(A/B 去掉重建 ⇒ 25)**
|
||||
p23.exe 7/7 60 信号:表格限高/可滚动/像素缓存命中;勾选框切换统计;整行展开收起;
|
||||
展开后出现滑块轨道;内容滚动生效
|
||||
p20 / p20c / p20d 全绿(第二十轮的面板限高 / 弱峰列表 / 统计推进 / 组名折起)
|
||||
make release / make debug 零 warning;Release 813,568 B(< 1MB 红线)
|
||||
```
|
||||
|
||||
### 8. 踩坑
|
||||
|
||||
* ⚠️ 用 `#define private public` 的离屏探针里,"读像素来判断文字是否被省略"必须**与同一 DPI
|
||||
下实测的文本宽度比较**:跨 DPI 比较字号本来就不同(本机主屏 125%,进程启动即 120 DPI)。
|
||||
* ⚠️ 探针里两个面板默认都叠在右上角 ⇒ `TopPanelAtPoint` 只返回最上层那个,
|
||||
要验证"某个面板的悬停"必须先把另一块的 `panel.x/y` 挪开。
|
||||
* ⚠️ 改完 `TabBar` 的 `SetState` 签名要同步 `ArrangeWidgets` 唯一调用点;
|
||||
探针 A/B 时**先确认 `make` 真的重编了**(过滤输出只看 error 会漏掉"没重编")。
|
||||
Reference in new issue
Block a user