修复拆分网格误继承实验性功能 / 阶跃线宽 / 面板拖拽残影 / 自由标记卡顿与交互

- 拆分网格:实验性功能只由原网格的首个信号继承(LaneCarry::owner);
  SplitLane 只让第一份继承;新增 PruneLaneSignalItems 按 lane.signals 过滤四类
  逐信号条目(修复"新网格出现别人的固定点、面板里却查不到")
- 阶跃信号:包络带横向膨胀半径 ceil -> floor(1px 线宽不再把竖直沿撑成 3px)
- 浮动面板:面板位置移出 PanelGlobalKey(拖动单个面板不再重画全部面板),
  新增 vacatedRects 让"上一帧被移动/缩小/关闭的面板腾出的区域"也强制重画
- 自由标记:新增 FreeMarkerContents 内容缓存(键不含视界),大量固定点时拖光标/平移不再逐帧采样;
  透明度滑块与光标模式解耦(始终显示);悬停胶囊恢复不透明(瞄着被遮住的数据点时除外);
  胶囊与面板五列按实测文本撑开,不再省略
- 面板交互:折起指示器与信号列表组名同款三角;GX 徽标/标题栏悬停不改光标、移除徽标气泡;
  标题栏双击滚动到该网格(单击不触发,双击不再折起)
- 验证:新增离屏 .preflight/fixcheck 37/37(三处 A/B 均能如实失败);
  回归 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-21 17:21:09 +08:00
1 parent 3400ac7c29
commit 8f735d51be
8 files changed
+654 -198

No files matched your search

+43 -11
View File
@@ -1836,6 +1836,46 @@ namespace jdi
gd::RectF close;
};
/**
* @brief 「自由标记」某个固定点的**内容**(取值与各种文本)。
*
* 这些值与**视界无关**(只取决于采样数据与信号样式),因此单独缓存:
* 平移视界、拖动时间光标时不需要重新采样/重新格式化。
* 面板的五列与网格内的取值胶囊共用这一份内容。
*/
struct FreeMarkerContentEntry
{
std::size_t itemIndex = 0; /**< `Lane::freeMarkerItems` 下标。 */
bool valid = false; /**< 取值是否有效(无效时全部文本为 `N/A`)。 */
double value = 0.0; /**< 绘制用取值(用于算胶囊/圆点的纵向位置)。 */
std::wstring capsuleText; /**< 网格内取值胶囊的文本(`值(±增量) = 枚举`)。 */
std::wstring valueText; /**< 面板:取值列。 */
std::wstring enumText; /**< 面板:枚举列(可能是空串)。 */
std::wstring deltaText; /**< 面板:增量列。 */
std::wstring timeText; /**< 面板:时刻列。 */
std::wstring deltaTimeText; /**< 面板:间隔(Δt)列。 */
std::uint32_t color = 0; /**< 信号色(信号样式里的颜色,已乘不透明度)。 */
};
/** 一个网格的「自由标记」内容缓存(`key` 只含与视界无关的输入)。 */
struct FreeMarkerContentCache
{
std::uint64_t key = 0;
std::vector<FreeMarkerContentEntry> entries;
};
/**
* @brief 取某个网格的「自由标记」内容列表(必要时重建,**与视界无关**)。
*
* ⚠️ 性能硬约束:大量固定点时,逐帧重新 `SampleDisplayedSignalAt` + 拼字符串
* 是“拖动全局光标/移动视界变卡”的主因。内容只依赖数据与样式,因此缓存起来;
* 命中缓存时每帧只做几何与绘制。
*/
const std::vector<FreeMarkerContentEntry>& FreeMarkerContents(int laneIndex) const;
/** 按网格下标的「自由标记」内容缓存(`mutable`:只在绘制时按需重建)。 */
mutable std::vector<FreeMarkerContentCache> m_freeMarkerContent;
/**
* @brief 计算某个网格里「第 index 个固定点」的标注几何(绘制与命中共源)。
*
@@ -2407,15 +2447,6 @@ namespace jdi
*/
void PaintSignalInteraction(gd::Graphics& g);
/**
* @brief 绘制浮动面板「GX」徽标的悬停提示气泡(用户 2026-10-19 要求)。
*
* 气泡锚定在徽标下方,内容为“G 编号”与当前可执行的操
*(目标网格已在视界内 / 点击滚动到该网格)。
* ⚠️ 必须在**面板像素图层之后**绘制(见 `PaintEdgeCursor` 末尾),否则会被缓存进面板位图。
*/
void PaintPanelBadgeTooltip(gd::Graphics& g);
/**
* @brief 在绘图区底部绘制临时提示条(如“已放弃当前选区”)。
* @param [IN,OUT] g 绘图上下文。
@@ -2620,8 +2651,9 @@ namespace jdi
/**
* @brief 上一帧鼠标是否悬停在某个浮动面板标题栏的「GX」徽标上(是则记录网格下标 / 面板种类)。
*
* 徽标绘制在面板**像素图层**里(缓存键只在鼠标位于面板内时才混入坐标),
* 而提示气泡是贴图之后的叠加层(见 `PaintPanelBadgeTooltip`),因此需要单独记录状态。
* 徽标本体绘制在面板**像素图层**里(缓存键只在鼠标位于面板内时才混入坐标),
* 因此需要单独记录状态才能让高亮跟着鼠标进出而刷新。
* ⚠️ 用户 2026-10-21 要求:徽标悬停**不改变鼠标形状**、也**不弹提示气泡**。
*/
int m_hoverPanelBadgeLane = -1;
int m_hoverPanelBadgeKind = -1;