修复输入框全选高亮溢出、标签页重命名无法失焦、新增信号行删除按钮
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:
1 parent
18b8f3e38e
commit
a1e30985b8
7 files changed
+270
-11
No files matched your search
@@ -34,6 +34,7 @@ namespace jdi
|
||||
const int kMinClientWidth = 860; /**< 窗口最小客户区宽度。 */
|
||||
const int kMinClientHeight = 540; /**< 窗口最小客户区高度。 */
|
||||
const UINT kMessageRemoveFile = WM_APP + 1; /**< 面板请求移除文件的自定义消息。 */
|
||||
const UINT kMessageRemoveSignal = WM_APP + 2; /**< 面板请求移除单个信号的自定义消息。 */
|
||||
const UINT_PTR kHintTimerId = 1; /**< 提示浮层淡出用的定时器 ID。 */
|
||||
const UINT kHintTimerPeriodMs = 33; /**< 提示浮层淡出的重绘间隔(约 30fps)。 */
|
||||
|
||||
@@ -583,6 +584,39 @@ namespace jdi
|
||||
UpdateWindowTitle();
|
||||
}
|
||||
|
||||
void Application::RemoveSignal(int fileIndex, int signalIndex)
|
||||
{
|
||||
SignalRef target;
|
||||
target.fileIndex = fileIndex;
|
||||
target.signalIndex = signalIndex;
|
||||
|
||||
const SignalData* signal = m_dataSet.Resolve(target);
|
||||
const DataFile* file = m_dataSet.FileAt(fileIndex);
|
||||
if (signal == nullptr || file == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const std::wstring name = signal->Title();
|
||||
|
||||
if (file->signals.size() <= 1)
|
||||
{
|
||||
// 组内只剩这一条信号:直接移除整个分组,避免在列表里留下一个空分组。
|
||||
RemoveFile(fileIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
// 先按旧下标修正各标签页配置与共享选中项,再从数据层移除(释放采样内存),最后对齐。
|
||||
for (TabConfig& tab : m_tabs)
|
||||
{
|
||||
tab.RemapAfterSignalRemoval(fileIndex, signalIndex);
|
||||
}
|
||||
m_dataSet.RemapSelectionAfterSignalRemoval(fileIndex, signalIndex);
|
||||
m_dataSet.RemoveSignal(fileIndex, signalIndex);
|
||||
SyncTabsToDataSet();
|
||||
|
||||
SetStatusMessage(L"已从工作区移除信号:" + name, false);
|
||||
}
|
||||
|
||||
void Application::Relayout()
|
||||
{
|
||||
RECT client = {};
|
||||
@@ -2169,6 +2203,17 @@ namespace jdi
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 标签栏重命名处于编辑态时,点击输入框之外的**任何**位置都提交并退出编辑态。
|
||||
// (面板与绘图区的输入框会在各自的 OnLButtonDown 内部提交,但点击它们之外
|
||||
// 的区域时宿主根本不会把消息转给标签栏,重命名输入框会一直停留在编辑态。)
|
||||
if (m_tabBar.IsEditing())
|
||||
{
|
||||
TabBarResult renameResult;
|
||||
m_tabBar.OnEditKey(VK_RETURN, renameResult);
|
||||
OnTabBarResult(renameResult);
|
||||
InvalidateRect(hwnd, nullptr, FALSE);
|
||||
}
|
||||
|
||||
// 内联数值输入处于活动态时,点击绘图区之外视为提交(与线宽输入一致)。
|
||||
if (m_plot.IsEditing() && !m_plot.HitTest(x, y))
|
||||
{
|
||||
@@ -2590,6 +2635,12 @@ namespace jdi
|
||||
RemoveFile(static_cast<int>(wParam));
|
||||
return 0;
|
||||
}
|
||||
case kMessageRemoveSignal:
|
||||
{
|
||||
// wParam = 文件下标,lParam = 文件内信号下标。
|
||||
RemoveSignal(static_cast<int>(wParam), static_cast<int>(static_cast<LONG_PTR>(lParam)));
|
||||
return 0;
|
||||
}
|
||||
case WM_TIMER:
|
||||
{
|
||||
// 提示浮层淡出:仅重绘,不再做其它处理;Render 会在淡出结束后停表。
|
||||
|
||||
Reference in new issue
Block a user