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:
1 parent
53768b8b25
commit
e3744f3eff
16 files changed
+462
-340
No files matched your search
@@ -20,6 +20,8 @@ namespace jdi
|
||||
const float kAddGap = 6.0f; /**< 新建按钮与末个标签的间距。 */
|
||||
const float kCorner = 5.0f; /**< 标签圆角半径。 */
|
||||
const float kMaxTabWidth = 200.0f; /**< 单个标签最大宽度(逻辑像素)。 */
|
||||
const float kEditingTabWidth = 320.0f; /**< 重命名输入时标签的最大宽度(便于看清长名称)。 */
|
||||
const float kMinTabWidth = 70.0f; /**< 单个标签最小宽度(逻辑像素)。 */
|
||||
}
|
||||
|
||||
TabBar::TabBar() = default;
|
||||
@@ -72,16 +74,50 @@ namespace jdi
|
||||
const float tabHeight = kTabHeight * m_scale;
|
||||
const float top = area.Y + kTopMargin * m_scale;
|
||||
const float closeSize = kCloseSize * m_scale;
|
||||
const float maxWidth = kMaxTabWidth * m_scale;
|
||||
const float minWidth = 70.0f * m_scale;
|
||||
const float minWidth = kMinTabWidth * m_scale;
|
||||
const float addSize = kAddSize * m_scale;
|
||||
|
||||
float cursorX = area.X + kLeftPadding * m_scale;
|
||||
|
||||
for (TabItem& tab : m_tabs)
|
||||
// 标签宽度按「加粗字体」测量:激活页用 uiBold 绘制,
|
||||
// 若按常规字体测量,加粗后的长名称会在激活时被省略号截断(预览过短)。
|
||||
std::vector<float> desired;
|
||||
desired.reserve(m_tabs.size());
|
||||
float total = kLeftPadding * m_scale;
|
||||
for (std::size_t index = 0; index < m_tabs.size(); ++index)
|
||||
{
|
||||
const float textWidth = UiMeasureTextWidth(m_fonts->ui, tab.name);
|
||||
const bool editing = (static_cast<int>(index) == m_editIndex);
|
||||
|
||||
// 重命名过程中按「正在输入的文本」测量,标签才能随输入逐步变宽;
|
||||
// 否则始终按已提交的旧名称算宽度,长名称会被挤成很短的一截(预览过短)。
|
||||
const std::wstring& measureText = editing ? m_edit.Text() : m_tabs[index].name;
|
||||
const float boldWidth = UiMeasureTextWidth(m_fonts->uiBold, measureText);
|
||||
const float regularWidth = UiMeasureTextWidth(m_fonts->ui, measureText);
|
||||
const float textWidth = std::max(boldWidth, regularWidth);
|
||||
|
||||
const float maxWidth = (editing ? kEditingTabWidth : kMaxTabWidth) * m_scale;
|
||||
|
||||
float width = kTabPadding * 2.0f * m_scale + textWidth + kCloseGap * m_scale + closeSize;
|
||||
width = std::max(minWidth, std::min(width, maxWidth));
|
||||
desired.push_back(width);
|
||||
total += width + kAddGap * m_scale;
|
||||
}
|
||||
total += addSize;
|
||||
|
||||
// 标签总宽超出可用宽度时整体等比收缩,保证「+」按钮始终可见。
|
||||
const float available = area.Width - kLeftPadding * m_scale;
|
||||
float shrink = 1.0f;
|
||||
if (total > available && total > 0.0f)
|
||||
{
|
||||
shrink = available / total;
|
||||
}
|
||||
|
||||
float cursorX = area.X + kLeftPadding * m_scale;
|
||||
for (std::size_t index = 0; index < m_tabs.size(); ++index)
|
||||
{
|
||||
TabItem& tab = m_tabs[index];
|
||||
float width = std::max(minWidth * shrink, desired[index] * shrink);
|
||||
|
||||
// 收缩后仍要保证「文本 + 关闭按钮」有最小可用空间。
|
||||
width = std::max(width, closeSize + kTabPadding * m_scale + 8.0f * m_scale);
|
||||
|
||||
tab.rect = gd::RectF(cursorX, top, width, tabHeight);
|
||||
tab.closeRect = gd::RectF(cursorX + width - kTabPadding * m_scale - closeSize,
|
||||
@@ -90,8 +126,8 @@ namespace jdi
|
||||
cursorX += width + kAddGap * m_scale;
|
||||
}
|
||||
|
||||
const float addSize = kAddSize * m_scale;
|
||||
m_addRect = gd::RectF(cursorX, top + (tabHeight - addSize) * 0.5f, addSize, addSize);
|
||||
m_addRect = gd::RectF(std::min(cursorX, area.X + area.Width - addSize - 2.0f * m_scale),
|
||||
top + (tabHeight - addSize) * 0.5f, addSize, addSize);
|
||||
}
|
||||
|
||||
void TabBar::Paint(gd::Graphics& g)
|
||||
@@ -421,15 +457,8 @@ namespace jdi
|
||||
OnEditKey(VK_RETURN, result);
|
||||
return true;
|
||||
}
|
||||
if (character == L'\b')
|
||||
{
|
||||
return m_edit.Backspace();
|
||||
}
|
||||
if (character == 0x7F)
|
||||
{
|
||||
return m_edit.DeleteForward();
|
||||
}
|
||||
if (character < L' ')
|
||||
// 退格/删除已由 WM_KEYDOWN 的 OnEditKey 处理,此处忽略全部控制字符。
|
||||
if (character < L' ' || character == 0x7F)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -491,6 +520,15 @@ namespace jdi
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TabBar::CollapseEditSelectionToEnd()
|
||||
{
|
||||
if (m_editIndex < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return m_edit.DeselectToEnd();
|
||||
}
|
||||
|
||||
bool TabBar::OnRButtonDown(int x, int y, int screenX, int screenY, TabBarResult& result)
|
||||
{
|
||||
result = TabBarResult();
|
||||
|
||||
Reference in new issue
Block a user