统一文本输入(新增 Utilities/Inc/TextEdit.hpp + TextEdit.cpp) - 一个共享的编辑模型,提供光标/选区/过滤/限长,接入全部输入框: 样式区数值与信号名/分组名、波形图例改名、视图标签页改名、 拾色器 R/G/B 与色号、光标时间与网格上下限。 - 新增能力:Ctrl+A/C/X/V(含剪贴板清洗)、Shift+方向键与 Home/End 选区、 退格与删除清除选区、代理对安全的光标步进。 - 渲染改为选区高亮 + 插入符,文本超出框宽时水平滚动并让插入符始终可见; 初始态为整段选中,首字符键入即整体替换(保持"登录框"式交互)。 - 新增 Utf8Util::PasteTextFromClipboard(换行/制表符折叠为空格)。 修复网格合并(Utilities/Src/DataModel.cpp) - 拖拽信号到其它网格时先固定目标网格的锚信号,再移除源信号并按引用找回目标, 避免空网格回收导致下标错位,从"与原网格交换位置"改为真正合并。 - 自定义划分下未分配网格的可见信号改为各自独占一个新网格, 修复"拖拽合并后再勾选新信号被并入该合并网格"的问题。 绘图区(Components/PlotView) - 网格右键菜单新增"时间轴自适应(匹配本网格)",把时间轴对齐到该网格信号范围。 - 时间轴放大到采样点在屏幕上可分辨(>=6 逻辑像素)时,拖动光标吸附到最近数据点; 缩小到无法分辨时保持自由移动,避免光标"跳格"。 验证:真实输入脚本逐项核对——拖拽合并后单网格含两条曲线、拖拽合并再勾选新信号得 G2 独立网格、 Shift 选区 + Delete 清除、Ctrl+A/C/V 复制粘贴、46 字符文本水平滚动、拾色器色号 1E90FF、 标签页改名 A1、光标时间框复制粘贴、全视图拖动得 0.522213(不吸附)而放大后得 0.28125(= 225 × 0.00125,已吸附)。
262 lines
8.5 KiB
C++
262 lines
8.5 KiB
C++
#ifndef __PAINT_UTIL_HPP__
|
||
#define __PAINT_UTIL_HPP__
|
||
|
||
#include <windows.h>
|
||
#include <objidl.h>
|
||
#include <gdiplus.h>
|
||
|
||
#include <cstdint>
|
||
#include <string>
|
||
|
||
#include "TextEdit.hpp"
|
||
#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] 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] track 轨道矩形。
|
||
* @param [IN] ratio 当前值比例(0-1)。
|
||
* @param [IN] fillColor 已填充部分颜色。
|
||
* @param [IN] active 是否处于悬停或拖拽状态(影响圆钮半径)。
|
||
* @param [IN] scale DPI 缩放比例。
|
||
*/
|
||
void UiDrawSlider(gd::Graphics& g, const gd::RectF& track, double ratio, std::uint32_t fillColor,
|
||
bool active, float scale);
|
||
|
||
/**
|
||
* @brief 绘制单行内联输入框(含选区高亮、插入符与水平滚动)。
|
||
*
|
||
* 初始状态为“整体选中”时以强调色底衬显示全部内容,首字符键入即整体替换,
|
||
* 交互观感与常见登录界面的账号/密码输入框一致;文本超出框宽时自动横向滚动,
|
||
* 保证插入符始终可见。
|
||
*
|
||
* @param [IN,OUT] g 绘图上下文。
|
||
* @param [IN] rect 输入框矩形。
|
||
* @param [IN] edit 输入框编辑模型。
|
||
* @param [IN] font 文本字体。
|
||
* @param [IN] scale DPI 缩放比例。
|
||
*/
|
||
void UiDrawEditField(gd::Graphics& g, const gd::RectF& rect, const TextEdit& edit, HFONT font,
|
||
float scale);
|
||
|
||
/**
|
||
* @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__
|