Files
Just-DataInspector/Components/SignalPanel/Inc/SignalPanel.hpp
T
DeepSeek V4.1 Flash 132b305544 feat: 搭建 Just DataInspector 波形数据查看器基础功能
基于 Win32 API + GDI+ 从零实现仿真数据检查器,用于替代 Simulink.sdi.view 查看带时间轴的 CSV 数据。

- 新增 Utilities 层:UTF-8/宽字符与数值格式化工具、CSV 解析器(自动识别分隔符与引号)、
  信号数据集模型(时间轴识别、信号名解析、取值采样)、Solarised Light 主题色板与绘图基础工具
- 新增 Toolbar 组件:打开 CSV、适应窗口、适应时间、放大、缩小、合并网格、每信号一格
- 新增 SignalPanel 组件:信号列表(可见性开关、颜色标识、所属网格标记)、样式编辑区
  (颜色、线宽、线段/散点/点线/阶梯显示方式、所属网格),支持右键上下文菜单与滚轮滚动
- 新增 PlotView 组件:多网格波形绘制、自适应时间轴与幅值轴、网格线、信号图例、
  时间光标与实时数值读数、纵向滚动条
- 新增 Application 组件:DPI 感知(Per-Monitor V2)、双缓冲绘制、区域布局与分隔条拖拽、
  鼠标与键盘消息分发、文件拖放、状态栏提示
- 交互能力:滚轮缩放、Shift+滚轮平移、Ctrl+滚轮缩放幅值、拖拽平移、幅值轴纵向缩放、
  右键框选缩放、单击固定/取消时间光标、双击自适应、方向键平移与滚动
- 补齐 Makefile 的源文件与头文件索引,并新增 gdiplus、comdlg32 链接库
2026-09-29 15:05:29 +08:00

219 lines
5.9 KiB
C++

#ifndef __SIGNAL_PANEL_HPP__
#define __SIGNAL_PANEL_HPP__
#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>
#include <array>
#include <string>
#include "PaintUtil.hpp"
#include "SignalSet.hpp"
#include "Theme.hpp"
namespace jdi
{
/**
* @brief 左侧信号面板:信号列表、可见性开关与样式编辑。
*/
class SignalPanel
{
public:
SignalPanel();
/**
* @brief 绑定宿主窗口、字体与主题资源。
* @param [IN] host 宿主窗口句柄,用于弹出上下文菜单。
* @param [IN] fonts 字体集合,需在面板生命周期内保持有效。
* @param [IN] theme 主题配色,需在面板生命周期内保持有效。
*/
void Setup(HWND host, const UiFonts* fonts, const Theme* theme);
/**
* @brief 绑定数据集。
* @param [IN] document 数据集指针,允许为空。
*/
void SetDocument(SignalSet* document);
/**
* @brief 设置 DPI 缩放比例。
* @param [IN] scale 缩放比例(1.0 对应 96 DPI)。
*/
void SetScale(float scale);
/**
* @brief 按给定区域重新排布面板内容。
* @param [IN] area 面板可用区域。
*/
void Layout(const gd::RectF& area);
/**
* @brief 绘制面板。
* @param [IN,OUT] g 绘图上下文。
*/
void Paint(gd::Graphics& g);
/**
* @brief 处理鼠标移动。
* @param [IN] x 客户区横坐标。
* @param [IN] y 客户区纵坐标。
* @return 悬停状态发生变化返回 true。
*/
bool OnMouseMove(int x, int y);
/**
* @brief 处理鼠标左键按下。
* @param [IN] x 客户区横坐标。
* @param [IN] y 客户区纵坐标。
* @return 需要重绘返回 true。
*/
bool OnLButtonDown(int x, int y);
/**
* @brief 处理鼠标左键抬起。
* @param [IN] x 客户区横坐标。
* @param [IN] y 客户区纵坐标。
* @return 视觉状态发生变化返回 true。
*/
bool OnLButtonUp(int x, int y);
/**
* @brief 处理鼠标左键双击(切换信号可见性)。
* @param [IN] x 客户区横坐标。
* @param [IN] y 客户区纵坐标。
* @return 需要重绘返回 true。
*/
bool OnDoubleClick(int x, int y);
/**
* @brief 处理鼠标右键按下(弹出信号上下文菜单)。
* @param [IN] x 客户区横坐标。
* @param [IN] y 客户区纵坐标。
* @return 需要重绘返回 true。
*/
bool OnRButtonDown(int x, int y);
/**
* @brief 处理滚轮滚动(列表纵向滚动)。
* @param [IN] delta 滚轮增量。
* @return 需要重绘返回 true。
*/
bool OnMouseWheel(int delta);
/**
* @brief 处理鼠标离开面板。
* @return 视觉状态发生变化返回 true。
*/
bool OnMouseLeave();
/**
* @brief 判断坐标是否落在面板区域内。
* @param [IN] x 客户区横坐标。
* @param [IN] y 客户区纵坐标。
* @return 落在区域内返回 true。
*/
bool HitTest(int x, int y) const;
private:
/**
* @brief 样式编辑区中的可点击条目类型。
*/
enum class StyleHit : int
{
NONE = 0, /**< 未命中。 */
COLOR, /**< 颜色色块。 */
WIDTH, /**< 线宽按钮。 */
MODE, /**< 绘制方式按钮。 */
LANE, /**< 网格选择按钮。 */
TOGGLE_ALL /**< 全部显示/隐藏按钮。 */
};
/**
* @brief 计算列表区域内容高度。
* @return 内容高度。
*/
float ContentHeight() const;
/**
* @brief 限制滚动偏移量到合法范围。
*/
void ClampScroll();
/**
* @brief 查询指定坐标对应的信号行下标。
* @param [IN] y 客户区纵坐标。
* @return 行下标,未命中返回 -1。
*/
int RowAtY(int y) const;
/**
* @brief 计算行的纵向矩形。
* @param [IN] row 行下标。
* @return 行矩形。
*/
gd::RectF RowRect(int row) const;
/**
* @brief 绘制列表区域的单行。
* @param [IN,OUT] g 绘图上下文。
* @param [IN] row 行下标。
*/
void PaintRow(gd::Graphics& g, int row);
/**
* @brief 绘制样式编辑区。
* @param [IN,OUT] g 绘图上下文。
*/
void PaintStyleSection(gd::Graphics& g);
/**
* @brief 弹出信号右键菜单。
* @param [IN] signalIndex 目标信号下标。
* @param [IN] screenX 屏幕坐标横坐标。
* @param [IN] screenY 屏幕坐标纵坐标。
*/
void ShowSignalMenu(int signalIndex, int screenX, int screenY);
/**
* @brief 弹出网格分配菜单。
*/
void ShowLaneMenu();
/**
* @brief 判断全部信号是否均为可见状态。
* @return 全部可见返回 true。
*/
bool AreAllSignalsVisible() const;
HWND m_host = nullptr; /**< 宿主窗口句柄。 */
const UiFonts* m_fonts = nullptr; /**< 字体资源。 */
const Theme* m_theme = nullptr; /**< 主题资源。 */
SignalSet* m_document = nullptr; /**< 数据集。 */
float m_scale = 1.0f; /**< DPI 缩放比例。 */
gd::RectF m_area; /**< 面板整体区域。 */
gd::RectF m_headerRect; /**< 标题区域。 */
gd::RectF m_listRect; /**< 列表区域。 */
gd::RectF m_styleRect; /**< 样式编辑区域。 */
gd::RectF m_toggleAllRect; /**< 全部显示/隐藏按钮。 */
gd::RectF m_laneButtonRect; /**< 网格选择按钮。 */
std::array<gd::RectF, 12> m_colorRects; /**< 颜色色块矩形。 */
std::array<gd::RectF, 4> m_widthRects; /**< 线宽按钮矩形。 */
std::array<gd::RectF, 4> m_modeRects; /**< 绘制方式按钮矩形。 */
int m_colorCount = 0; /**< 实际可用的颜色数量。 */
float m_widthRowLabelX = 0.0f; /**< 样式标签列起始横坐标。 */
float m_styleRowHeight = 0.0f; /**< 样式行高。 */
float m_scrollOffset = 0.0f; /**< 列表滚动偏移量。 */
int m_hoverRow = -1; /**< 当前悬停行。 */
StyleHit m_hoverStyle = StyleHit::NONE; /**< 当前悬停的样式条目类型。 */
int m_hoverStyleIndex = -1; /**< 当前悬停的样式条目下标。 */
};
} // namespace jdi
#endif // __SIGNAL_PANEL_HPP__