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

+121 -20
View File
@@ -21,15 +21,38 @@ namespace jdi
enum class PlotDragMode : int
{
NONE = 0, /**< 未拖拽。 */
PAN_TIME, /**< 水平平移时间轴(常规模式下的左键拖拽)。 */
PAN, /**< 常规模式:水平平移时间轴 + 纵向偏移当前网格幅值。 */
RUBBER_TIME, /**< 时间轴缩放选区(竖向贯穿全高)。 */
RUBBER_VALUE, /**< Y 轴缩放选区(限定在某个网格内)。 */
SCROLL_LANES, /**< 拖动网格滚动条。 */
CURSOR_MOVE /**< 拖拽时间光标。 */
CURSOR_MOVE, /**< 拖拽时间光标。 */
MOVE_SIGNAL /**< 拖拽信号曲线到其它网格。 */
};
/**
* @brief 波形绘图区:网格、时间轴、光标、缩放与自适应。
* @brief 绘图区内的内联数值输入目标。
*/
enum class PlotEditTarget : int
{
NONE = 0, /**< 未处于输入状态。 */
CURSOR_TIME, /**< 编辑时间光标位置。 */
LANE_Y_MAX, /**< 编辑某网格的 Y 轴最大值。 */
LANE_Y_MIN /**< 编辑某网格的 Y 轴最小值。 */
};
/**
* @brief 绘图区右键菜单命令标识(与信号面板的命令空间相互独立)。
*/
enum PlotMenuCommand : int
{
PLOT_CMD_LANE_AUTO = 1, /**< 该网格恢复 Y 轴自适应。 */
PLOT_CMD_LANE_Y_MAX = 2, /**< 输入该网格 Y 轴最大值。 */
PLOT_CMD_LANE_Y_MIN = 3, /**< 输入该网格 Y 轴最小值。 */
PLOT_CMD_FIT_ALL = 4 /**< 全部网格与时间轴自适应。 */
};
/**
* @brief 波形绘图区:网格、时间轴、光标、缩放、自适应与信号拖拽。
*
* 绘图区同时依赖数据层(DataSet,只读)与当前标签页配置(TabConfig,可写),
* 视图范围、网格滚动与时间光标均保存在标签页配置中,因此各标签页互不干扰。
@@ -201,10 +224,40 @@ namespace jdi
PlotZoomMode CurrentZoomMode() const;
/**
* @brief 判断是否已进入精确时间输入状态。
* @brief 查询坐标命中的网格下标(用于右键菜单)。
* @param [IN] x 客户区横坐标。
* @param [IN] y 客户区纵坐标。
* @return 网格下标,未命中返回 -1。
*/
int LaneIndexAt(int x, int y) const;
/**
* @brief 判断某网格的 Y 轴是否处于自适应状态。
* @param [IN] laneIndex 网格下标。
* @return 自适应返回 true。
*/
bool LaneRangeIsAuto(int laneIndex) const;
/**
* @brief 让某网格的 Y 轴恢复自适应。
* @param [IN] laneIndex 网格下标。
* @return 状态发生变化返回 true。
*/
bool ResetLaneRange(int laneIndex);
/**
* @brief 进入某网格 Y 轴上限/下限的内联输入状态。
* @param [IN] laneIndex 网格下标。
* @param [IN] editMax 为 true 编辑上限,为 false 编辑下限。
* @return 进入成功返回 true。
*/
bool BeginLaneValueEdit(int laneIndex, bool editMax);
/**
* @brief 判断是否处于任意内联数值输入状态。
* @return 处于编辑态返回 true。
*/
bool IsEditingCursor() const { return m_cursorEditing; }
bool IsEditing() const { return m_editTarget != PlotEditTarget::NONE; }
/**
* @brief 处理编辑态下的字符输入。
@@ -373,6 +426,21 @@ namespace jdi
*/
bool ApplyValueSelection(int laneIndex, float y0, float y1);
/**
* @brief 以指定倍率缩放某网格的幅值轴(保持锚点幅值不动)。
* @param [IN] laneIndex 目标网格下标。
* @param [IN] factor 缩放倍率,大于 1 表示放大。
* @param [IN] anchorValue 锚点幅值。
*/
void ScaleLaneRange(int laneIndex, double factor, double anchorValue);
/**
* @brief 平移某网格的幅值轴(偏移波形显示位置)。
* @param [IN] laneIndex 目标网格下标。
* @param [IN] deltaValue 幅值偏移量。
*/
void ShiftLaneRange(int laneIndex, double deltaValue);
/**
* @brief 计算时间光标当前的横坐标。
* @return 横坐标。
@@ -393,17 +461,34 @@ namespace jdi
bool IsOnCursorLine(int x) const;
/**
* @brief 进入时间光标的精确时间输入状态。
* @return 进入成功返回 true。
* @brief 精确检测鼠标位置是否命中某条可见信号曲线。
* @param [IN] x 客户区横坐标。
* @param [IN] y 客户区纵坐标。
* @return 命中的信号引用,未命中返回无效引用。
*/
bool BeginCursorEdit();
SignalRef HitTestSignal(int x, int y) const;
/**
* @brief 结束时间光标的精确时间输入。
* @brief 计算当前内联输入框的矩形(依编辑目标而定)。
* @return 输入框矩形,未处于编辑态时返回空矩形。
*/
gd::RectF EditFieldRect() const;
/**
* @brief 以给定目标与初始文本进入内联输入状态。
* @param [IN] target 编辑目标。
* @param [IN] laneIndex 目标网格下标(光标编辑时忽略)。
* @param [IN] initialText 初始文本。
* @return 进入成功返回 true。
*/
bool BeginEdit(PlotEditTarget target, int laneIndex, const std::wstring& initialText);
/**
* @brief 结束内联输入。
* @param [IN] commit 是否提交当前输入。
* @return 状态发生变化返回 true。
*/
bool EndCursorEdit(bool commit);
bool EndEdit(bool commit);
/**
* @brief 构建单条信号在当前视图下的折线点序列。
@@ -421,10 +506,9 @@ namespace jdi
* @param [IN] laneIndex 网格下标。
* @param [IN] lane 网格绘制信息。
* @param [IN] timeTicks 时间刻度序列。
* @param [IN] timeStep 时间刻度步长。
*/
void PaintLane(gd::Graphics& g, int laneIndex, const LaneVisual& lane,
const std::vector<double>& timeTicks, double timeStep);
const std::vector<double>& timeTicks);
/**
* @brief 绘制底部时间轴。
@@ -447,6 +531,18 @@ namespace jdi
*/
void PaintRubberBand(gd::Graphics& g);
/**
* @brief 绘制内联数值输入框(时间光标或网格 Y 轴上下限)。
* @param [IN,OUT] g 绘图上下文。
*/
void PaintEditField(gd::Graphics& g);
/**
* @brief 绘制信号悬停提示与拖拽虚影。
* @param [IN,OUT] g 绘图上下文。
*/
void PaintSignalInteraction(gd::Graphics& g);
/**
* @brief 绘制网格纵向滚动条。
* @param [IN,OUT] g 绘图上下文。
@@ -503,10 +599,9 @@ namespace jdi
gd::RectF m_timeAxisRect; /**< 时间轴区域。 */
gd::RectF m_scrollBarRect; /**< 网格滚动条区域。 */
float m_yAxisWidth = 74.0f; /**< 纵轴标签列宽度(逻辑像素)。 */
float m_labelBandWidth = 66.0f; /**< 网格内侧纵轴标尺带宽度(逻辑像素)。 */
float m_timeAxisHeight = 32.0f; /**< 时间轴高度(逻辑像素)。 */
float m_laneGap = 6.0f; /**< 网格间距(逻辑像素)。 */
float m_minLaneHeight = 46.0f; /**< 网格最小高度(逻辑像素)。 */
float m_minLaneHeight = 54.0f; /**< 网格最小高度(逻辑像素)。 */
float m_laneContentHeight = 0.0f; /**< 网格内容总高度。 */
bool m_scrollBarVisible = false; /**< 是否需要显示滚动条。 */
@@ -517,15 +612,21 @@ namespace jdi
int m_dragStartY = 0; /**< 拖拽起点纵坐标。 */
int m_dragLastX = 0; /**< 上一次拖拽横坐标。 */
int m_dragLastY = 0; /**< 上一次拖拽纵坐标。 */
gd::RectF m_rubberRect; /**< 拖拽选区矩形。 */
gd::RectF m_rubberRect; /**< 拖拽选区矩形。 */
SignalRef m_hoverSignal; /**< 鼠标悬停命中的信号(曲线高亮)。 */
SignalRef m_dragSignal; /**< 正在被拖拽的信号。 */
int m_dragTargetLane = -1; /**< 拖拽信号时的目标网格下标。 */
bool m_cursorHover = false; /**< 鼠标是否悬停在时间光标上。 */
bool m_cursorEditing = false; /**< 是否处于精确时间输入状态。 */
bool m_cursorEditFresh = false; /**< 编辑框是否处于“首次输入整体替换”状态。 */
std::wstring m_cursorEditText; /**< 编辑框当前文本。 */
gd::RectF m_cursorEditRect; /**< 编辑框矩形(用于命中测试与绘制)。 */
PlotEditTarget m_editTarget = PlotEditTarget::NONE; /**< 当前内联输入目标。 */
bool m_editFresh = false; /**< 输入框是否处于“首次输入整体替换”状态。 */
std::wstring m_editText; /**< 输入框当前文本。 */
int m_editLane = -1; /**< 内联输入所作用的网格下标。 */
int m_hoverLane = -1; /**< 当前悬停网格下标。 */
int m_mouseX = 0; /**< 最近一次鼠标横坐标(用于悬停提示定位)。 */
int m_mouseY = 0; /**< 最近一次鼠标纵坐标(用于悬停提示定位)。 */
std::vector<LaneVisual> m_lanes; /**< 当前网格绘制信息集合。 */
};
File diff suppressed because it is too large. Load diff