feat(clip): 新增「选区截取」实验性功能 + 筛选态组复选框只作用于筛选结果 + 重采样统计不被省略
一、重采样面板统计信息不再被省略为 `…`
- 根因:EdgePanelWidth 里数值列按"典型样例"(1h 1min 2s(1.23456 GHz))估宽,
真实文本(16ms 182.614us(61.795 Hz))更长 => 绘制矩形不够宽 => 尾部被裁。
- 新增 FormatIntervalWithFrequency() 作为「间隔(频率)」文本的唯一实现,
宽度计算与绘制共用它;EdgePanelWidth 改为逐信号实测真实文本宽度取最大值。
二、筛选状态下组复选框只作用于「筛选出来的信号」
- TabConfig 新增 SetGroupVisibleSubset / GroupAllVisibleSubset / GroupHasVisibleSubset,
只读写掩码内元素,未通过筛选的信号可见性保持不变。
- SignalPanel::BuildFilterMask 提供逐信号掩码(未筛选时返回 false,走整组语义)。
- 组复选框的点击、绘制、行位图缓存键三处统一改用子集判定
(只改绘制不改缓存键会导致勾选后复选框不刷新)。
三、新增实验性功能「选区截取」(EdgePanelKind::CLIP = 6,PLOT_CMD_LANE_CLIP = 14)
- 菜单位置:实验性功能二级菜单,「重采样」之下、「自由标记」上方,带勾选。
- 面板:逐信号一行(信号色叠底条目栏 + 右侧复选框,不可展开),内容可滚动;
底部两个不滚动的按钮「截取为新信号」与「原始信号截取」;
未启用双光标时两个按钮为空矩形并给出提示。
- 截取为新信号:区间内原始数据(不烘焙)+ 继承源信号整套调整,
名称为 <源信号名> (AAAA - BBBB)(显示时刻、保留三位小数、带 s),插入源信号下方,
使用 AppendGroupAxis 新建的独立时间轴。
- 原始信号截取:DataSet::ClipSignalRange 就地裁剪时间轴与采样,
用新建+swap+shrink_to_fit 真正归还内存,并重算统计与轴的 minTime/maxTime/monotonic。
调用前先 PauseDerivedAsync() 避免后台派生读到已释放采样。
- 时间轴偏移参与区间比较:双光标是显示时刻(time+offsetTime),
BuildClippedSignal 比较时加偏移,ClipSignalInPlace 换算回采样时刻(low-offsetTime)。
- 同步点已全部补齐:LaneCarry(三处)/SplitLane/PruneLaneSignalItems/RemapAfterSignalInsert/
purgeRefs/PanelSlotKey/CollectDebugBoxes/SceneContentHash/kEdgePanelKinds/kOrder/
EdgePanelLayoutFor/EDGE_PANEL_MOVE/m_pendingPanelClose/MEAN_SCROLL/滚轮/悬停/
SetLanePanelCollapsed/LanePanelCollapsed/QueryCursor。
make release 零 warning,产物 860,160 B。
This commit is contained in:
1 parent
5d305cb10f
commit
62220477c0
18 files changed
+1263
-67
No files matched your search
@@ -1990,6 +1990,115 @@ namespace jdi
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================ 「选区截取」 ============================
|
||||
|
||||
bool PlotView::SetLaneClip(int laneIndex, bool enabled)
|
||||
{
|
||||
if (m_tab == nullptr || laneIndex < 0 || laneIndex >= static_cast<int>(m_tab->Lanes().size()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Lane& lane = m_tab->Lanes()[static_cast<std::size_t>(laneIndex)];
|
||||
if (lane.clip == enabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
lane.clip = enabled;
|
||||
if (enabled)
|
||||
{
|
||||
// 默认只勾选网格内**第一个可见信号**(与其它实验性功能一致)。
|
||||
if (lane.clipItems.empty())
|
||||
{
|
||||
for (const SignalRef& ref : lane.signals)
|
||||
{
|
||||
const ResolvedSignal resolved = ResolveSignal(ref);
|
||||
if (resolved.data != nullptr && resolved.visible)
|
||||
{
|
||||
lane.EnsureClipItem(ref);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
lane.clipPanel.open = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
lane.clipPanel.open = false;
|
||||
}
|
||||
EnsureLaneLayersPrefetched();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlotView::LaneClip(int laneIndex) const
|
||||
{
|
||||
if (m_tab == nullptr || laneIndex < 0 || laneIndex >= static_cast<int>(m_tab->Lanes().size()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return m_tab->Lanes()[static_cast<std::size_t>(laneIndex)].clip;
|
||||
}
|
||||
|
||||
bool PlotView::ToggleLaneClip(int laneIndex)
|
||||
{
|
||||
const bool enabled = !LaneClip(laneIndex);
|
||||
SetLaneClip(laneIndex, enabled);
|
||||
return enabled;
|
||||
}
|
||||
|
||||
bool PlotView::ToggleLaneClipSignal(int laneIndex, const SignalRef& ref)
|
||||
{
|
||||
if (m_tab == nullptr || laneIndex < 0 || laneIndex >= static_cast<int>(m_tab->Lanes().size()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Lane& lane = m_tab->Lanes()[static_cast<std::size_t>(laneIndex)];
|
||||
if (lane.ClipEnabled(ref))
|
||||
{
|
||||
lane.RemoveClipItem(ref);
|
||||
return false;
|
||||
}
|
||||
lane.EnsureClipItem(ref);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlotView::LaneClipSignalEnabled(int laneIndex, const SignalRef& ref) const
|
||||
{
|
||||
if (m_tab == nullptr || laneIndex < 0 || laneIndex >= static_cast<int>(m_tab->Lanes().size()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return m_tab->Lanes()[static_cast<std::size_t>(laneIndex)].ClipEnabled(ref);
|
||||
}
|
||||
|
||||
bool PlotView::SetLaneClipScroll(int laneIndex, float scroll)
|
||||
{
|
||||
if (m_tab == nullptr || laneIndex < 0 || laneIndex >= static_cast<int>(m_tab->Lanes().size()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Lane& lane = m_tab->Lanes()[static_cast<std::size_t>(laneIndex)];
|
||||
const float clamped = std::max(0.0f, scroll);
|
||||
if (std::fabs(lane.clipScroll - clamped) < 0.5f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
lane.clipScroll = clamped;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlotView::TakePendingClipBuild(int& laneIndex, std::vector<ClipBuild>& items)
|
||||
{
|
||||
if (m_pendingClipLane < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
laneIndex = m_pendingClipLane;
|
||||
items = m_pendingClipItems;
|
||||
m_pendingClipLane = -1;
|
||||
m_pendingClipItems.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PlotView::SetLaneEdgeCenterScroll(int laneIndex, float scroll) {
|
||||
if (m_tab == nullptr || laneIndex < 0 || laneIndex >= static_cast<int>(m_tab->Lanes().size()))
|
||||
@@ -2098,6 +2207,9 @@ namespace jdi
|
||||
case EdgePanelKind::RESAMPLE:
|
||||
state = &lane.resamplePanel;
|
||||
break;
|
||||
case EdgePanelKind::CLIP:
|
||||
state = &lane.clipPanel;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -2130,6 +2242,8 @@ namespace jdi
|
||||
return lane.freeMarkerPanel.collapsed;
|
||||
case EdgePanelKind::RESAMPLE:
|
||||
return lane.resamplePanel.collapsed;
|
||||
case EdgePanelKind::CLIP:
|
||||
return lane.clipPanel.collapsed;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user