fix: 修正滑块填充残留、数值内联输入与信号/分组重命名,拖拽虚影跟随鼠标

- 滑块最小值时不再有超出圆钮的填充残留,三处滑块统一为共享实现
- 透明度/RGB/色号支持点击或双击直接输入,整段高亮、首次键入替换、回车提交、Ctrl+C 复制
- 双击信号行或分组名进入重命名编辑;分组竖线改为绘制而非字符
- 拖拽信号时曲线虚影跟随鼠标纵向位移
- 数据层新增展示名覆盖,面板改为持有可写数据集合
This commit is contained in:
DeepSeek V4.1 Flash committed 2026-09-30 09:38:22 +08:00
1 parent 542aa51e40
commit 261b8ac07d
13 files changed
+1074 -274

No files matched your search

+65 -44
View File
@@ -1185,6 +1185,7 @@ namespace jdi
{
const int target = LaneAtY(y);
m_dragMoved = true;
m_dragMouseY = y;
if (target != m_dragTargetLane)
{
m_dragTargetLane = target;
@@ -1883,7 +1884,7 @@ namespace jdi
std::wstring label = BuildLegendText(*resolved.data);
if (multiFile && resolved.file != nullptr)
{
label += L" · " + resolved.file->fileName;
label += L" · " + resolved.file->Title();
}
const float itemWidth = 13.0f * m_scale + UiTextWidth(g, label, m_fonts->uiSmall) +
14.0f * m_scale;
@@ -1915,7 +1916,7 @@ namespace jdi
std::wstring label = BuildLegendText(*resolved.data);
if (multiFile && resolved.file != nullptr)
{
label += L" · " + resolved.file->fileName;
label += L" · " + resolved.file->Title();
}
const float textWidth = UiTextWidth(g, label, m_fonts->uiSmall);
const float itemWidth = 13.0f * m_scale + textWidth + 14.0f * m_scale;
@@ -1992,10 +1993,10 @@ namespace jdi
}
ReadoutLine line;
line.text = resolved.data->name;
line.text = resolved.data->Title();
if (multiFile)
{
line.text += L" · " + resolved.file->fileName;
line.text += L" · " + resolved.file->Title();
}
line.text += L" = " + FormatValue(value);
lines.push_back(std::move(line));
@@ -2226,55 +2227,75 @@ namespace jdi
return;
}
// 拖拽中:在目标网格内以虚线绘制该信号的“虚影”,并高亮目标网格。
// 拖拽中:虚影跟随鼠标纵向位移,同时在目标网格内高亮落点。
if (m_dragMode == PlotDragMode::MOVE_SIGNAL && m_dragSignal.IsValid())
{
const int target = (m_dragTargetLane >= 0) ? m_dragTargetLane : m_tab->LaneOfSignal(m_dragSignal);
const ResolvedSignal resolved = ResolveSignal(m_dragSignal);
const int sourceLane = m_tab->LaneOfSignal(m_dragSignal);
if (resolved.data == nullptr || resolved.style == nullptr || sourceLane < 0 ||
sourceLane >= static_cast<int>(m_lanes.size()))
{
return;
}
// 虚影:以源网格的幅值映射构建波形,并整体平移跟随鼠标,形成“拖着曲线走”的观感。
LaneVisual ghostLane = m_lanes[static_cast<std::size_t>(sourceLane)];
const float follow = static_cast<float>(m_dragMouseY - m_dragStartY);
ghostLane.rect.Y += follow;
{
const float clipTop = std::max(m_plotRect.Y, m_plotRect.Y);
const float clipHeight = m_plotRect.Height;
const int saveState = g.Save();
g.SetClip(gd::RectF(m_plotRect.X, clipTop, m_plotRect.Width, clipHeight),
gd::CombineModeIntersect);
std::vector<gd::PointF> points;
std::vector<std::size_t> breaks;
BuildPolyline(resolved, ghostLane, points, breaks);
gd::Pen ghost(ToGdiColor(WithAlpha(m_theme->accent, 0xC0)),
std::max(1.8f, resolved.style->lineWidth) * m_scale);
ghost.SetDashStyle(gd::DashStyleDash);
ghost.SetStartCap(gd::LineCapRound);
ghost.SetEndCap(gd::LineCapRound);
for (std::size_t k = 0; k < breaks.size(); ++k)
{
const std::size_t start = breaks[k];
const std::size_t stop = (k + 1 < breaks.size()) ? breaks[k + 1] : points.size();
if (stop <= start + 1)
{
continue;
}
g.DrawLines(&ghost, points.data() + start, static_cast<INT>(stop - start));
}
g.Restore(saveState);
}
// 落点提示:高亮鼠标所在网格并给出文字说明。
const int target = (m_dragTargetLane >= 0) ? m_dragTargetLane : sourceLane;
if (target >= 0 && target < static_cast<int>(m_lanes.size()))
{
const LaneVisual& lane = m_lanes[static_cast<std::size_t>(target)];
const ResolvedSignal resolved = ResolveSignal(m_dragSignal);
if (resolved.data != nullptr && resolved.style != nullptr)
const gd::RectF& targetRect = m_lanes[static_cast<std::size_t>(target)].rect;
const float visibleTop = std::max(targetRect.Y, m_plotRect.Y);
const float visibleBottom = std::min(targetRect.Y + targetRect.Height,
m_plotRect.Y + m_plotRect.Height);
if (visibleBottom > visibleTop)
{
const int saveState = g.Save();
g.SetClip(gd::RectF(m_plotRect.X, std::max(lane.rect.Y, m_plotRect.Y), m_plotRect.Width,
std::min(lane.rect.Y + lane.rect.Height,
m_plotRect.Y + m_plotRect.Height) -
std::max(lane.rect.Y, m_plotRect.Y)),
gd::CombineModeIntersect);
// 目标网格边框高亮。
gd::Pen frame(ToGdiColor(m_theme->accent), 2.0f);
g.DrawRectangle(&frame, lane.rect.X, lane.rect.Y, lane.rect.Width, lane.rect.Height);
g.DrawRectangle(&frame, targetRect.X, visibleTop, targetRect.Width,
visibleBottom - visibleTop);
std::vector<gd::PointF> points;
std::vector<std::size_t> breaks;
BuildPolyline(resolved, lane, points, breaks);
gd::Pen ghost(ToGdiColor(WithAlpha(m_theme->accent, 0xB0)),
std::max(1.6f, resolved.style->lineWidth) * m_scale);
ghost.SetDashStyle(gd::DashStyleDash);
for (std::size_t k = 0; k < breaks.size(); ++k)
{
const std::size_t start = breaks[k];
const std::size_t stop = (k + 1 < breaks.size()) ? breaks[k + 1] : points.size();
if (stop <= start + 1)
{
continue;
}
g.DrawLines(&ghost, points.data() + start, static_cast<INT>(stop - start));
}
g.Restore(saveState);
// 目标网格名称提示。
const std::wstring hint =
L"移动到网格 " + std::to_wstring(target + 1) + L":松开左键确认";
const std::wstring hint = (target == sourceLane)
? std::wstring(L"松开左键放回本网格")
: (L"移动到网格 " + std::to_wstring(target + 1) +
L":松开左键确认");
const float textWidth = UiTextWidth(g, hint, m_fonts->uiSmall) + 16.0f * m_scale;
const float height = 20.0f * m_scale;
float left = lane.rect.X + (lane.rect.Width - textWidth) * 0.5f;
float left = targetRect.X + (targetRect.Width - textWidth) * 0.5f;
left = std::max(m_plotRect.X, std::min(left, m_plotRect.X + m_plotRect.Width - textWidth));
const gd::RectF pill(left, lane.rect.Y + 4.0f * m_scale, textWidth, height);
const gd::RectF pill(left, visibleTop + 4.0f * m_scale, textWidth, height);
UiFillRoundRect(g, pill, 3.0f * m_scale, m_theme->accent);
UiText(g, hint, m_fonts->uiSmall, pill, m_theme->textOnAccent, TextAlign::CENTER);
}
@@ -2299,7 +2320,7 @@ namespace jdi
}
const LaneVisual& lane = m_lanes[static_cast<std::size_t>(laneIndex)];
const std::wstring text = resolved.data->name + L" · 按住拖拽可移入其它网格";
const std::wstring text = resolved.data->Title() + L" · 按住拖拽可移入其它网格";
const float textWidth = UiTextWidth(g, text, m_fonts->uiSmall) + 16.0f * m_scale;
const float height = 20.0f * m_scale;