Files
Just-DataInspector/Utilities/Inc/PaintUtil.hpp
T
DeepSeek V4.1 Flash 542aa51e40 feat: 重构绘图区网格布局与信号拖拽,精简界面信息并新增 Y 轴精确控制
网格与标尺:
- 消除网格之间无意义的间隔,改用较重的横向分界线明确区分相邻网格
- 纵轴标尺从绘图区左侧外侧移入网格内侧,并改为带半透明衬底的覆盖层绘制,
  使其在波形之上依然清晰可读;绘图区左侧空间因此完全还给波形
- 继续保证底部时间轴预留高度,并把时间列名贴左显示、避开刻度标签

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

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

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

其他:
- 新增 PlotView::PaintEditField 统一绘制时间光标与网格 Y 轴上下限的输入框
- 移除已无引用的 UiDrawDashedLine 与绘图区标尺占位宽度
2026-09-29 20:49:21 +08:00

244 lines
7.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef __PAINT_UTIL_HPP__
#define __PAINT_UTIL_HPP__
#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>
#include <cstdint>
#include <string>
#include "Theme.hpp"
namespace jdi
{
/**
* @brief 文本水平对齐方式(垂直方向始终居中)。
*/
enum class TextAlign : int
{
LEFT = 0, /**< 左对齐。 */
CENTER = 1, /**< 水平居中。 */
RIGHT = 2 /**< 右对齐。 */
};
/**
* @brief 图标朝向。
*/
enum class IconDirection : int
{
LEFT = 0, /**< 指向左侧。 */
RIGHT = 1, /**< 指向右侧。 */
UP = 2, /**< 指向上方。 */
DOWN = 3 /**< 指向下方。 */
};
/**
* @brief 按 DPI 创建并缓存整套界面字体(GDI 字体句柄)。
*/
struct UiFonts
{
HFONT ui = nullptr; /**< 常规界面字体。 */
HFONT uiBold = nullptr; /**< 加粗界面字体。 */
HFONT uiSmall = nullptr; /**< 小号界面字体。 */
HFONT uiSmallBold = nullptr;/**< 小号加粗界面字体。 */
HFONT title = nullptr; /**< 标题字体。 */
HFONT mono = nullptr; /**< 等宽数值字体。 */
HFONT monoSmall = nullptr; /**< 小号等宽字体。 */
UINT dpi = 96; /**< 创建时所使用的 DPI。 */
/**
* @brief 依据 DPI 创建全部字体。
* @param [IN] dpi 目标 DPI(96 对应 100% 缩放)。
* @return 创建成功返回 true。
*/
bool Create(UINT dpi);
/**
* @brief 释放全部字体句柄。
*/
void Destroy();
~UiFonts() { Destroy(); }
};
/**
* @brief 将 0xAARRGGBB 颜色值转换为 GDI COLORREF。
* @param [IN] argb 颜色值。
* @return GDI 颜色值。
*/
inline COLORREF ToColorRef(std::uint32_t argb)
{
return RGB((argb >> 16) & 0xFFu, (argb >> 8) & 0xFFu, argb & 0xFFu);
}
/**
* @brief 判断点是否落在矩形内部。
* @param [IN] rect 目标矩形。
* @param [IN] x 横坐标。
* @param [IN] y 纵坐标。
* @return 落在内部返回 true。
*/
inline bool UiPointInRect(const gd::RectF& rect, float x, float y)
{
return x >= rect.X && x <= (rect.X + rect.Width) && y >= rect.Y && y <= (rect.Y + rect.Height);
}
/**
* @brief 填充矩形区域。
* @param [IN,OUT] g 绘图上下文。
* @param [IN] rect 目标矩形。
* @param [IN] argb 填充颜色。
*/
void UiFillRect(gd::Graphics& g, const gd::RectF& rect, std::uint32_t argb);
/**
* @brief 填充圆角矩形区域。
* @param [IN,OUT] g 绘图上下文。
* @param [IN] rect 目标矩形。
* @param [IN] radius 圆角半径。
* @param [IN] argb 填充颜色。
*/
void UiFillRoundRect(gd::Graphics& g, const gd::RectF& rect, float radius, std::uint32_t argb);
/**
* @brief 描边圆角矩形。
* @param [IN,OUT] g 绘图上下文。
* @param [IN] rect 目标矩形。
* @param [IN] radius 圆角半径。
* @param [IN] argb 线条颜色。
* @param [IN] width 线条宽度。
*/
void UiDrawRoundRect(gd::Graphics& g, const gd::RectF& rect, float radius, std::uint32_t argb, float width);
/**
* @brief 绘制一条直线。
* @param [IN,OUT] g 绘图上下文。
* @param [IN] x1 起点横坐标。
* @param [IN] y1 起点纵坐标。
* @param [IN] x2 终点横坐标。
* @param [IN] y2 终点纵坐标。
* @param [IN] argb 线条颜色。
* @param [IN] width 线条宽度。
*/
void UiDrawLine(gd::Graphics& g, float x1, float y1, float x2, float y2, std::uint32_t argb, float width);
/**
* @brief 在指定矩形内绘制单行文本(垂直居中,超长自动省略)。
* @param [IN,OUT] g 绘图上下文。
* @param [IN] text 文本内容。
* @param [IN] font 字体句柄。
* @param [IN] rect 文本布局矩形。
* @param [IN] argb 文本颜色。
* @param [IN] align 水平对齐方式。
*/
void UiText(gd::Graphics& g, const std::wstring& text, HFONT font, const gd::RectF& rect, std::uint32_t argb,
TextAlign align = TextAlign::LEFT);
/**
* @brief 测量单行文本的像素宽度。
* @param [IN,OUT] g 绘图上下文。
* @param [IN] text 文本内容。
* @param [IN] font 字体句柄。
* @return 文本像素宽度。
*/
float UiTextWidth(gd::Graphics& g, const std::wstring& text, HFONT font);
/**
* @brief 测量单行文本的像素宽度(无需 GDI+ 上下文,可在布局阶段调用)。
* @param [IN] font 字体句柄。
* @param [IN] text 文本内容。
* @return 文本像素宽度。
*/
float UiMeasureTextWidth(HFONT font, const std::wstring& text);
/**
* @brief 在超出可用宽度时对文本做尾部省略截断。
* @param [IN,OUT] g 绘图上下文。
* @param [IN] text 原始文本。
* @param [IN] font 字体句柄。
* @param [IN] maxWidth 允许的最大像素宽度。
* @return 截断后的文本。
*/
std::wstring UiEllipsize(gd::Graphics& g, const std::wstring& text, HFONT font, float maxWidth);
/**
* @brief 在矩形中心绘制一个加号图标。
* @param [IN,OUT] g 绘图上下文。
* @param [IN] rect 图标布局矩形。
* @param [IN] argb 线条颜色。
* @param [IN] strokeWidth 线条宽度。
*/
void UiDrawPlusIcon(gd::Graphics& g, const gd::RectF& rect, std::uint32_t argb, float strokeWidth);
/**
* @brief 在矩形中心绘制一个叉号(关闭)图标。
* @param [IN,OUT] g 绘图上下文。
* @param [IN] rect 图标布局矩形。
* @param [IN] argb 线条颜色。
* @param [IN] strokeWidth 线条宽度。
*/
void UiDrawCrossIcon(gd::Graphics& g, const gd::RectF& rect, std::uint32_t argb, float strokeWidth);
/**
* @brief 在矩形中心绘制一个箭头(折线形)图标。
* @param [IN,OUT] g 绘图上下文。
* @param [IN] rect 图标布局矩形。
* @param [IN] argb 线条颜色。
* @param [IN] strokeWidth 线条宽度。
* @param [IN] direction 箭头朝向。
*/
void UiDrawArrowIcon(gd::Graphics& g, const gd::RectF& rect, std::uint32_t argb, float strokeWidth,
IconDirection direction);
/**
* @brief 在矩形中心绘制一个实心三角形指示器。
* @param [IN,OUT] g 绘图上下文。
* @param [IN] rect 图标布局矩形。
* @param [IN] argb 填充颜色。
* @param [IN] direction 三角形朝向。
*/
void UiDrawTriangleIcon(gd::Graphics& g, const gd::RectF& rect, std::uint32_t argb, IconDirection direction);
/**
* @brief 将滑块轨道上的横坐标换算为取值比例。
* @param [IN] trackRect 轨道矩形。
* @param [IN] x 横坐标。
* @return 取值比例,范围 0-1。
*/
double UiSliderRatioFromX(const gd::RectF& trackRect, float x);
/**
* @brief 绘制一个带边框的复选框。
* @param [IN,OUT] g 绘图上下文。
* @param [IN] rect 复选框矩形。
* @param [IN] state 选中状态:0 未选,1 全选,2 部分选。
* @param [IN] radius 圆角半径。
*/
void UiDrawCheckBox(gd::Graphics& g, const gd::RectF& rect, int state, float radius);
/**
* @brief 绘制颜色样块:叠加不透明度填充,透明度过低时补充描边以保证可辨识。
* @param [IN,OUT] g 绘图上下文。
* @param [IN] rect 样块矩形。
* @param [IN] color 基础颜色(0xAARRGGBB,其 Alpha 通道会被不透明度覆盖)。
* @param [IN] opacity 不透明度(0-1)。
* @param [IN] radius 圆角半径。
* @param [IN] scale DPI 缩放比例,用于推导描边粗细。
* @return 实际填充颜色的 0xAARRGGBB 值(供需要同步其他元素的调用方使用)。
*/
std::uint32_t UiDrawSwatch(gd::Graphics& g, const gd::RectF& rect, std::uint32_t color, float opacity,
float radius, float scale);
/**
* @brief 判断给定不透明度是否低到需要为样块补充描边。
* @param [IN] opacity 不透明度(0-1)。
* @return 需要描边返回 true。
*/
bool UiSwatchNeedsOutline(float opacity);
} // namespace jdi
#endif // __PAINT_UTIL_HPP__