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
@@ -127,7 +127,8 @@ namespace jdi
|
||||
PLOT_CMD_LANE_MEAN_FILTER = 10, /**< 切换本网格的「实验性功能 → 均值滤波」开关。 */
|
||||
PLOT_CMD_LANE_WEAK_PEAK = 11, /**< 切换本网格的「实验性功能 → 弱峰调整」开关。 */
|
||||
PLOT_CMD_LANE_FREE_MARKER = 12, /**< 切换本网格的「实验性功能 → 自由标记」开关。 */
|
||||
PLOT_CMD_LANE_RESAMPLE = 13 /**< 切换本网格的「实验性功能 → 重采样」开关。 */
|
||||
PLOT_CMD_LANE_RESAMPLE = 13, /**< 切换本网格的「实验性功能 → 重采样」开关。 */
|
||||
PLOT_CMD_LANE_CLIP = 14 /**< 切换本网格的「实验性功能 → 选区截取」开关。 */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -140,7 +141,8 @@ namespace jdi
|
||||
MEAN = 2, /**< 均值滤波。 */
|
||||
PEAK = 3, /**< 弱峰调整。 */
|
||||
MARK = 4, /**< 自由标记。 */
|
||||
RESAMPLE = 5 /**< 重采样(把非固定频率采样规整为固定频率)。 */
|
||||
RESAMPLE = 5, /**< 重采样(把非固定频率采样规整为固定频率)。 */
|
||||
CLIP = 6 /**< 选区截取(按双光标区间截取信号,必须配合双光标使用)。 */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1087,6 +1089,51 @@ namespace jdi
|
||||
*/
|
||||
bool SignalDataInterval(const SignalRef& ref, double& maxInterval, double& minInterval) const;
|
||||
|
||||
// ------------------------------------------------------------------ 选区截取
|
||||
/**
|
||||
* @brief 「选区截取」的单个请求(一个被勾选的信号 + 截取区间 + 是否破坏原信号)。
|
||||
*/
|
||||
struct ClipBuild
|
||||
{
|
||||
int groupIndex = -1; /**< 信号所属分组下标。 */
|
||||
int signalIndex = -1; /**< 组内信号下标。 */
|
||||
double begin = 0.0; /**< 截取区间左端(显示时刻,秒)。 */
|
||||
double end = 0.0; /**< 截取区间右端(显示时刻,秒)。 */
|
||||
/** @brief `true` = 破坏性截取原始信号;`false` = 插到源信号下方的派生信号。 */
|
||||
bool destructive = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 取出「选区截取」请求(由面板底部两个按钮触发)。
|
||||
* @param [OUT] laneIndex 触发该请求的网格下标。
|
||||
* @param [OUT] items 需要截取的信号及其区间。
|
||||
* @return 存在待处理请求返回 true(取出后清空)。
|
||||
*/
|
||||
bool TakePendingClipBuild(int& laneIndex, std::vector<ClipBuild>& items);
|
||||
|
||||
/**
|
||||
* @brief 开启 / 关闭某网格的「选区截取」功能。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @param [IN] enabled 是否开启。
|
||||
* @return 状态发生变化返回 true。
|
||||
*/
|
||||
bool SetLaneClip(int laneIndex, bool enabled);
|
||||
|
||||
/** @brief 查询某网格的「选区截取」开关。 */
|
||||
bool LaneClip(int laneIndex) const;
|
||||
|
||||
/** @brief 切换某网格的「选区截取」开关(右键菜单用)。 */
|
||||
bool ToggleLaneClip(int laneIndex);
|
||||
|
||||
/** @brief 切换某信号是否为选区截取的目标(面板条目栏右侧复选框)。 */
|
||||
bool ToggleLaneClipSignal(int laneIndex, const SignalRef& ref);
|
||||
|
||||
/** @brief 查询某信号是否为选区截取的目标。 */
|
||||
bool LaneClipSignalEnabled(int laneIndex, const SignalRef& ref) const;
|
||||
|
||||
/** @brief 设置「选区截取」面板内容的滚动偏移(自动夹到合法范围)。 */
|
||||
bool SetLaneClipScroll(int laneIndex, float scroll);
|
||||
|
||||
/**
|
||||
* @brief 设置某网格是否处于「自由标记点选取」(浮动面板底部的切换按钮)。
|
||||
*
|
||||
@@ -2119,6 +2166,17 @@ namespace jdi
|
||||
gd::RectF showDelta;
|
||||
/** @brief 「显示枚举文本」开关按钮(同一行的右半)。 */
|
||||
gd::RectF showEnum;
|
||||
/**
|
||||
* @brief 「选区截取」底部的两个固定按钮(**不参与滚动**)。
|
||||
*
|
||||
* `clipBuildButton` = 「截取为新信号」(在源信号下方插入派生信号);
|
||||
* `clipDestructiveButton` = 「原始信号截取」(破坏性截取,丢弃区间外的采样)。
|
||||
* 未启用双光标模式时两者都是空矩形(不可点)。
|
||||
*/
|
||||
gd::RectF clipBuildButton;
|
||||
gd::RectF clipDestructiveButton;
|
||||
/** @brief 「选区截取」需要双光标时的提示文案矩形(未启用双光标时使用)。 */
|
||||
gd::RectF clipHint;
|
||||
/**
|
||||
* @brief 「自由标记」:每个信号名右侧的「清除该信号全部固定点」✕。
|
||||
*
|
||||
@@ -3015,6 +3073,9 @@ namespace jdi
|
||||
std::vector<WeakPeakBuild> m_pendingWeakPeakItems; /**< 待构建的弱峰调整信号及其参数。 */
|
||||
int m_pendingResampleLane = -1; /**< 待构建的重采样信号所属网格下标(-1 表示无请求)。 */
|
||||
std::vector<ResampleBuild> m_pendingResampleItems; /**< 待构建的重采样信号及其间隔。 */
|
||||
|
||||
int m_pendingClipLane = -1; /**< 待截取的信号所属网格下标(-1 表示无请求)。 */
|
||||
std::vector<ClipBuild> m_pendingClipItems; /**< 待截取的信号及其区间。 */
|
||||
bool m_mouseOverPanel = false; /**< 上一帧鼠标是否落在某个实验性功能面板上。 */
|
||||
int m_peakDragLane = -1; /**< 正在拖动弱峰滑块的面板所属网格。 */
|
||||
SignalRef m_peakDragRef; /**< 正在拖动弱峰滑块的**信号**(每个信号一套参数)。 */
|
||||
|
||||
@@ -607,6 +607,21 @@ namespace jdi
|
||||
inline const double kResampleIntervalMin = 1.0e-9;
|
||||
inline const double kResampleIntervalMax = 1.0e6;
|
||||
|
||||
// ---- 「选区截取」面板 ----
|
||||
/** 「选区截取」面板标题。 */
|
||||
inline const wchar_t* const kClipTitle = L"选区截取";
|
||||
/** 底部按钮:「截取为新信号」(在源信号下方插入派生信号)。 */
|
||||
inline const wchar_t* const kClipBuildLabel = L"截取为新信号";
|
||||
/** 底部按钮:「原始信号截取」(破坏性截取,丢弃区间外的采样)。 */
|
||||
inline const wchar_t* const kClipDestructiveLabel = L"原始信号截取";
|
||||
/**
|
||||
* @brief 未启用双光标模式时面板给出的提示。
|
||||
*
|
||||
* 该功能依赖「双光标」定义的截取区间,因此单光标/无光标时无法工作。
|
||||
*/
|
||||
inline const wchar_t* const kClipNeedDoubleCursorHint =
|
||||
L"请先启用「双光标」模式(工具栏 → 光标),再回到此面板截取选区。";
|
||||
|
||||
// ---- 「公式映射」的分组包络缓存(见 `PlotView::AcquireFormulaEnvelope`)----
|
||||
/**
|
||||
* @brief 每个信号的包络分组数上限(分组宽度按采样数反算)。
|
||||
@@ -1066,7 +1081,8 @@ namespace jdi
|
||||
*/
|
||||
inline const EdgePanelKind kEdgePanelKinds[] = {EdgePanelKind::COUNT, EdgePanelKind::CENTER,
|
||||
EdgePanelKind::MEAN, EdgePanelKind::PEAK,
|
||||
EdgePanelKind::MARK, EdgePanelKind::RESAMPLE};
|
||||
EdgePanelKind::MARK, EdgePanelKind::RESAMPLE,
|
||||
EdgePanelKind::CLIP};
|
||||
|
||||
/** 实验性功能浮动面板的种类数(遍历与命中测试统一用它,避免新增功能时漏改)。 */
|
||||
inline const int kEdgePanelKindCount = static_cast<int>(sizeof(kEdgePanelKinds) / sizeof(kEdgePanelKinds[0]));
|
||||
@@ -1342,6 +1358,31 @@ namespace jdi
|
||||
return FormatFrequency(hertz);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 「重采样」面板统计行的完整文本:`<间隔>(<频率>)`。
|
||||
*
|
||||
* ⚠️ **唯一实现**:面板**宽度计算**与**绘制**必须都调它,
|
||||
* 否则宽度按"典型文本"估算、实际文本更长时会被 `UiEllipsize` 截成 `…`
|
||||
* (用户 2026-11-03 报告"统计信息显示不完整")。
|
||||
*
|
||||
* 例:`3ms 696.631us(270.517 Hz)`、`16ms 182.614us(61.795 Hz)`。
|
||||
*
|
||||
* @param [IN] seconds 该统计行对应的间隔(秒)。
|
||||
* @return 完整文本;非法值返回 "—"。
|
||||
*/
|
||||
inline std::wstring FormatIntervalWithFrequency(double seconds)
|
||||
{
|
||||
if (!std::isfinite(seconds) || seconds <= 0.0)
|
||||
{
|
||||
return L"—";
|
||||
}
|
||||
std::wstring text = FormatDurationCompound(seconds);
|
||||
text += L"(";
|
||||
text += FormatFrequencyText(1.0 / seconds);
|
||||
text += L")";
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 按比例缩放颜色的 alpha 通道(用于提示浮层淡出)。
|
||||
* @param [IN] argb 原始 0xAARRGGBB 颜色。
|
||||
|
||||
Reference in new issue
Block a user