fix: 修复网格滚动溢出并重构绘图区缩放与时间光标交互
网格滚动: - 修复纵向滚动时波形与文字溢出到工具栏/时间轴的问题:网格内容裁剪改为与绘图区求交, 并对网格内的图例、幅值标签与读数框增加显式可见性判定 (GDI 文本不遵循 GDI+ 裁剪区,仅裁剪矢量绘制不足以阻止溢出)。 - 网格之间改为完整矩形描边并加大间距,边界清晰;时间轴固定预留高度,不再被网格挤压。 - 时间轴刻度标签夹在绘图区横向范围内,避免与左侧时间列名重叠。 缩放交互: - 取消滚轮缩放:滚轮改为纵向滚动网格,Shift+滚轮水平平移。 - 新增「时间轴缩放」「Y 轴缩放」工具栏切换按钮:选中后在绘图区拖拽选区放大对应轴向, 拖动过程显示选区与跨度提示(时间用强调色、Y 轴用警示色);再次点击退出该模式。 - 「适应视图」回到初始状态:恢复自适应范围并退出缩放模式。 - 移除右键框选缩放,避免与模式化缩放重复。 时间光标: - 改为工具栏「光标」按钮切换;启用时置于当前视图中心,再次点击关闭(Esc 亦可关闭)。 - 光标由鼠标靠近后拖拽移动,不再跟随鼠标;纵向贯穿全部网格并延伸到时间轴底部, 顶部带三角把手提示可拖拽。 - 具体时间读数移至绘图区顶部,仅在鼠标覆盖光标时显示,不再遮挡时间轴刻度尺。 - 双击光标进入精确时间输入,交互与线宽输入一致:整段高亮、首次键入即整体覆盖、 回车提交、Esc 取消、点击框外提交。 - 光标形态按模式区分:默认与悬停线外为箭头(不再出现十字指针), 时间轴缩放/光标为水平双向箭头,Y 轴缩放为垂直双向箭头。
This commit is contained in:
1 parent
cba62c8218
commit
17eb03a1b3
6 files changed
+852
-359
No files matched your search
@@ -32,7 +32,8 @@ namespace jdi
|
||||
const int kMinClientWidth = 860; /**< 窗口最小客户区宽度。 */
|
||||
const int kMinClientHeight = 540; /**< 窗口最小客户区高度。 */
|
||||
const UINT kMessageRemoveFile = WM_APP + 1; /**< 面板请求移除文件的自定义消息。 */
|
||||
const wchar_t* kStatusHint = L"滚轮缩放 · Shift+滚轮平移 · Ctrl+滚轮调幅值 · 右键框选 · 双击自适应";
|
||||
const wchar_t* kStatusHint =
|
||||
L"滚轮纵向滚动网格 · Shift+滚轮平移 · 双击绘图区恢复自适应 · Esc 关闭光标";
|
||||
|
||||
/** @brief 标签页右键菜单命令 ID。 */
|
||||
const int kMenuTabNew = 1;
|
||||
@@ -576,6 +577,13 @@ namespace jdi
|
||||
m_toolbar.SetStatusText(std::wstring());
|
||||
}
|
||||
|
||||
// 工具栏可切换按钮的选中状态始终与当前标签页配置保持一致。
|
||||
m_toolbar.SetToggleState(ToolbarAction::ZOOM_TIME,
|
||||
m_plot.CurrentZoomMode() == PlotZoomMode::TIME);
|
||||
m_toolbar.SetToggleState(ToolbarAction::ZOOM_VALUE,
|
||||
m_plot.CurrentZoomMode() == PlotZoomMode::VALUE);
|
||||
m_toolbar.SetToggleState(ToolbarAction::CURSOR, m_plot.CursorEnabled());
|
||||
|
||||
{
|
||||
gd::Graphics g(m_backDc);
|
||||
g.SetSmoothingMode(gd::SmoothingModeAntiAlias);
|
||||
@@ -641,7 +649,7 @@ namespace jdi
|
||||
rightText = m_statusMessage;
|
||||
rightColor = m_statusIsError ? m_theme.danger : m_theme.textStrong;
|
||||
}
|
||||
else if (m_plot.HasCursor() && !m_dataSet.Empty())
|
||||
else if (m_plot.CursorEnabled() && !m_dataSet.Empty())
|
||||
{
|
||||
rightText = L"光标 · " + FormatValue(m_plot.CursorTime());
|
||||
rightColor = m_theme.text;
|
||||
@@ -813,13 +821,36 @@ namespace jdi
|
||||
OpenFileDialog();
|
||||
break;
|
||||
case ToolbarAction::FIT_ALL:
|
||||
// 自适应同时回到初始状态:退出缩放模式并显示全部信号范围。
|
||||
m_plot.FitAll();
|
||||
SetStatusMessage(L"已恢复自适应视图。", false);
|
||||
break;
|
||||
case ToolbarAction::ZOOM_IN:
|
||||
m_plot.ZoomTimeStep(1.4);
|
||||
case ToolbarAction::ZOOM_TIME:
|
||||
if (m_plot.ToggleZoomMode(PlotZoomMode::TIME))
|
||||
{
|
||||
SetStatusMessage((m_plot.CurrentZoomMode() == PlotZoomMode::TIME)
|
||||
? L"时间轴缩放:在绘图区横向拖拽选择区间即可放大。"
|
||||
: L"已退出时间轴缩放模式。",
|
||||
false);
|
||||
}
|
||||
break;
|
||||
case ToolbarAction::ZOOM_OUT:
|
||||
m_plot.ZoomTimeStep(1.0 / 1.4);
|
||||
case ToolbarAction::ZOOM_VALUE:
|
||||
if (m_plot.ToggleZoomMode(PlotZoomMode::VALUE))
|
||||
{
|
||||
SetStatusMessage((m_plot.CurrentZoomMode() == PlotZoomMode::VALUE)
|
||||
? L"Y 轴缩放:在某个网格内纵向拖拽选择区间即可放大。"
|
||||
: L"已退出 Y 轴缩放模式。",
|
||||
false);
|
||||
}
|
||||
break;
|
||||
case ToolbarAction::CURSOR:
|
||||
if (m_plot.ToggleCursor())
|
||||
{
|
||||
SetStatusMessage(m_plot.CursorEnabled()
|
||||
? L"时间光标已启用:拖动竖线移动,双击竖线可输入精确时间。"
|
||||
: L"时间光标已关闭。",
|
||||
false);
|
||||
}
|
||||
break;
|
||||
case ToolbarAction::MERGE_LANES:
|
||||
if (!m_dataSet.Empty())
|
||||
@@ -895,7 +926,7 @@ namespace jdi
|
||||
switch (key)
|
||||
{
|
||||
case VK_ESCAPE:
|
||||
m_plot.ClearCursor();
|
||||
m_plot.DisableCursor();
|
||||
return true;
|
||||
case VK_ADD:
|
||||
case VK_OEM_PLUS:
|
||||
@@ -1336,6 +1367,12 @@ namespace jdi
|
||||
const int x = GET_X_LPARAM(lParam);
|
||||
const int y = GET_Y_LPARAM(lParam);
|
||||
|
||||
// 时间光标处于精确输入态时,点击绘图区之外视为提交(与线宽输入一致)。
|
||||
if (m_plot.IsEditingCursor() && !m_plot.HitTest(x, y))
|
||||
{
|
||||
m_plot.OnEditKey(VK_RETURN);
|
||||
}
|
||||
|
||||
// 点击面板之外的位置时收起面板内展开的自定义颜色面板。
|
||||
if (!m_panel.HitTest(x, y))
|
||||
{
|
||||
@@ -1496,33 +1533,12 @@ namespace jdi
|
||||
m_activeTarget = Target::NONE;
|
||||
return 0;
|
||||
}
|
||||
if (m_plot.HitTest(x, y))
|
||||
{
|
||||
SetCapture(hwnd);
|
||||
m_activeTarget = Target::PLOT;
|
||||
if (m_plot.OnRButtonDown(x, y))
|
||||
{
|
||||
InvalidateRect(hwnd, nullptr, FALSE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case WM_RBUTTONUP:
|
||||
{
|
||||
const int x = GET_X_LPARAM(lParam);
|
||||
const int y = GET_Y_LPARAM(lParam);
|
||||
bool changed = false;
|
||||
if (m_activeTarget == Target::PLOT)
|
||||
{
|
||||
changed = m_plot.OnRButtonUp(x, y);
|
||||
}
|
||||
ReleaseCapture();
|
||||
m_activeTarget = Target::NONE;
|
||||
if (changed)
|
||||
{
|
||||
InvalidateRect(hwnd, nullptr, FALSE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case WM_MOUSEWHEEL:
|
||||
@@ -1531,9 +1547,7 @@ namespace jdi
|
||||
ScreenToClient(hwnd, &point);
|
||||
|
||||
const int delta = GET_WHEEL_DELTA_WPARAM(wParam);
|
||||
const bool control = (GET_KEYSTATE_WPARAM(wParam) & MK_CONTROL) != 0;
|
||||
const bool shift = (GET_KEYSTATE_WPARAM(wParam) & MK_SHIFT) != 0;
|
||||
const bool alt = (GetKeyState(VK_MENU) & 0x8000) != 0;
|
||||
|
||||
bool changed = false;
|
||||
if (m_panel.HitTest(point.x, point.y))
|
||||
@@ -1542,7 +1556,7 @@ namespace jdi
|
||||
}
|
||||
else if (m_plot.HitTest(point.x, point.y))
|
||||
{
|
||||
changed = m_plot.OnMouseWheel(point.x, point.y, delta, control, shift, alt);
|
||||
changed = m_plot.OnMouseWheel(point.x, point.y, delta, shift);
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
@@ -1577,7 +1591,7 @@ namespace jdi
|
||||
break;
|
||||
}
|
||||
case WM_KEYDOWN:
|
||||
// 线宽数值输入状态优先接管按键(回车提交、Esc 取消、退格删除)。
|
||||
// 数值输入状态优先接管按键(回车提交、Esc 取消、退格删除)。
|
||||
if (m_panel.IsEditingWidth())
|
||||
{
|
||||
if (m_panel.OnEditKey(wParam))
|
||||
@@ -1586,6 +1600,14 @@ namespace jdi
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (m_plot.IsEditingCursor())
|
||||
{
|
||||
if (m_plot.OnEditKey(wParam))
|
||||
{
|
||||
InvalidateRect(hwnd, nullptr, FALSE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (HandleKeyDown(wParam))
|
||||
{
|
||||
InvalidateRect(hwnd, nullptr, TRUE);
|
||||
@@ -1594,7 +1616,7 @@ namespace jdi
|
||||
break;
|
||||
case WM_CHAR:
|
||||
{
|
||||
// 线宽数值仅接受数字与小数点,其余字符一律吞掉。
|
||||
// 数值输入仅接受数字与小数点(或科学计数法符号),其余字符一律吞掉。
|
||||
if (m_panel.IsEditingWidth())
|
||||
{
|
||||
if (m_panel.OnEditChar(static_cast<wchar_t>(wParam)))
|
||||
@@ -1603,6 +1625,14 @@ namespace jdi
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (m_plot.IsEditingCursor())
|
||||
{
|
||||
if (m_plot.OnEditChar(static_cast<wchar_t>(wParam)))
|
||||
{
|
||||
InvalidateRect(hwnd, nullptr, FALSE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_KILLFOCUS:
|
||||
|
||||
Reference in new issue
Block a user