网格菜单重构、大文件异步加载与内存/解析优化、修复应用图标
网格右键菜单: - 菜单顺序改为: 网格 N / Y 轴最大值 / Y 轴最小值 / 选区 Y 轴自适应 / --分隔线-- / Y 轴自适应 / 时间轴自适应 / 全部自适应 (恢复自适应移到分隔线以下、时间轴自适应上方) - Y 轴最大值/最小值改为菜单内联输入框:点击就地编辑、回车提交,菜单不关闭, 处理方式与拾色器的 RGB 内联编辑一致;提交后按真实夹取结果回写菜单显示值, 并同步刷新自适应项的文案/对勾/可用状态 - 新增"选区 Y 轴自适应":只按当前显示时间段内的数据做幅值自适应 (时间单调时二分定位区间,非单调时全扫并按区间过滤) 大文件加载: - 加载改为工作线程执行(解析 + 按列重组),主线程抽送消息并播放过渡动画 (旋转弧线 + 进度条 + 文件名 + 百分比 + 按 Esc 取消),界面不再整块卡死 - 加载完成后主线程只做一次 O(1) 的移动入队,不会产生可见卡顿 - 新增 DataModel::BuildDataFile / DataSet::AddPreparedFile:不依赖 DataSet, 因此可以安全地在线程上运行 内存与解析效率: - CsvTable 由"行优先二维数组"改为"列优先":百万行文件原先会产生上百万次独立堆分配 (每行还有 vector 控制块与容量对齐开销),现在每列一整块连续内存 - 解析改为流式分块读取(4MB),不再把整个文件读入内存,也没有体积上限 (原先超过 512MB 直接拒绝);实测 51MB 文件峰值内存约 126MB(数据本身 113MB) - BuildDataFile 直接把整列移动进 SignalData(零拷贝),不再逐元素复制 - TryParseDouble 增加十进制快速路径:ucrt strtod 实测约 335ns/次,手写路径约 13ns (快 25 倍);非十进制写法(十六进制浮点、inf/nan、带尾部杂字符)原样交回 strtod, 输入接受语义完全不变(实测与 strtod 的差异不超过 1 ULP) → 640MB 测试文件加载时间由约 40s 降到 2s 以内 交互流畅性: - 拖拽(平移/框选/拖动信号)期间关闭波形抗锯齿并压缩顶点预算(2 像素一列包络), 松开后立即恢复全质量绘制;实测 BIG_DATA 10 信号全显示的帧耗时由 105~168ms 降到 75~90ms(其中折线绘制 55ms→23ms) - 折线包络抽稀改为"列边界单调推进"的二分,避免每列在全区间二分造成缓存缺失 - 未对波形构建引入多线程:构建已由几何键缓存消除,且拖拽降级后仅约 1~2ms/帧, 并行化收益不足以抵消线程与同步的复杂度(加载路径的多线程收益明确,故只在该处引入) 图标: - 窗口类与 WM_SETICON 原先使用系统默认图标 IDI_APPLICATION,导致标题栏、 任务栏与 Alt+Tab 缩略图都显示成通用应用图标;改为按 SM_CXICON/SM_CXSMICON 从应用的 IDI_APP_ICON 资源加载(多尺寸 ICO 会挑选最接近的一帧) 其他: - PopupMenu 新增 EDIT 项类型(菜单内联输入框)与 UpdateItemValue/UpdateItemLabel
This commit is contained in:
1 parent
d6a81839bb
commit
45b44eae57
11 files changed
+1637
-222
No files matched your search
+122
-3
@@ -10,6 +10,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "PaintUtil.hpp"
|
||||
#include "TextEdit.hpp"
|
||||
#include "Theme.hpp"
|
||||
|
||||
namespace jdi
|
||||
@@ -34,7 +35,8 @@ namespace jdi
|
||||
NORMAL = 0, /**< 普通可点击项。 */
|
||||
SEPARATOR = 1, /**< 分隔线。 */
|
||||
HEADER = 2, /**< 分组标题(不可点击)。 */
|
||||
SWATCHES = 3 /**< 颜色色块行。 */
|
||||
SWATCHES = 3, /**< 颜色色块行。 */
|
||||
EDIT = 4 /**< 带内联输入框的项:在菜单内部直接编辑数值(菜单不关闭)。 */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -43,13 +45,15 @@ namespace jdi
|
||||
struct MenuItem
|
||||
{
|
||||
MenuItemKind kind = MenuItemKind::NORMAL; /**< 项目类型。 */
|
||||
std::wstring label; /**< 显示文本。 */
|
||||
std::wstring label; /**< 显示文本;EDIT 项为输入框左侧的说明文字。 */
|
||||
int id = 0; /**< 命令标识。 */
|
||||
bool enabled = true; /**< 是否可用。 */
|
||||
bool checked = false; /**< 是否处于选中(单选)状态。 */
|
||||
int swatchCount = 0; /**< 色块数量(仅色块行有效)。 */
|
||||
std::uint32_t swatches[16] = {}; /**< 色块颜色。 */
|
||||
int checkedSwatch = -1; /**< 被选中的色块下标。 */
|
||||
std::wstring value; /**< EDIT 项的当前数值文本(非编辑态显示)。 */
|
||||
EditFilter filter = EditFilter::ANY; /**< EDIT 项的输入过滤规则。 */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -62,6 +66,8 @@ namespace jdi
|
||||
int id = 0; /**< 被选中项的命令标识。 */
|
||||
int swatchIndex = -1; /**< 被选中的色块下标(非色块行为 -1)。 */
|
||||
gd::RectF itemRect; /**< 被点击条目的矩形(客户区坐标),供就近弹出输入框。 */
|
||||
bool editCommit = false; /**< 该结果来自菜单内联输入框的提交(菜单保持打开)。 */
|
||||
std::wstring editText; /**< 提交的输入文本(editCommit 为 true 时有效)。 */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -158,11 +164,84 @@ namespace jdi
|
||||
/**
|
||||
* @brief 判断坐标是否落在菜单内部。
|
||||
* @param [IN] x 客户区横坐标。
|
||||
* @param [IN] y 客户区纵坐标。
|
||||
* @param [IN] y 客户区纵坐标。
|
||||
* @return 落在菜单内返回 true。
|
||||
*/
|
||||
bool ContainsPoint(int x, int y) const;
|
||||
|
||||
/**
|
||||
* @brief 设置剪贴板所有者窗口句柄(供内联输入框复制/粘贴)。
|
||||
* @param [IN] host 宿主窗口句柄,允许为空。
|
||||
*/
|
||||
void SetHostWindow(HWND host) { m_host = host; }
|
||||
|
||||
/**
|
||||
* @brief 判断是否有菜单项正处于内联编辑状态。
|
||||
* @return 处于编辑状态返回 true。
|
||||
*/
|
||||
bool IsEditing() const { return m_editIndex >= 0; }
|
||||
|
||||
/**
|
||||
* @brief 获取当前正在编辑的菜单项命令标识。
|
||||
* @return 命令标识,未编辑时返回 0。
|
||||
*/
|
||||
int EditingItemId() const;
|
||||
|
||||
/**
|
||||
* @brief 判断坐标是否落在当前正在编辑的输入框内。
|
||||
* @param [IN] x 客户区横坐标。
|
||||
* @param [IN] y 客户区纵坐标。
|
||||
* @return 落在输入框内返回 true。
|
||||
*/
|
||||
bool IsOnEditField(int x, int y) const;
|
||||
|
||||
/**
|
||||
* @brief 编辑态下按下左键:定位插入符并开始拖拽框选。
|
||||
* @param [IN] x 客户区横坐标。
|
||||
* @param [IN] y 客户区纵坐标。
|
||||
* @return 命中输入框返回 true。
|
||||
*/
|
||||
bool OnEditMouseDown(int x, int y);
|
||||
|
||||
/**
|
||||
* @brief 编辑态下拖拽鼠标:扩展选区。
|
||||
* @param [IN] x 客户区横坐标。
|
||||
* @return 选区发生变化返回 true。
|
||||
*/
|
||||
bool OnEditMouseMove(int x);
|
||||
|
||||
/**
|
||||
* @brief 编辑态下松开左键:结束拖拽框选。
|
||||
* @return 之前处于拖拽中返回 true。
|
||||
*/
|
||||
bool OnEditMouseUp();
|
||||
|
||||
/**
|
||||
* @brief 编辑态下处理字符输入。
|
||||
* @param [IN] character 字符。
|
||||
* @param [OUT] result 提交时返回 editCommit 结果。
|
||||
* @return 需要重绘返回 true。
|
||||
*/
|
||||
bool OnChar(wchar_t character, MenuResult& result);
|
||||
|
||||
/**
|
||||
* @brief 更新指定命令项显示的值文本(菜单保持打开,立即重新排布)。
|
||||
* @param [IN] id 命令标识。
|
||||
* @param [IN] value 新的值文本。
|
||||
* @return 找到对应项并更新返回 true。
|
||||
*/
|
||||
bool UpdateItemValue(int id, const std::wstring& value);
|
||||
|
||||
/**
|
||||
* @brief 更新指定普通项的文字与可用/选中状态(用于实时反映状态)。
|
||||
* @param [IN] id 命令标识。
|
||||
* @param [IN] label 新的文字。
|
||||
* @param [IN] checked 新的选中状态。
|
||||
* @param [IN] enabled 新的可用状态。
|
||||
* @return 找到对应项并更新返回 true。
|
||||
*/
|
||||
bool UpdateItemLabel(int id, const std::wstring& label, bool checked = false, bool enabled = true);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief 计算单个菜单项的纵向高度。
|
||||
@@ -201,6 +280,38 @@ namespace jdi
|
||||
*/
|
||||
bool CommitHover(MenuResult& result);
|
||||
|
||||
/**
|
||||
* @brief 计算指定下标项的内联输入框矩形(EDIT 项)。
|
||||
* @param [IN] index 项目下标。
|
||||
* @return 输入框矩形,非法下标返回空矩形。
|
||||
*/
|
||||
gd::RectF EditFieldRect(int index) const;
|
||||
|
||||
/**
|
||||
* @brief 进入指定项的内联编辑状态。
|
||||
* @param [IN] index 项目下标。
|
||||
* @return 成功进入返回 true。
|
||||
*/
|
||||
bool BeginItemEdit(int index);
|
||||
|
||||
/**
|
||||
* @brief 结束内联编辑。
|
||||
* @param [IN] commit 是否提交(false 为放弃修改)。
|
||||
* @param [OUT] result 提交时输出 editCommit 结果。
|
||||
* @return 之前处于编辑状态返回 true。
|
||||
*/
|
||||
bool EndItemEdit(bool commit, MenuResult& result);
|
||||
|
||||
/**
|
||||
* @brief 依据当前项集合重新排布(用于值文本变化后)。
|
||||
*/
|
||||
void RebuildLayout();
|
||||
|
||||
/**
|
||||
* @brief 退出内联编辑状态(不产生任何结果)。
|
||||
*/
|
||||
void CloseEditState();
|
||||
|
||||
const UiFonts* m_fonts = nullptr; /**< 字体资源。 */
|
||||
const Theme* m_theme = nullptr; /**< 主题资源。 */
|
||||
float m_scale = 1.0f; /**< DPI 缩放比例。 */
|
||||
@@ -217,6 +328,14 @@ namespace jdi
|
||||
int m_hoverSwatch = -1; /**< 当前悬停色块。 */
|
||||
int m_pressedIndex = -1; /**< 按下时的项目下标。 */
|
||||
int m_pressedSwatch = -1; /**< 按下时的色块下标。 */
|
||||
|
||||
HWND m_host = nullptr; /**< 剪贴板所有者窗口句柄。 */
|
||||
TextEdit m_edit; /**< 内联输入框编辑模型。 */
|
||||
int m_editIndex = -1; /**< 正在编辑的项目下标,-1 表示未编辑。 */
|
||||
|
||||
gd::RectF m_buildBounds; /**< 最近一次排布使用的宿主矩形。 */
|
||||
int m_buildX = 0; /**< 最近一次排布使用的锚点横坐标。 */
|
||||
int m_buildY = 0; /**< 最近一次排布使用的锚点纵坐标。 */
|
||||
};
|
||||
|
||||
} // namespace jdi
|
||||
|
||||
Reference in new issue
Block a user