主题自适应配色 + 预览曲线连续配色 + 样式区复位按钮 + 均值滤波面板重做 + 面板缓存环带残留 + 调试层序 + 自由标记选取与性能
① 主题自适应(`Theme.cpp`):新增 `SrgbLuminance` / `ContrastRatio` / `EnsureContrast` /
`MixToLuminance` / `ThemeLaneBackground`;四套主题的结构色(gridWeak 1.30 / gridStrong 1.65 /
axisLine 2.10 / borderStrong 1.70)按底色自动校正,Solarised Light 逐位不变;网格叠底改用
`ThemeLaneBackground()`(4 处),深色主题下网格层与绘图区底色可辨。
② 派生预览曲线(`HighContrastDerived`)重写为**连续**方案:方向沿信号所在侧远离底色,
目标亮度 = max(与底色对比度 3.2, 信号亮度 ± 0.18),再按亮度平滑混色;调用点传入真实网格底色
(旧实现默认写死 Solarised Light 底色 ⇒ 深色主题永远选到更暗的那一侧、几乎看不见)。
③ 信号样式区「线宽 / 透明度」两行右侧新增**复位按钮**(`UiPaintResetIcon` 成为唯一实现,
菜单/弱峰面板/样式区共用同一套笔画);默认线宽统一到 `DefaultSignalLineWidth(finiteCount)`
(单点信号取 10.0)。按钮右边界与内容列对齐,内容列过窄时整列不显示。
④ 「均值滤波」面板重做:信号色叠底标题栏 + 复选框 + 展开三角 + 「均值点数 / 迭代次数」两行滑块
(点击数值可改滑块上限、右侧复位)+ 内容区滚动;新增 `MeanFilterItem::{maxPoints,maxIterations,
collapsed}` 与 `Lane::meanFilterScroll`,缓存键同步补全。
⑤ 浮动面板命中像素缓存时只贴**面板圆角形状之内**的像素(`CreateRoundRectRgn` 裁剪)并按本帧重画投影
⇒ 中键移视界后面板周围不再出现一圈旧波形。
⑥ 显示布局边界:每个浮动面板**独占一个绘制层**(按 `m_panelOrder` 递增),绘制侧
`UiSetTextLayer` 在同一循环内同步推进 ⇒ 下层面板的边框/文字不再画到上层面板上。
⑦ 自由标记:采样候选距离改为**二维欧氏距离**(单点信号不再在整幅宽度内吸住光标),
纵向光标画在鼠标位置、圆点落在真实采样点(新增 `FreeMarkerProbe::pointX`);
`MinorCellSparse` 只对胜出信号算一次;折线缓存容量改为 `max(64, 信号数×2)` 且查找改为
单键哈希 ⇒ MF4 的 285 信号合并网格中 `ProbeFreeMarker` 平均 0.11ms。
验证:`.preflight` 探针重建(`panelcheck` 71/71、`markercheck` 13/13、`ringcheck` 6/6,合计 90 条,
LTO 目标文件上复跑同样全绿);`make release` / `make debug` 零警告;产物 815,104 B。
文档:`agent_mem.md` 第十六轮(含补丁脚本与编码/行尾踩坑)。
This commit is contained in:
1 parent
71195c4c48
commit
bdd703b88b
24 files changed
+1815
-256
No files matched your search
@@ -62,7 +62,10 @@ namespace jdi
|
||||
PEAK_ITERATIONS, /**< 拖动「弱峰调整」某信号的迭代次数滑块(1 … 该信号自定义上限)。 */
|
||||
LANE_REORDER, /**< 拖动网格图例中的 GX 编号徽标:上下调整网格次序。 */
|
||||
MARKER_OPACITY, /**< 拖动「自由标记」面板的「标记透明度」滑块。 */
|
||||
MARKER_SCROLL /**< 拖动「自由标记」面板内容的滚动条滑块。 */
|
||||
MARKER_SCROLL, /**< 拖动「自由标记」面板内容的滚动条滑块。 */
|
||||
MEAN_POINTS, /**< 拖动「均值滤波」某信号的「均值点数」滑块(0 … 该信号自定义上限)。 */
|
||||
MEAN_ITERATIONS,/**< 拖动「均值滤波」某信号的「迭代次数」滑块(1 … 该信号自定义上限)。 */
|
||||
MEAN_SCROLL /**< 拖动「均值滤波」面板内容的滚动条滑块。 */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -91,6 +94,15 @@ namespace jdi
|
||||
MEAN_FILTER_POINTS, /**< 编辑「均值滤波」的均值点数 X。 */
|
||||
MEAN_FILTER_ITERATIONS, /**< 编辑「均值滤波」的迭代次数 N。 */
|
||||
PEAK_ITERATIONS_MAX, /**< 编辑「弱峰调整」某信号「迭代次数 N」滑块的**上限**(正整数)。 */
|
||||
/**
|
||||
* @brief 编辑「均值滤波」某信号「均值点数」滑块的**上限**(正整数)。
|
||||
*
|
||||
* 与 `PEAK_ITERATIONS_MAX` 同一交互语义:点击滑块右侧数值 → 整行变成输入框,
|
||||
* 输入框以空内容开始、并显示“输入上限(当前N)”提示。
|
||||
*/
|
||||
MEAN_POINTS_MAX,
|
||||
/** @brief 编辑「均值滤波」某信号「迭代次数」滑块的**上限**(正整数)。 */
|
||||
MEAN_ITERATIONS_MAX,
|
||||
FREE_MARKER_TIME, /**< 编辑「自由标记」某固定点的**自身时间**(秒)。 */
|
||||
FREE_MARKER_DELTA /**< 编辑「自由标记」某固定点相对前一固定点的**时间间隔**(秒)。 */
|
||||
};
|
||||
@@ -1079,6 +1091,12 @@ namespace jdi
|
||||
*/
|
||||
bool SetLaneFreeMarkerScroll(int laneIndex, float scroll);
|
||||
|
||||
/**
|
||||
* @brief 设置某网格「均值滤波」面板内容的滚动偏移(客户区像素,0 = 顶部)。
|
||||
* @return 偏移真的发生变化返回 true。
|
||||
*/
|
||||
bool SetLaneMeanFilterScroll(int laneIndex, float scroll);
|
||||
|
||||
/**
|
||||
* @brief 切换某网格「自由标记」面板里某个信号分组的收起状态。
|
||||
* @return 切换后为「已收起」返回 true。
|
||||
@@ -1799,6 +1817,15 @@ namespace jdi
|
||||
*/
|
||||
std::vector<gd::RectF> rowLevelResets;
|
||||
std::vector<gd::RectF> rowIterResets;
|
||||
/**
|
||||
* @brief 「均值滤波」面板每个信号的**信号色叠底标题栏**矩形(与 `rowRefs` 同序)。
|
||||
*
|
||||
* 排版与「自由标记」面板的信号分组栏一致(左侧展开三角 + 信号名),
|
||||
* 但右端是**复选框**(`rowChecks`)而不是 ✕。未勾选时标题栏仍显示(用于勾选)。
|
||||
*/
|
||||
std::vector<gd::RectF> rowHeaders;
|
||||
/** @brief 「均值滤波」面板每个信号标题栏左侧的**展开 / 收起三角**(仅勾选后出现)。 */
|
||||
std::vector<gd::RectF> rowTriangles;
|
||||
std::vector<SignalRef> rowRefs;
|
||||
/**
|
||||
* @brief 「自由标记」面板的一行(一个固定点)。
|
||||
@@ -1843,6 +1870,13 @@ namespace jdi
|
||||
gd::RectF tableHeader;
|
||||
gd::RectF triangle; /**< 展开/收起三角的命中矩形。 */
|
||||
gd::RectF close; /**< 右侧✕的命中矩形。 */
|
||||
/**
|
||||
* @brief 右侧**复选框**的命中矩形(仅「均值滤波」面板使用;「自由标记」为空)。
|
||||
*
|
||||
* 均值滤波面板的组头右端是"是否预览该信号"的复选框(用户 2026-10-30 要求),
|
||||
* 只有它被勾选时左侧的展开三角才出现、才能展开参数行。
|
||||
*/
|
||||
gd::RectF check;
|
||||
bool collapsed = false;
|
||||
/**
|
||||
* @brief 该分组栏是否处于**吸顶**(滚动时被钉在内容区顶部)。
|
||||
@@ -1862,6 +1896,14 @@ namespace jdi
|
||||
gd::RectF content;
|
||||
/** 「自由标记」面板的**内容总高度**(含被滚动出去的条目),用于换算滚动比例。 */
|
||||
float markerContentHeight = 0.0f;
|
||||
/**
|
||||
* @brief 内容区当前生效的**滚动偏移**(像素,≥ 0)。
|
||||
*
|
||||
* 「自由标记」与「均值滤波」两个面板的内容区都可能需要滚动;取值来源不同
|
||||
* (`Lane::freeMarkerScroll` / `Lane::meanFilterScroll`),但布局之后一律从这里读,
|
||||
* 绘制与命中共用同一份偏移(避免两处各自夹取导致"画的和点的不一致")。
|
||||
*/
|
||||
float scrollOffset = 0.0f;
|
||||
gd::RectF scrollTrack; /**< 内容区右侧的滚动条轨道(不需要滚动时为空矩形)。 */
|
||||
gd::RectF scrollThumb; /**< 滚动条滑块。 */
|
||||
gd::RectF opacityTrack; /**< 「标记透明度」滑动条轨道(总是显示,与选取模式无关)。 */
|
||||
@@ -1945,7 +1987,15 @@ namespace jdi
|
||||
bool cursorMode = false; /**< 该网格是否处于「自由标记点选取」(决定是否画纵向光标)。 */
|
||||
int laneIndex = -1; /**< 该网格下标。 */
|
||||
double time = 0.0; /**< 标注时刻(显示时刻;吸附时 = 采样时刻)。 */
|
||||
float x = 0.0f; /**< 该时刻的屏幕横坐标。 */
|
||||
float x = 0.0f; /**< 纵向光标的横坐标(= 鼠标位置,跟随鼠标)。 */
|
||||
/**
|
||||
* @brief 被标注的那个**数据点**的屏幕横坐标。
|
||||
*
|
||||
* 与 `x`(鼠标位置)分开:纵向光标画在 `x`,而取值圆点必须落在**真实采样点**上
|
||||
*(`TimeToX(time)`)—— 稀疏信号下两者可能相差十几个像素。
|
||||
* 用户 2026-10-30 明确要求"光标跟着鼠标走,提示靠纵向最近的数据点"。
|
||||
*/
|
||||
float pointX = 0.0f;
|
||||
SignalRef ref; /**< 就近信号(网格内没有可用信号时无效)。 */
|
||||
double value = 0.0; /**< 已叠加「调整」变换的取值(用于标注与增量)。 */
|
||||
double enumValue = 0.0; /**< 采样原值(用于查枚举表)。 */
|
||||
@@ -2750,6 +2800,14 @@ namespace jdi
|
||||
bool m_mouseOverPanel = false; /**< 上一帧鼠标是否落在某个实验性功能面板上。 */
|
||||
int m_peakDragLane = -1; /**< 正在拖动弱峰滑块的面板所属网格。 */
|
||||
SignalRef m_peakDragRef; /**< 正在拖动弱峰滑块的**信号**(每个信号一套参数)。 */
|
||||
int m_meanDragLane = -1; /**< 正在拖动「均值滤波」参数滑块的面板所属网格。 */
|
||||
SignalRef m_meanDragRef; /**< 正在拖动「均值滤波」参数滑块的信号(每信号一套参数)。 */
|
||||
/**
|
||||
* @brief 正在编辑「均值滤波」某个滑块上限时,输入框内灰色提示用的**当前上限值**。
|
||||
*
|
||||
* 与 `m_peakEditCurrentMax` 同一语义(输入框以空内容开始,空内容时显示当前上限)。
|
||||
*/
|
||||
int m_meanEditCurrentMax = 0;
|
||||
/**
|
||||
* @brief 正在编辑「迭代次数 N 上限」时,输入框内灰色提示用的**当前上限值**。
|
||||
*
|
||||
@@ -3079,6 +3137,16 @@ namespace jdi
|
||||
{
|
||||
SignalRef ref; /**< 信号引用。 */
|
||||
const SignalGroup* group = nullptr; /**< 所属分组(缓存键的一部分)。 */
|
||||
/**
|
||||
* @brief 全部键字段的 64 位哈希(FNV-1a)。
|
||||
*
|
||||
* ⚠️ **缓存查找只比这一个值**:旧实现逐条比较下面十几个字段,
|
||||
* 而"上百个信号合并到同一网格"时(例如 MF4-Record 的 283 个信号)每次查找
|
||||
* 都要扫过整张表 ⇒ 绘制与 `ProbeFreeMarker` 每帧做数万次字段比较,
|
||||
* 鼠标在网格内移动会明显卡顿(用户 2026-10-30 报告)。
|
||||
* 命中哈希后再校验 `ref` / `sampleCount` / 视界三项(极低成本),可忽略碰撞风险。
|
||||
*/
|
||||
std::uint64_t key = 0;
|
||||
std::size_t sampleCount = 0; /**< 采样点数(数据变化时改变)。 */
|
||||
double viewMin = 0.0; /**< 时间轴显示下界。 */
|
||||
double viewMax = 0.0; /**< 时间轴显示上界。 */
|
||||
@@ -3145,6 +3213,14 @@ namespace jdi
|
||||
const LaneVisual& lane) const;
|
||||
|
||||
mutable std::deque<PolylineCacheEntry> m_polylineCache; /**< 折线顶点缓存(按几何键复用)。 */
|
||||
/**
|
||||
* @brief 折线顶点缓存的**容量上限**(条目数)。
|
||||
*
|
||||
* 由 `BuildLaneVisuals` 按"当前全部网格的信号总数 × 2"刷新(下限 `kPolylineCacheLimit`)。
|
||||
* ⚠️ 固定 64 条在"多信号合并网格"下会**持续抖动**(装满即整表清空 ⇒ 下一帧全部重建),
|
||||
* 这正是"上百个信号合并到同一网格时自由标记非常卡"的根因之一。
|
||||
*/
|
||||
mutable std::size_t m_polylineCacheCapacity = 64;
|
||||
|
||||
/**
|
||||
* @brief 图层**横向补条**渲染期间的折线裁剪范围(省掉整段折线的重建与描边)。
|
||||
|
||||
Reference in new issue
Block a user