自由标记:面板表头/吸顶/行选中与悬停联动 + 原位显示 + 探测容差与阶跃吸附

- 面板:每个展开分组下方新增一行列表头(标记值/枚举文本/增量/时间点/时间间隔),
  与数据行共用列边界;列宽同时容纳列标题;表头行计入内容总高与面板高度;
  全部无枚举文本时仍整列缺省
- 吸顶:分组栏与表头各自按 max(自然, min(吸顶, 组下边界-自身高)) 钉住,
  组末尾按"表头先走 -> 条目 -> 分组栏最后离场";绘制顺序改为条目->表头->吸顶分组栏,
  被盖住的条目不绘制也不可命中
- 行交互:Lane::freeMarkerSelected(单击选中/再点取消)+ 独立的整行悬停状态
  (整行悬停不会把该行 ✕ 变成 danger 色);悬停时网格内对应固定点整体高亮
  (数据点圆环 + 胶囊强制不透明 + accent 描边,仅视界内)
- 固定点恢复原位显示(删除纵向避让,允许遮挡,回到初版方案)
- 探测判据重写:鼠标到画出来的折线的垂直距离 <= kSignalHitTolerance(与曲线高亮同源),
  命中后吸附到最近采样时刻 => 修复阶跃竖直跳变线无法探测/固定的问题;
  删除已无用的 kFreeMarkerHoverTolerance
- 修复滚动时条目文字串到面板标题栏(GDI 文本不认 GDI+ 裁剪,改用 UiTextClipped)
- 顺带清理过期注释(四列->五列、折起指示器已无横线、探测判据说明),
  RemoveFreeMarker 改为复用 RemoveFreeMarkerAt(选中下标校正只有一处)
- 验证:新增离屏 .preflight/mark4check 38/38(三组 A/B 均如实失败);
  回归 markcheck 61/61、fixcheck 37/37、round3check 31/31、round4check 34/34、
  round5check 5/5、editcheck 20/20、convcheck 18/18;make release/debug 零警告
This commit is contained in:
DeepSeek V4.1 Flash committed 2026-10-22 21:04:03 +08:00
1 parent 8f735d51be
commit 79eebc281e
10 files changed
+618 -116

No files matched your search

+24 -9
View File
@@ -337,6 +337,23 @@ namespace jdi
/** 「自由标记」面板里每个固定点行的高度(五列 + 行尾 ✕)。 */
inline const float kFreeMarkerItemRowHeight = 20.0f;
/**
* @brief 「自由标记」面板里每组分栏下方那一行**列表头**的高度(逻辑像素)。
*
* 表头 = 取值 / (枚举文本)/ 增量 / 时间点 / 时间间隔 五个列标题,
* 与数据行共用同一组列边界 ⇒ 表头与数据严格对齐。
* ⚠️ 滚动时分组栏与表头会**各自吸顶**(见 `EdgePanelLayoutFor` 的 `MarkerGroup`),
* 因此表头高度必须参与内容总高度与吸顶量计算。
*/
inline const float kFreeMarkerHeaderRowHeight = 18.0f;
/**
* @brief 「自由标记」面板表头的五个列标题(顺序与 `markerColumns` 一致:
* ① 取值 ② 枚举 ③ 增量 ④ 时刻 ⑤ 间隔)。
*/
inline const wchar_t* const kFreeMarkerColumnLabels[5] = {
L"标记值", L"枚举文本", L"增量", L"时间点", L"时间间隔"};
/** 「自由标记」面板与行尾 ✕ 按钮的边长(网格内取值胶囊后的 ✕ 另按胶囊高度取正方形)。 */
inline const float kFreeMarkerCloseSize = 13.0f;
@@ -381,18 +398,16 @@ namespace jdi
/**
* @brief 所有实验性功能浮动面板标题栏左侧「展开/折起」指示器的宽度。
*
* 指示器 = 三角(朝右 = 已折起、朝下 = 已展开)+ 三角后方的一条横线;
* 点击它切换面板的折起状态。`GX` 编号徽标向右让出这块宽度。
* 指示器 = 与信号列表组名**同款**的折叠三角(朝右 = 已折起、朝下 = 已展开),
* 单击它切换面板的折起状态。`GX` 编号徽标向右让出这块宽度。
* ⚠️ 2026-10-21 起**不再**画三角后方那条横线(用户要求与组名标记完全一致)。
*/
inline const float kEdgePanelDisclosureWidth = 20.0f;
/**
* @brief 非光标模式下判定"鼠标在信号曲线上"的纵向容差(逻辑像素)。
*
* 默认(不启用光标模式)时只有鼠标贴近曲线才显示取值预览;这个容差决定"贴近"的量级。
* 取得太小会很难命中细线,太大则会在空白处误判成"有信号"从而吃掉平移操作。
*/
inline const float kFreeMarkerHoverTolerance = 8.0f;
// ⚠️ 这里曾有 `kFreeMarkerHoverTolerance = 8`(旧的非光标模式“纵向贴近”容差)。
// 用户 2026-10-22 要求把自由标记的触发范围与「常规状态下触发信号曲线高亮」**统一**,
// 因此现在直接复用 `kSignalHitTolerance`(6 逻辑像素)并改判“到折线的垂直距离”
//(见 `PlotView::ProbeFreeMarker`)。旧的 8 像素常量已删除,不要再加回来。
/** 固定点取值胶囊与 ✕ 之间的间距。 */
inline const float kFreeMarkerCloseGap = 3.0f;