fix: 统一输入框编辑行为、外观跨视图同步并优化标尺与网格可读性

输入框(TextEdit,全组件共用):
- 修复退格一次删除两个字符:WM_CHAR 与 WM_KEYDOWN 重复处理了退格/删除,
  现统一由 OnEditKey 处理,WM_CHAR 忽略全部控制字符。
- 进入编辑(整段选中)后按右键:取消全选并把插入符移到文本最右侧。
- 存在选区时松开 Shift 再按左右方向键,插入符收拢到选区的左/右端。
- 修复整段选中后按 Home/End 不收拢选区的问题。

标签页:
- 按加粗字体测量宽度,避免激活页长名称被提前省略(预览过短)。
- 重命名过程中按正在输入的文本测量并加宽上限(320px),标签随输入增长,
  解决长内容绘制错误;输入溢出时整体等比收缩,保证「+」始终可见。

信号显示外观跨标签页同步:
- 外观(颜色/自定义色记忆/透明度/线宽/样式)从 TabConfig 上移到 DataSet
  的 SignalData,成为信号的全局属性;可见性仍按标签页独立保存。
- 因此任一视图中修改某信号的颜色/线宽/透明度/样式,其它视图自动一致。

工具栏:
- 移除「全选信号」按钮;「清空勾选」改为「清空网格」,
  「拆分信号网格」改为「拆分网格」。

自适应:
- 无可见信号(未勾选/全部取消/清空网格)时复位 ViewInitialized,
  下次勾选第一个信号会重新自适应,而不是停留在旧视图范围。

绘图区标尺与网格:
- 幅值刻度密度按网格高度自适应(3-8 档),各网格刻度数量一致;
  网格较矮时同步收紧标签行距,提高可读密度。
- 网格线与五等分估读线加深,与网格边界(蓝灰)保持明显区分。
- 时间轴列名补上单位,显示为 time (s)。
This commit is contained in:
DeepSeek V4.1 Flash committed 2026-09-30 15:16:53 +08:00
1 parent 53768b8b25
commit e3744f3eff
16 files changed
+462 -340

No files matched your search

+6
View File
@@ -118,6 +118,12 @@ namespace jdi
*/
bool IsEditing() const { return m_editField != EditField::NONE; }
/**
* @brief 编辑态下按下鼠标右键:取消选区并把插入符移到文本末尾。
* @return 发生改变返回 true;不在编辑态返回 false。
*/
bool CollapseEditSelectionToEnd();
/**
* @brief 设置剪贴板所有者窗口句柄(用于输入框的复制/粘贴)。
* @param [IN] owner 宿主窗口句柄,允许为空。
+37 -38
View File
@@ -81,7 +81,23 @@ namespace jdi
};
/**
* @brief 单条信号的元数据与采样值(纯数据,不含显示配置)。
* @brief 单个信号的显示外观(颜色/透明度/线宽/绘制方式)。
*
* 外观属于信号自身而非某个标签页——同一信号在所有标签页中必须显示效果一致,
* 因此在任一视图里修改颜色/线宽/透明度/样式,其它视图会自动同步。
* 信号是否可见则属于各标签页自己的配置(见 `TabConfig`)。
*/
struct SignalStyle
{
std::uint32_t color = 0xFF268BD2; /**< 波形颜色,格式 0xAARRGGBB。 */
std::uint32_t customColor = 0xFF6C71C4; /**< 自定义颜色记忆值(切换预设色后仍保留)。 */
float opacity = 1.0f; /**< 不透明度,取值 0.0-1.0,默认 1.0。 */
float lineWidth = 1.6f; /**< 线宽(逻辑像素,未乘 DPI 缩放)。 */
DrawMode mode = DrawMode::LINE; /**< 绘制方式。 */
};
/**
* @brief 单条信号的元数据与采样值(纯数据,不含可见性配置)。
*/
struct SignalData
{
@@ -93,6 +109,7 @@ namespace jdi
double minValue = 0.0; /**< 有限采样值最小值。 */
double maxValue = 0.0; /**< 有限采样值最大值。 */
std::size_t finiteCount = 0; /**< 有限采样点数量。 */
SignalStyle style; /**< 显示外观(全局共享,跨标签页同步)。 */
/**
* @brief 获取用于界面展示的名称。
@@ -206,6 +223,20 @@ namespace jdi
*/
const SignalData* Resolve(const SignalRef& ref) const;
/**
* @brief 获取指定信号的显示外观(只读)。
* @param [IN] ref 信号引用。
* @return 外观指针,引用无效时返回 nullptr。
*/
const SignalStyle* Style(const SignalRef& ref) const;
/**
* @brief 获取指定信号的显示外观(可写)。
* @param [IN] ref 信号引用。
* @return 外观指针,引用无效时返回 nullptr。
*/
SignalStyle* Style(const SignalRef& ref);
/**
* @brief 计算全部文件时间范围的并集下限。
* @return 时间下限。
@@ -222,19 +253,6 @@ namespace jdi
std::vector<DataFile> m_files; /**< 已加载文件集合。 */
};
/**
* @brief 单个信号的显示配置(属于某个标签页)。
*/
struct SignalStyle
{
bool visible = false; /**< 是否参与绘制。默认关闭,由用户自行勾选。 */
std::uint32_t color = 0xFF268BD2; /**< 波形颜色,格式 0xAARRGGBB。 */
std::uint32_t customColor = 0xFF6C71C4; /**< 自定义颜色记忆值(切换预设色后仍保留)。 */
float opacity = 1.0f; /**< 不透明度,取值 0.0-1.0,默认 1.0。 */
float lineWidth = 1.6f; /**< 线宽(逻辑像素,未乘 DPI 缩放)。 */
DrawMode mode = DrawMode::LINE; /**< 绘制方式。 */
};
/**
* @brief 一个波形网格(纵向泳道),可容纳多条信号叠加显示。
*/
@@ -267,7 +285,10 @@ namespace jdi
int FindNearestSample(const DataFile& file, double time);
/**
* @brief 单个标签页的独立视图配置(信号可见性、样式、网格划分与视图范围)。
* @brief 单个标签页的独立视图配置(信号可见性、网格划分与视图范围)。
*
* 仅保存「本页看到哪些信号」与视图状态;信号的显示外观(颜色/线宽/透明度/样式)
* 保存在 `DataSet` 中并被所有标签页共享,因此同一个信号在各视图中的显示效果一致。
*/
class TabConfig
{
@@ -299,20 +320,6 @@ namespace jdi
*/
void RemapAfterFileRemoval(int fileIndex);
/**
* @brief 获取指定信号的显示配置(只读)。
* @param [IN] ref 信号引用。
* @return 配置指针,引用无效时返回 nullptr。
*/
const SignalStyle* Style(const SignalRef& ref) const;
/**
* @brief 获取指定信号的显示配置(可写)。
* @param [IN] ref 信号引用。
* @return 配置指针,引用无效时返回 nullptr。
*/
SignalStyle* Style(const SignalRef& ref);
/**
* @brief 判断指定信号是否可见。
* @param [IN] ref 信号引用。
@@ -501,16 +508,8 @@ namespace jdi
PlotZoomMode ZoomMode() const { return m_zoomMode; }
private:
/**
* @brief 为新增信号补默认样式(含调色板取色)。
* @param [IN] dataSet 数据集合。
* @param [IN] fileIndex 文件下标。
* @param [IN] signalIndex 信号下标。
*/
void EnsureStyle(const DataSet& dataSet, int fileIndex, int signalIndex);
std::wstring m_name; /**< 标签页名称。 */
std::vector<std::vector<SignalStyle>> m_styles; /**< 显示配置,按 [文件][信号] 索引。 */
std::vector<std::vector<bool>> m_visible; /**< 信号可见性,按 [文件][信号] 索引(本页独立)。 */
std::vector<bool> m_collapsed; /**< 文件分组折叠状态,按文件索引。 */
std::vector<Lane> m_lanes; /**< 网格划分。 */
LaneMode m_laneMode = LaneMode::PER_SIGNAL; /**< 网格划分策略。 */
+6
View File
@@ -138,6 +138,12 @@ namespace jdi
*/
void SelectAll();
/**
* @brief 取消选区并把插入符移动到文本末尾(模拟在输入框右侧按下鼠标)。
* @return 光标或选区发生变化返回 true。
*/
bool DeselectToEnd();
/**
* @brief 复制当前内容到剪贴板(存在选区时只复制选区)。
* @param [IN] owner 剪贴板所有者窗口句柄,允许为空。