修复输入框全选高亮溢出、标签页重命名无法失焦、新增信号行删除按钮

1. 内联输入框全选高亮越界(组名/标签页名/信号名编辑)
   UiFillRect 在不透明且面积 >= 20000 时走 GDI FillRect 快路径,而 GDI 填充不受
   GDI+ SetClip 约束;长文本全选时高亮宽度可达上千像素,于是画到输入框之外。
   UiDrawEditField 现在先把高亮矩形与裁剪区求交再填充。

2. 标签页重命名处于编辑态时,点击输入框之外的任何位置都不退出编辑
   Application 只在点击落在标签栏内时才把点击交给 TabBar。现在 WM_LBUTTONDOWN
   会先检查 m_tabBar.IsEditing(),是则提交(OnEditKey + OnTabBarResult)并退出编辑态,
   覆盖绘图区、信号面板、工具栏、分隔条等位置,且不会丢失新名字。

3. 信号选择区域每个信号新增 ✕ 删除按钮
   - 位置与所在组复选框同一列(垂直对齐),悬停显示手型光标并高亮。
   - 点击后面板向宿主发送 WM_APP+2;Application::RemoveSignal 会重映射所有标签页的
     可见性与网格引用、修正当前选中项,再真正从 DataSet 中删除该信号并释放采样内存;
     删除组内最后一个信号时退化为移除整个文件分组。
   - DataSet::RemoveSignal 采用移动填充 + shrink_to_fit,保证缓冲区内即刻析构。
This commit is contained in:
DeepSeek V4.1 Flash committed 2026-10-10 10:54:50 +08:00
1 parent 18b8f3e38e
commit a1e30985b8
7 files changed
+270 -11

No files matched your search

+33
View File
@@ -220,6 +220,26 @@ namespace jdi
*/
bool RemoveFile(int fileIndex);
/**
* @brief 从某个分组中移除一条信号,并立即释放它的采样内存。
*
* 该信号之后的所有信号下标整体前移一位,因此调用方必须紧接着对每个标签页调用
* `TabConfig::RemapAfterSignalRemoval()`,并用 `RemapSelectionAfterSignalRemoval()`
* 修正共享选中项。使用者一旦确认不再需要该信号即可调用,本调用后其采样缓冲立即析构。
*
* @param [IN] fileIndex 信号所属文件下标。
* @param [IN] signalIndex 文件内信号下标。
* @return 移除成功返回 true。
*/
bool RemoveSignal(int fileIndex, int signalIndex);
/**
* @brief 在数据层移除某条信号之前,按旧下标修正选中引用。
* @param [IN] fileIndex 信号所属文件下标。
* @param [IN] signalIndex 即将被移除的信号下标。
*/
void RemapSelectionAfterSignalRemoval(int fileIndex, int signalIndex);
/**
* @brief 判断数据集合是否为空。
* @return 未加载任何文件返回 true。
@@ -486,6 +506,19 @@ namespace jdi
*/
void RemapAfterFileRemoval(int fileIndex);
/**
* @brief 在数据层移除某条信号之前,按旧下标修正本配置(不重建网格)。
*
* 会删除该信号的可见性记录与网格归属,并把同一文件内位于其后的引用下标前移一位。
* 若某个网格因此变空则一并移除(与“取消勾选后空网格消失”的策略一致)。
*
* @param [IN] fileIndex 信号所属文件下标。
* @param [IN] signalIndex 即将被移除的信号下标。
* @note 调用顺序必须为:各标签页 RemapAfterSignalRemoval → 数据层修正选中 →
* 数据层 RemoveSignal → 各标签页 SyncToDataSet。
*/
void RemapAfterSignalRemoval(int fileIndex, int signalIndex);
/**
* @brief 判断指定信号是否可见。
* @param [IN] ref 信号引用。