修复「信号列表滚动把组名/信号名画到筛选框上」+「边沿统计面板在不移动鼠标时显示冻结」
一、列表滚动越界绘制(SignalPanel + PaintUtil) 根因:UiText 走 GDI DrawTextW,而 GDI 文本不遵循 GDI+ 的 Graphics::SetClip。 列表虽然用 g.SetClip(m_listRect) 裁剪,但被滚出视口的「部分可见」行(分组行、信号名) 仍会把文字画到列表上方的筛选框区域(用户报告 MF4 多信号场景);UiFillRect 对大面积的 不透明矩形会改走 GDI FillRect,同样越界。 修法: * PaintUtil 新增 UiTextClipped(g, text, font, rect, argb, align, clipRect) ——在同一个 HDC 上 SaveDC + IntersectClipRect + RestoreDC;UiText 重构为转发 clip = nullptr,行为与旧实现完全一致。 * SignalPanel 新增 PaintRowText()(裁剪到 m_listRect)与 FillRowRect()(夹取到 m_listRect),分组行与信号行的全部文本、行底色/选中底色都改走它们。 二、两个边沿计数浮动面板「鼠标不动就不刷新」(PlotView::PanelSlotKey) 根因:浮动面板使用像素图层缓存(m_panelDc + m_panelSlots + PanelSlotKey),而界面上显示的 「上升沿 / 下降沿」是分帧推进出来的中间结果,PanelSlotKey 里没有这些数字 ⇒ 统计推进不会 让键变化 ⇒ 面板一直贴旧像素 ⇒ 显示停在「统计中…」或某个中间值,只有移动鼠标(改变面板 层序 / 悬停 / 鼠标坐标等其它键)才会重绘并显示早已算完的正确结果;扫描推进本身并没有停。 修法:PanelSlotKey 内按面板实际显示的条目回调 EdgeCountsFor(COUNT 面板)/ EdgeCenterCountsFor(CENTER 面板),把 (rising, falling, complete) 一并 mix 进键。 三、验证(离屏 .preflight/check:SW_HIDE 窗口、不注入真实鼠标键盘、进程/线程 BELOW_NORMAL) 39/39 通过(连跑两次稳定): * [A] 40 信号同一网格、滚轮下滚:列表上边界以上区域逐像素 0 变化,列表内部仍有变化 (证明是裁剪而不是整块不画); * [B] 3 信号 × 300 万采样、两种统计同时开启:面板像素图层缓存键在扫描期间持续变化, 且不注入任何鼠标消息即可 complete; * [C] 真实 TestData/MF4-Record.MF4(124 信号 / 3 条时间轴):同样 0 像素变化。 A/B:git stash 回退本轮修复后重跑 ⇒ [A] 1571 像素被污染、[B] 两个面板的缓存键均不推进, 如实失败。 make release 零警告(用户正在运行 Target.exe,链接用临时 -o 名字验证通过)。 四、规则同步 Documents/agent_mem.md 新增 §9.28、§11.2 第 53/54 条硬约束与变更日志。
This commit is contained in:
1 parent
6eedbe3c5d
commit
3bca3b1201
6 files changed
+304
-62
No files matched your search
@@ -439,6 +439,35 @@ namespace jdi
|
||||
*/
|
||||
void PaintSignalRow(gd::Graphics& g, int row);
|
||||
|
||||
/**
|
||||
* @brief 在列表区内绘制行内文本(**显式裁剪到列表矩形**)。
|
||||
*
|
||||
* ⚠️ `UiText` 走 GDI `DrawTextW`,**不遵循 GDI+ 的 `SetClip`**:列表需要滚动时,
|
||||
* 被滚出视口的行(顶部部分可见的两三行)会把组名/信号名画到上方筛选框上。
|
||||
* 因此行内文本一律经本函数绘制(见 `UiTextClipped`)。
|
||||
*
|
||||
* @param [IN,OUT] g 绘图上下文。
|
||||
* @param [IN] text 文本内容。
|
||||
* @param [IN] font 字体句柄。
|
||||
* @param [IN] rect 文本布局矩形。
|
||||
* @param [IN] argb 文本颜色。
|
||||
* @param [IN] align 水平对齐方式。
|
||||
*/
|
||||
void PaintRowText(gd::Graphics& g, const std::wstring& text, HFONT font, const gd::RectF& rect,
|
||||
std::uint32_t argb, TextAlign align);
|
||||
|
||||
/**
|
||||
* @brief 在列表区内填充行内矩形(**夹取到列表矩形**)。
|
||||
*
|
||||
* ⚠️ `UiFillRect` 对大面积的**不透明**矩形会改走 GDI `FillRect`(同样不受 GDI+ 裁剪约束),
|
||||
* 高 DPI 下行的面积足以超过该阈值 ⇒ 行背景/选中底色必须先把矩形夹到列表矩形。
|
||||
*
|
||||
* @param [IN,OUT] g 绘图上下文。
|
||||
* @param [IN] rect 目标矩形。
|
||||
* @param [IN] argb 填充颜色。
|
||||
*/
|
||||
void FillRowRect(gd::Graphics& g, const gd::RectF& rect, std::uint32_t argb);
|
||||
|
||||
/**
|
||||
* @brief 绘制样式编辑区(固定四行:颜色 / 线宽 / 样式 / 透明度)。
|
||||
* @param [IN,OUT] g 绘图上下文。
|
||||
|
||||
Reference in new issue
Block a user