自由标记:面板表头/吸顶/行选中与悬停联动 + 原位显示 + 探测容差与阶跃吸附
- 面板:每个展开分组下方新增一行列表头(标记值/枚举文本/增量/时间点/时间间隔), 与数据行共用列边界;列宽同时容纳列标题;表头行计入内容总高与面板高度; 全部无枚举文本时仍整列缺省 - 吸顶:分组栏与表头各自按 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:
1 parent
8f735d51be
commit
79eebc281e
10 files changed
+618
-116
No files matched your search
@@ -991,6 +991,16 @@ namespace jdi
|
||||
*/
|
||||
bool ToggleLaneFreeMarkerGroup(int laneIndex, const SignalRef& ref);
|
||||
|
||||
/**
|
||||
* @brief 选中「自由标记」面板里的某个条目(`-1` = 取消选中)。
|
||||
*
|
||||
* 选中的行在面板里高亮;它与网格内的固定点一一对应。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @param [IN] itemIndex `Lane::freeMarkerItems` 下标(越界会被夹成“取消选中”)。
|
||||
* @return 选中状态发生变化返回 true。
|
||||
*/
|
||||
bool SelectLaneFreeMarker(int laneIndex, int itemIndex);
|
||||
|
||||
/**
|
||||
* @brief 切换某个实验性功能浮动面板的**折起**状态(只显示标题栏)。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
@@ -1716,9 +1726,25 @@ namespace jdi
|
||||
{
|
||||
SignalRef ref;
|
||||
gd::RectF header; /**< 分组栏托底矩形。 */
|
||||
/**
|
||||
* @brief 分组栏下方的一行**列表头**(取值 / 枚举文本 / 增量 / 时间点 / 时间间隔)。
|
||||
*
|
||||
* 与条目列共用 `markerColumns` 的列边界 ⇒ 表头与数据严格对齐。
|
||||
* 分组被收起(或还没登记)时为空矩形。
|
||||
* ⚠️ 滚动时它可能与分组栏一起**悬浮**在内容区顶部(吸顶),
|
||||
* 因此它的 Y 不一定是“分组栏 Y + 行高”。
|
||||
*/
|
||||
gd::RectF tableHeader;
|
||||
gd::RectF triangle; /**< 展开/收起三角的命中矩形。 */
|
||||
gd::RectF close; /**< 右侧✕的命中矩形。 */
|
||||
bool collapsed = false;
|
||||
/**
|
||||
* @brief 该分组栏是否处于**吸顶**(滚动时被钉在内容区顶部)。
|
||||
*
|
||||
* 吸顶时分组栏与表头会盖住正在向上滚的条目 ⇒ 绘制侧必须把它们画在**条目之后**
|
||||
* (否则会被条目覆盖),交互侧也已把这些被盖住的条目从 `markerRows` 里剔除。
|
||||
*/
|
||||
bool pinned = false;
|
||||
};
|
||||
/** 「自由标记」:信号分组栏(顺序与面板显示顺序一致)。 */
|
||||
std::vector<MarkerGroup> markerGroups;
|
||||
@@ -1788,9 +1814,13 @@ namespace jdi
|
||||
* 该网格内所有可见信号中**离鼠标最近**的那一个。
|
||||
*
|
||||
* 两种模式由 `Lane::freeMarkerCursor` 决定:
|
||||
* * **默认(非光标模式)**:只有鼠标**贴近某条信号曲线**(或该信号命中「自动点线」
|
||||
* 稀疏判定、且鼠标靠近某个数据点)时才有结果(`valid == true`),也**不画**纵向光标;
|
||||
* * **光标模式**:网格内始终 `valid == true`(画纵向光标),能取到数据点时再标注取值。
|
||||
* * **默认(非光标模式)**:只有鼠标**贴近某条信号曲线**时才有结果(`valid == true`),
|
||||
* 也**不画**纵向光标。⚠️ 判据 = 鼠标到**画出来的折线**的垂直距离 ≤
|
||||
* `kSignalHitTolerance`(与「常规状态下触发信号曲线高亮」**完全同一范围**;
|
||||
* 因此阶跃的竖直跳变段也能探测到)。判定通过后,标注时刻会被吸附到最近的**采样时刻**
|
||||
* (固定点必须落在真实数据点上);
|
||||
* * **光标模式**:网格内始终 `valid == true`(画纵向光标),能取到数据点时再标注取值
|
||||
* (此时只有命中「自动点线」稀疏判据的信号才吸附)。
|
||||
*/
|
||||
struct FreeMarkerProbe
|
||||
{
|
||||
@@ -2665,6 +2695,16 @@ namespace jdi
|
||||
/** 最近一次解析出的「自由标记」跟随数据点(绘制与命中共用)。 */
|
||||
FreeMarkerProbe m_freeMarker;
|
||||
|
||||
/**
|
||||
* @brief 上一帧鼠标悬停在「自由标记」面板的哪个**条目行**上(-1 = 没有)。
|
||||
*
|
||||
* 与 `m_freeMarkerPanelHoverLane/Item`(只表示 ✕ 的悬停)**分开**:
|
||||
* 悬停在整行上时要把网格内对应的固定点整体高亮(取值胶囊 + 数据点),
|
||||
* 但**不能**因此把该行的 ✕ 画成 danger 色(那是“准备删除”的语义)。
|
||||
*/
|
||||
int m_freeMarkerRowHoverLane = -1;
|
||||
std::size_t m_freeMarkerRowHoverItem = static_cast<std::size_t>(-1);
|
||||
|
||||
/**
|
||||
* @brief 上一次绘制时登记的固定点 ✕ 命中矩形。
|
||||
*
|
||||
|
||||
Reference in new issue
Block a user