「所属网格」菜单:标题固定 + 10 行上限 + 滚动条;网格滚动联动改为动态过渡
1) 菜单滚动时最上方的「所属网格」标题不再跟着滚走
- 根因:上一轮只实现了“尾部固定区”(最后一个分隔线 + 「新建网格」钉在底部),
而滚动区是从条目 0 开始的,于是标题也被一起滚掉。
- 修法:BuildLayout 新增 m_scrollFirst(= 前导 HEADER / HEADER_ACTION 的个数),
滚动区收敛为半开区间 [m_scrollFirst, m_pinnedIndex):
· 前导标题从菜单顶向下固定排(不参与滚动);
· 滚动区条目受 m_scrollOffset 影响;
· 尾部固定区从菜单底向上对齐。
- 配套:Paint 的裁剪与“跳过不可见条目”范围、ItemAtPoint 的“必须落在滚动视口内”判定、
EnsureItemVisible 的下界全部改用该区间;新增 ScrollRegion(first, last) 供查询/测试。
2) 菜单长度上限改为「最多 10 条网格」并加滚动条
- MenuLayoutConstraint 新增 maxScrollRows(滚动区最多显示的标准行数;与 maxHeight
同时给出时取更严格者);OpenLaneMenu 传 10(kLaneMenuVisibleRows),
另保留 maxHeight = max(180, 客户区高 × 0.8) 作为矮窗口的硬上限。
- 新增滚动条:轨道贴滚动条目区右内侧(不盖住标题与底部固定项),滑块高度按视口/内容比
(下限 22 逻辑像素);滚动区条目宽度让出 kScrollBarWidth + kScrollBarGap,
文本与对勾不会压在滑块上。
- 滚动条可拖拽:按下滑块 → 拖动(只改偏移、不更新悬停);点击轨道空白 → 滑块中心移过去;
松开结束拖拽且不下发命令、菜单保持打开。新增 ScrollOffsetForThumbTop 反算偏移。
- ⚠️ BuildLayout 绝不能复位 m_scrollBarDragging:拖拽时每帧都会 RebuildLayout(),
在那里清零会让拖拽“拖一下就脱手”(该状态只在 Open / Close 里复位)。
3) 网格滚动联动改为动态过渡(旧实现直接把视界瞬移过去,过于僵硬)
- PlotView::ScrollLaneIntoView 只负责启动平滑动画:与信号列表的“滚动到目标信号”同源
(ease-out cubic;时长 clamp(距离×0.35ms, 130, 300)),新增
m_laneScrollAnimActive/From/To/StartMs/DurationMs。
- 宿主 16ms 定时器(kScrollTimerId)调用 AdvanceLaneScrollAnimation() 逐帧推进,
与信号面板动画共用同一条定时器;Render 的“需要保持定时重绘”判定加入
LaneScrollAnimationActive()。
- 每帧 ClampLaneScroll() + BuildLaneVisuals()(网格滚动量参与场景/图层指纹与各网格 rect);
结束时精确落到目标。已完整可见的网格仍然不启动动画。
- ⚠️ 用户自己滚动网格(滚轮 / 拖滚动条)会 CancelLaneScrollAnimation(),避免与动画抢滚动位置。
验证(全部离屏执行:窗口 SW_HIDE + 只注入合成消息 + 进程与线程 BELOW_NORMAL,
不移动真实光标、不抢焦点、不截屏):
- .preflight/check 扩到 95 项,95/95 通过;新增断言:
· 菜单顶部标题在滚动时不动(Y 坐标不变)、滚动视口高度恰为 10 × 行高;
· 滚动条轨道/滑块存在、随滚动移动、按住滑块拖到底(菜单不关、不下发命令、末条目入视口)、
滚轮回到顶部;
· ScrollLaneIntoView 不瞬移(刚触发时几乎未动)、中间帧单调递进、收尾精确到位、
已可见时不启动动画、滚轮/手动滚动会取消动画。
- A/B:回退三处(标题固定 / 10 行上限 / 滚动动画)⇒ 10 项如实失败;恢复后 95/95。
- make release / make debug 零警告。
文档:Documents/agent_mem.md 新增 §9.39、§11.2 第 104–107 条与变更日志一行。
This commit is contained in:
1 parent
2904699eae
commit
82b5ebe4f9
10 files changed
+496
-78
No files matched your search
@@ -924,7 +924,7 @@ namespace jdi
|
||||
bool TakePanelScrollRequest(SignalRef& ref);
|
||||
|
||||
/**
|
||||
* @brief 把指定网格纵向滚动到**完整可见**(网格不在可视区时自动调节滚动条)。
|
||||
* @brief 把指定网格**平滑滚动**到完整可见(带动画,网格不在可视区时自动调节滚动条)。
|
||||
*
|
||||
* 用户 2026-10-16 要求:信号很多时(例如把 MF4 的上百条信号各自放进独立网格)
|
||||
* 每个网格只占绘图区的一小段,绝大多数网格都在可视区之外 —— 在信号列表里点选一条
|
||||
@@ -933,13 +933,31 @@ namespace jdi
|
||||
* * 目标网格在可视区**下方** ⇒ 向下滚动直到它的下边界进入绘图区下沿;
|
||||
* * 已经完整可见 ⇒ 不动(避免无意义地改变视图)。
|
||||
*
|
||||
* ⚠️ 过渡必须是**带动画的平滑滚动**(与信号列表的“滚动到目标信号”同源:ease-out cubic、
|
||||
* 时长 `clamp(距离×0.35ms, 130, 300)`),不是直接把视界瞬移过去 —— 用户 2026-10-16 明确要求。
|
||||
* 动画由宿主 16ms 定时器驱动(`AdvanceLaneScrollAnimation`)。
|
||||
*
|
||||
* ⚠️ 只在**点击**信号时调用(悬停只做高亮联动,绝不改变视图)。
|
||||
*
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @return 视图(网格滚动量)发生变化返回 true。
|
||||
* @return 开始了滚动(动画或已到位)返回 true;已完整可见则返回 false。
|
||||
*/
|
||||
bool ScrollLaneIntoView(int laneIndex);
|
||||
|
||||
/**
|
||||
* @brief 推进一步网格滚动动画(由宿主定时器驱动)。
|
||||
* @return 动画仍在进行返回 true(宿主应保持定时重绘)。
|
||||
*/
|
||||
bool AdvanceLaneScrollAnimation();
|
||||
|
||||
/** @brief 网格滚动动画是否正在进行。 */
|
||||
bool LaneScrollAnimationActive() const { return m_laneScrollAnimActive; }
|
||||
|
||||
/**
|
||||
* @brief 取消网格滚动动画(用户自己滚动网格时调用,避免动画与手动滚动抢滚动位置)。
|
||||
*/
|
||||
void CancelLaneScrollAnimation() { m_laneScrollAnimActive = false; }
|
||||
|
||||
/**
|
||||
* @brief 处理编辑态下的字符输入。
|
||||
* @param [IN] character 输入字符。
|
||||
@@ -2023,6 +2041,13 @@ namespace jdi
|
||||
float m_laneContentHeight = 0.0f; /**< 网格内容总高度。 */
|
||||
bool m_scrollBarVisible = false; /**< 是否需要显示滚动条。 */
|
||||
|
||||
/** 网格滚动(“点选信号 ⇒ 把目标网格滚入可视区”)的平滑过渡状态。 */
|
||||
bool m_laneScrollAnimActive = false; /**< 动画是否正在进行。 */
|
||||
float m_laneScrollAnimFrom = 0.0f; /**< 动画起始滚动偏移。 */
|
||||
float m_laneScrollAnimTo = 0.0f; /**< 动画目标滚动偏移。 */
|
||||
std::uint64_t m_laneScrollAnimStartMs = 0; /**< 动画起始时刻(`GetTickCount64()`)。 */
|
||||
std::uint32_t m_laneScrollAnimDurationMs = 0; /**< 动画总时长(毫秒)。 */
|
||||
|
||||
PlotDragMode m_dragMode = PlotDragMode::NONE; /**< 当前拖拽模式。 */
|
||||
PlotRubberAxis m_rubberAxis = PlotRubberAxis::UNDECIDED; /**< 选区放大拖拽的轴向。 */
|
||||
int m_dragLane = -1; /**< 拖拽所作用的网格下标。 */
|
||||
|
||||
Reference in new issue
Block a user