交互细节修复:悬停提示锚定、选区放大提示生命周期、光标样式统一与差值标签
- 信号悬停提示改为"锚定在首次出现位置":新增 m_hoverAnchorX/Y, PaintSignalInteraction 用锚点而非当前鼠标位置;同时补回 OnMouseMove 里 漏写的 m_hoverSignal 赋值(该行缺失会导致悬停提示完全不显示)。 - 选区放大(RUBBER_SELECT)的提示文字按阶段切换: 开启开关 -> 「横向或纵向拖动以放大选择区域,ESC退出选区模式」; 左键按下不显示提示;开始拖动后维持「右键取消选区,ESC退出选区模式」; 松开左键后淡出。新增 SetHintSticky/ReleaseHint(m_hintSticky 期间阻塞淡出), HintNeedsAnimation() 驱动宿主的淡出定时器。 - 两个时间光标统一为同一颜色与样式(去掉 theme.cursorAlt,仅保留 theme.cursor); 光标把手统一为同一形状。工具栏按钮文案动态化: 未选中「光标」/ 单光标「光标x1」/ 双光标「光标x2」 (Toolbar::SetActionLabel 返回是否变化,变化时 Application::Relayout() 以重算按钮宽度)。 - 取值胶囊避让重叠:PaintCursor 先把两条时间读数标签与 Δt 标签的矩形预填进 m_cursorLabelRects,取值标签逐条检测重叠并向下/向上让位, 多信号数据点重合或过近时读数不再互相覆盖。 两光标靠近时,光标 2 的时间读数标签自动上移一层叠放,避免互相覆盖。 - 双光标时间读数与 Δt 差值标签支持拖拽,并区分悬停与拖拽: 悬停显示手形(IDC_HAND),拖拽统一使用抓握图标(IDC_SIZEALL, 用 m_dragOnLabel 与"直接在光标线上抓取"的左右箭头区分); Δt 标签拖拽时两条光标整体平移,差值保持不变。 - Δt 差值显示样式与光标时间读数一致,文案为「Δt <时间差值>」,单位复合化: >= 60s 一路整合到 h/min/s(3662s -> 「1h 1min 2s」);1~60s 显示整秒, 非整数时补 ms(5.06s -> 「5s 60ms」,5s -> 「5s」);< 1s 逐级降到 ms/us/ns/ps 且只降一级,顶级单位为 ps 时不再降级并保留小数(「5.123 ps」)。 - 双击 Δt 进入编辑时数值量级始终为秒(例如显示 1min 时编辑框为 60.0), 修正进入高级单位后(如 1.5min)编辑框只显示 1.5 的问题。 验证(使用 TestData/VERY_BIG_DATA.CSV,1.77GB / 5 信号): - 悬停提示停留在首次出现位置,网格内继续移动鼠标不再跟随。 - 选区放大提示:开启/按下/拖动/松开四个阶段的文案与淡出均符合预期。 - 工具栏文案 光标 / 光标x1 / 光标x2 正常;两光标样式与颜色完全一致。 - 5 条信号合并网格时取值标签全部完整可见,无覆盖。 - 光标形态探测:时间读数标签与 Δt 标签悬停 HAND、拖拽 SIZEALL; 直接在光标线上拖拽仍为 SIZEWE。 - Δt 分别输入 3662 / 5.06 / 5.123e-12 秒得到「Δt 1h 1min 2s」/ 「Δt 5s 60ms」/「Δt 5.11591 ps」;整数秒显示「Δt 5s」。 - 双击 Δt(显示 15s 457.214ms)编辑框内容为 15.4572(秒)。 - Δt 标签拖拽 (-320px):光标 64.4051/79.8623 -> 30.743/46.2002,差值保持 15.4572。 - 两光标靠近时时间读数标签上下叠放、Δt 标签落位正确,取值标签不重叠。 - [1].CSV 回归正常;make clean && make all 无警告无错误。
This commit is contained in:
1 parent
eaf5b9cadf
commit
ed13aa7d49
7 files changed
+583
-84
No files matched your search
@@ -64,6 +64,24 @@ namespace jdi
|
||||
*/
|
||||
void SetToggleState(ToolbarAction action, bool checked);
|
||||
|
||||
/**
|
||||
* @brief 覆盖某个按钮的显示文本(用于状态相关的动态标签,例如「光标」)。
|
||||
*
|
||||
* 调用后需要由宿主重新排布(`Layout`)才能让按钮宽度与新文本匹配。
|
||||
*
|
||||
* @param [IN] action 目标按钮动作。
|
||||
* @param [IN] label 新文本。
|
||||
* @return 文本发生变化返回 true(此时宿主应重新排布)。
|
||||
*/
|
||||
bool SetActionLabel(ToolbarAction action, const std::wstring& label);
|
||||
|
||||
/**
|
||||
* @brief 获取某个动作按钮当前的显示文本。
|
||||
* @param [IN] action 目标按钮动作。
|
||||
* @return 按钮文本;不存在时返回空串。
|
||||
*/
|
||||
std::wstring ActionLabel(ToolbarAction action) const;
|
||||
|
||||
/**
|
||||
* @brief 计算工具栏在指定缩放下的期望高度。
|
||||
* @return 期望高度(像素)。
|
||||
@@ -150,6 +168,7 @@ namespace jdi
|
||||
float m_scale = 1.0f; /**< DPI 缩放比例。 */
|
||||
bool m_documentLoaded = false; /**< 是否已加载数据。 */
|
||||
std::vector<Button> m_buttons; /**< 按钮集合。 */
|
||||
std::vector<std::pair<ToolbarAction, std::wstring>> m_labelOverrides; /**< 动态文本覆盖表。 */
|
||||
gd::RectF m_area; /**< 工具栏整体区域。 */
|
||||
int m_hoverIndex = -1; /**< 当前悬停按钮下标。 */
|
||||
int m_pressedIndex = -1; /**< 当前按下按钮下标。 */
|
||||
|
||||
@@ -94,6 +94,17 @@ namespace jdi
|
||||
button.primary = spec.primary;
|
||||
button.needsDocument = spec.needsDocument;
|
||||
button.toggle = spec.toggle;
|
||||
|
||||
// 动态文本覆盖(例如「光标」按当前模式显示 光标 / 光标x1 / 光标x2)。
|
||||
for (const std::pair<ToolbarAction, std::wstring>& entry : m_labelOverrides)
|
||||
{
|
||||
if (entry.first == spec.action)
|
||||
{
|
||||
button.label = entry.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
button.width = horizontalPadding + UiMeasureTextWidth(m_fonts->ui, button.label);
|
||||
m_buttons.push_back(std::move(button));
|
||||
}
|
||||
@@ -134,6 +145,51 @@ namespace jdi
|
||||
}
|
||||
}
|
||||
|
||||
bool Toolbar::SetActionLabel(ToolbarAction action, const std::wstring& label)
|
||||
{
|
||||
for (std::pair<ToolbarAction, std::wstring>& entry : m_labelOverrides)
|
||||
{
|
||||
if (entry.first == action)
|
||||
{
|
||||
if (entry.second == label)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
entry.second = label;
|
||||
// 已排布过时同步更新按钮文本,宿主随后会调用 Layout() 重新计算宽度。
|
||||
for (Button& button : m_buttons)
|
||||
{
|
||||
if (button.action == action)
|
||||
{
|
||||
button.label = label;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
m_labelOverrides.emplace_back(action, label);
|
||||
for (Button& button : m_buttons)
|
||||
{
|
||||
if (button.action == action)
|
||||
{
|
||||
button.label = label;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::wstring Toolbar::ActionLabel(ToolbarAction action) const
|
||||
{
|
||||
for (const Button& button : m_buttons)
|
||||
{
|
||||
if (button.action == action)
|
||||
{
|
||||
return button.label;
|
||||
}
|
||||
}
|
||||
return std::wstring();
|
||||
}
|
||||
|
||||
void Toolbar::Paint(gd::Graphics& g)
|
||||
{
|
||||
if (m_theme == nullptr || m_fonts == nullptr)
|
||||
|
||||
Reference in new issue
Block a user