修复组名编辑态点击穿透;浮动面板 GX 徽标悬停提示 + 点击滚动联动;最小网格高度提升到 81 逻辑像素
1) 组名/信号名处于编辑态时,在编辑框内双击、快速连点或框选编辑文本会让分组展开/收起。
两处根因:
- 行高大于输入框高度(上下各留 3 逻辑像素),起点落在内边距上时 OnEditMouseDown 返回
false,宿主把按下交给 OnLButtonDown,命中分组行的 BODY 分支 ⇒ 折叠状态被切换;
- 窗口带 CS_DBLCLKS,快速第二次按下被合成为 WM_LBUTTONDBLCLK,而 OnDoubleClick 没有
编辑态保护,直接进入分组行双击逻辑 ⇒ 再次折叠 / 再次改名。
修法:新增 NameEditAbsorbRect(输入框横向范围 × 整行高度)作为编辑态的“文本吸收区”:
OnLButtonDown 命中即按文本操作处理(落点夹回输入框再算插入符),OnDoubleClick 命中即
直接返回。横向仍限定在名称区域,同一行的复选框 / 「N 项」/ GX 徽标 / ✕ 继续可点。
2) 所有实验性功能浮动面板标题栏左侧的 GX 徽标:
- EdgePanelLayout 新增 badge 矩形,成为绘制 / 悬停 / 手型光标 / 点击联动的唯一几何来源
(命中顺序 close → badge → title,徽标在标题栏内部,放到 title 之后会被判成拖面板);
- 悬停时徽标高亮 + 气泡提示(“G12 · 点击滚动到该网格” / “G12 · 已在视界内”),气泡在
面板像素图层存进缓存之后绘制,避免被烘进位图后在鼠标移开后残留;
- 点击调用 ScrollLaneIntoView:目标网格不可见时启动与“点选信号联动滚动”同源的平滑动画,
已完整可见时不做任何改动。
3) 网格被压缩时的最小高度由 54 提升到 81 逻辑像素(1.5 倍)。同时修掉 m_minLaneHeight 被
二次乘 m_scale 的隐患:Layout 里不再预先乘缩放,滚动条判定改用 laneCount × 81 × scale,
与实际网格高度使用同一换算(125% 缩放下 128 个网格实测 101.25px = 81×1.25)。
验证(全部离屏:SW_HIDE 窗口 + 只注入合成消息 + BELOW_NORMAL,不占用鼠标键盘屏幕):
- 新增 .preflight/round3check(真实 TestData/MF4-Record.MF4,128 网格)31/31;
A/B 临时禁用双击保护 ⇒ 1 项如实失败(证明断言有判别力);
- 回归:.preflight/editcheck 20/20、.preflight/check 137/137;
- make release / make debug 零警告。
This commit is contained in:
1 parent
1e50494c41
commit
be76f523f3
8 files changed
+307
-11
No files matched your search
@@ -878,6 +878,13 @@ namespace jdi
|
||||
// ✕ 按钮:与面板/标签栏的其它 ✕ 一致,用手型光标作为可点击提示。
|
||||
return LoadCursorW(nullptr, IDC_HAND);
|
||||
}
|
||||
// 「GX」编号徽标:悬停给出提示 + 手型光标;点击把该网格滚动到视界内。
|
||||
// ⚠️ 必须排在标题栏之前(徽标位于标题栏矩形内部,否则会被判成“可拖拽”)。
|
||||
if (layout.badge.Width > 0.0f &&
|
||||
UiPointInRect(layout.badge, static_cast<float>(x), static_cast<float>(y)))
|
||||
{
|
||||
return LoadCursorW(nullptr, IDC_HAND);
|
||||
}
|
||||
if (UiPointInRect(layout.title, static_cast<float>(x), static_cast<float>(y)))
|
||||
{
|
||||
return LoadCursorW(nullptr, IDC_SIZEALL);
|
||||
@@ -1383,6 +1390,30 @@ namespace jdi
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// 浮动面板标题栏左侧的「GX」编号徽标:悬停高亮 + 提示气泡(用户 2026-10-19 要求)。
|
||||
// 徽标在面板像素图层里,因此悬停态必须由这里单独记录并触发重绘
|
||||
//(面板缓存键在鼠标位于面板内时会混入坐标,所以重绘即可看到高亮)。
|
||||
int hoverPanelBadgeLane = -1;
|
||||
int hoverPanelBadgeKind = -1;
|
||||
if (overEdgePanel && panelLane >= 0)
|
||||
{
|
||||
const EdgePanelLayout badgeLayout =
|
||||
EdgePanelLayoutFor(panelLane, static_cast<EdgePanelKind>(hoverPanelKind));
|
||||
if (badgeLayout.badge.Width > 0.0f &&
|
||||
UiPointInRect(badgeLayout.badge, fx, static_cast<float>(y)))
|
||||
{
|
||||
hoverPanelBadgeLane = panelLane;
|
||||
hoverPanelBadgeKind = hoverPanelKind;
|
||||
}
|
||||
}
|
||||
if (hoverPanelBadgeLane != m_hoverPanelBadgeLane ||
|
||||
hoverPanelBadgeKind != m_hoverPanelBadgeKind)
|
||||
{
|
||||
m_hoverPanelBadgeLane = hoverPanelBadgeLane;
|
||||
m_hoverPanelBadgeKind = hoverPanelBadgeKind;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// 悬停网格:**只有**鼠标悬停在实验性功能浮动面板上时才高亮该面板所属网格。
|
||||
// ⚠️ 用户 2026-10-15 明确要求:鼠标在网格里移动**不再触发**网格变色高亮;
|
||||
// 改为在信号列表 / 样式区「目标」行悬停到某条已绘制信号时联动高亮
|
||||
@@ -1663,6 +1694,19 @@ namespace jdi
|
||||
return true;
|
||||
}
|
||||
|
||||
// 「GX」编号徽标:点击把该网格滚动到视界内(用户 2026-10-19 要求)。
|
||||
// ⚠️ 必须排在标题栏之前:徽标位于标题栏矩形内部,否则会变成“拖动面板”。
|
||||
// `ScrollLaneIntoView` 自带“已经完整可见 ⇒ 什么都不做”,且是平滑动画。
|
||||
if (layout.badge.Width > 0.0f && UiPointInRect(layout.badge, fx, fy))
|
||||
{
|
||||
m_dragMode = PlotDragMode::NONE;
|
||||
if (ScrollLaneIntoView(index))
|
||||
{
|
||||
SetHint(L"正在滚动到 G" + std::to_wstring(index + 1) + L" 网格…");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 「中心轴边沿计数」/「均值滤波」/「弱峰调整」面板:逐信号条目
|
||||
// (前两者是「名称 + 复选框 + 两个参数输入框」,弱峰调整是「名称 + 复选框 + 两行滑块」)。
|
||||
if ((kind == EdgePanelKind::MEAN || kind == EdgePanelKind::CENTER ||
|
||||
@@ -2297,6 +2341,13 @@ namespace jdi
|
||||
m_hoverBadge = -1;
|
||||
changed = true;
|
||||
}
|
||||
if (m_hoverPanelBadgeLane != -1 || m_hoverPanelBadgeKind != -1)
|
||||
{
|
||||
// 浮动面板的「GX」徽标悬停提示必须随鼠标离开清除(否则提示气泡残留)。
|
||||
m_hoverPanelBadgeLane = -1;
|
||||
m_hoverPanelBadgeKind = -1;
|
||||
changed = true;
|
||||
}
|
||||
if (m_hoverSignal.IsValid())
|
||||
{
|
||||
m_hoverSignal = SignalRef();
|
||||
|
||||
Reference in new issue
Block a user