feat: 重构绘图区网格布局与信号拖拽,精简界面信息并新增 Y 轴精确控制

网格与标尺:
- 消除网格之间无意义的间隔,改用较重的横向分界线明确区分相邻网格
- 纵轴标尺从绘图区左侧外侧移入网格内侧,并改为带半透明衬底的覆盖层绘制,
  使其在波形之上依然清晰可读;绘图区左侧空间因此完全还给波形
- 继续保证底部时间轴预留高度,并把时间列名贴左显示、避开刻度标签

常规模式拖拽:
- 常规模式下水平拖动平移时间轴,纵向拖动偏移当前网格的幅值显示位置
- 绘图区右键菜单新增「恢复 Y 轴自适应」「设置 Y 轴最大值…」「设置 Y 轴最小值…」
  「全部自适应」,上下限通过内联输入框直接键入(与线宽输入一致的交互)

信号拖拽:
- 鼠标贴近信号曲线时给出光晕高亮与提示气泡(与时间光标的提示方式一致)
- 仅在出现提示时按左键才会进入拖拽;拖拽过程中在目标网格内绘制曲线虚影、
  高亮目标网格边框并提示「移动到网格 N」,松开左键确认归属变更
- 命中检测基于折线到光标的精确点到线段距离,散点模式按采样点距离判定

界面精简:
- 移除底部状态栏(左下角统计与右下角提示均不再占用空间),错误改由对话框提示
- 标题栏只显示应用名称
- 移除工具栏右上角的视图时间范围文本;按钮除「导入文件」外整体靠右排列

其他:
- 新增 PlotView::PaintEditField 统一绘制时间光标与网格 Y 轴上下限的输入框
- 移除已无引用的 UiDrawDashedLine 与绘图区标尺占位宽度
This commit is contained in:
DeepSeek V4.1 Flash committed 2026-09-29 20:49:21 +08:00
1 parent 17eb03a1b3
commit 542aa51e40
9 files changed
+981 -335

No files matched your search

-7
View File
@@ -58,12 +58,6 @@ namespace jdi
*/
void SetDocumentLoaded(bool hasDocument);
/**
* @brief 设置工具栏右侧的状态文本。
* @param [IN] text 状态文本。
*/
void SetStatusText(const std::wstring& text);
/**
* @brief 设置可切换按钮的选中状态。
* @param [IN] action 目标按钮动作。
@@ -156,7 +150,6 @@ namespace jdi
const Theme* m_theme = nullptr; /**< 主题资源。 */
float m_scale = 1.0f; /**< DPI 缩放比例。 */
bool m_documentLoaded = false; /**< 是否已加载数据。 */
std::wstring m_statusText; /**< 右侧状态文本。 */
std::vector<Button> m_buttons; /**< 按钮集合。 */
gd::RectF m_area; /**< 工具栏整体区域。 */
int m_hoverIndex = -1; /**< 当前悬停按钮下标。 */
+29 -24
View File
@@ -36,11 +36,6 @@ namespace jdi
m_documentLoaded = hasDocument;
}
void Toolbar::SetStatusText(const std::wstring& text)
{
m_statusText = text;
}
float Toolbar::DesiredHeight() const
{
return (kButtonHeight + kTopPadding * 2.0f) * m_scale;
@@ -71,7 +66,7 @@ namespace jdi
};
const Spec specs[] = {
{ToolbarAction::OPEN_FILE, L"打开 CSV", true, false, false},
{ToolbarAction::OPEN_FILE, L"导入文件", true, false, false},
{ToolbarAction::FIT_ALL, L"适应视图", false, true, false},
{ToolbarAction::ZOOM_TIME, L"时间轴缩放", false, true, true},
{ToolbarAction::ZOOM_VALUE, L"Y 轴缩放", false, true, true},
@@ -81,13 +76,17 @@ namespace jdi
{ToolbarAction::SELECT_ALL, L"全选信号", false, true, false},
{ToolbarAction::CLEAR_ALL, L"清空勾选", false, true, false},
};
const std::size_t specCount = sizeof(specs) / sizeof(specs[0]);
// 按钮宽度按实际文本像素宽 + 固定内边距计算,避免中文标签被裁切。
float cursorX = area.X + kSidePadding * m_scale;
const float top = area.Y + kTopPadding * m_scale;
const float height = kButtonHeight * m_scale;
const float horizontalPadding = kButtonPadding * 2.0f * m_scale;
// 先建立全部按钮并测量宽度,再决定“导入文件”固定在左、其余按钮整体靠右。
m_buttons.clear();
m_buttons.reserve(specCount);
for (const Spec& spec : specs)
{
Button button;
@@ -97,17 +96,31 @@ namespace jdi
button.needsDocument = spec.needsDocument;
button.toggle = spec.toggle;
button.width = horizontalPadding + UiMeasureTextWidth(m_fonts->ui, button.label);
button.rect = gd::RectF(cursorX, top, button.width, height);
cursorX += button.width + kButtonGap * m_scale;
if (spec.action == ToolbarAction::OPEN_FILE || spec.action == ToolbarAction::CURSOR ||
spec.action == ToolbarAction::SPLIT_LANES)
{
cursorX += kGroupGap * m_scale;
}
m_buttons.push_back(std::move(button));
}
// 首按钮(导入文件)靠左;其余按钮作为整体靠右,并留出一组额外间距。
const float leftX = area.X + kSidePadding * m_scale;
float groupWidth = 0.0f;
for (std::size_t index = 1; index < m_buttons.size(); ++index)
{
groupWidth += m_buttons[index].width;
if (index + 1 < m_buttons.size())
{
groupWidth += kButtonGap * m_scale;
}
}
float cursorX = leftX;
m_buttons[0].rect = gd::RectF(cursorX, top, m_buttons[0].width, height);
const float rightEdge = area.X + area.Width - kSidePadding * m_scale;
cursorX = std::max(leftX + m_buttons[0].width + kGroupGap * m_scale, rightEdge - groupWidth);
for (std::size_t index = 1; index < m_buttons.size(); ++index)
{
m_buttons[index].rect = gd::RectF(cursorX, top, m_buttons[index].width, height);
cursorX += m_buttons[index].width + kButtonGap * m_scale;
}
}
void Toolbar::SetToggleState(ToolbarAction action, bool checked)
@@ -195,14 +208,6 @@ namespace jdi
UiText(g, button.label, m_fonts->ui, button.rect, textColor, TextAlign::CENTER);
}
// 右侧状态文本。
if (!m_statusText.empty())
{
const float rightPadding = kSidePadding * m_scale;
gd::RectF textRect(m_area.X, m_area.Y, m_area.Width - rightPadding, m_area.Height);
UiText(g, m_statusText, m_fonts->uiSmall, textRect, m_theme->textMuted, TextAlign::RIGHT);
}
// 底部分隔线。
UiDrawLine(g, m_area.X, m_area.Y + m_area.Height - 1.0f, m_area.X + m_area.Width,
m_area.Y + m_area.Height - 1.0f, m_theme->border, 1.0f);