fix(resample,formula,clone): 重采样面板拖动/关闭失效 + 统计频率与输入框不一致 + 派生烘焙接入公式映射 + 克隆拆分

一、「重采样」浮动面板拖不动 / ✕ 关不掉(两个独立缺陷)
1. 拖不动:OnLButtonDown 的 resampleMode 分支处理完条目与按钮后无条件 return true,
   而「标题栏 -> EDGE_PANEL_MOVE」的判定在面板分支最末尾 => 标题栏按下被吞掉。
   改为只消费 insideContent 之内的点击。
2. 拖不动(第二处):OnMouseMove 的 EDGE_PANEL_MOVE -> switch (m_edgePanelDragKind)
   漏了 case RESAMPLE => 位置写进 edgePanel、又从 resamplePanel 读 => 纹丝不动。
3. ✕ 关不掉:OnLButtonUp 的 m_pendingPanelClose -> switch (kind) 漏了 RESAMPLE
   => 落进 default 关掉的是「边沿计数」。补 SetLaneResample(lane,false)。

二、统计「最小数据间隔」与「重采样频率」输入框不一致(用户报告)
   实例 MF4-Record.MF4 / m_MOT_Current_DCom[0]:最小间隔 0.003696631s
   - 统计行先舍入到 3 位有效数字(3.70ms)再换算 => 270.27 Hz;
   - 输入框用未舍入原值换算 => 270.517 Hz。
   真值 270.5166 Hz,两条路径基准不同。修法:频率一律由 RoundIntervalForDisplay
   之后的同一份显示值换算 => 输入框与统计行同为 270.27 Hz、间隔文本同为 3ms 700us。
   未改动面板行数与任何 UI 布局。

三、派生烘焙接入「公式映射」
   BuildDerivedSignal 与 CloneSignal 各写了一份
   gain!=1 || absolute || mirrorVertical || offsetY!=0,漏掉 HasFormula()
   => 带公式的信号派生/克隆后公式被静默丢弃。改为含 HasFormula() 的统一判定。
   BuildResampledSignal 本就走 ApplyDrawTransform 全程烘值,天然包含公式。

四、信号右键菜单:克隆拆成两个语义(均不烘焙采样值)
   - 「克隆该信号」:原始数据 + 外观 + 仅保留时间轴偏移,其余调整复位;
   - 「克隆该信号(带调整)」:原始数据 + 外观 + 整套调整参数。
   新增 Application::CloneSignalAdjusted、CMD_SIGNAL_CLONE_ADJUSTED=6、
   kMessageCloneSignalAdjusted=WM_APP+6。

五、教训:离屏探针崩溃会经 MemProbe::OnTerminate 弹模态「内存不足」框,
   反复重跑即反复弹窗(用户看到十几次报警,真实进程并无内存问题)。
   探针应避免 Initialize+Render,或只做数据层验证;必须无缓冲输出阶段标记。

验证:.preflight/r26 三个探针(真实 MF4 数据一致性 SAME;逻辑 7/7;端到端 12/12);
      make release 零 warning。
This commit is contained in:
DeepSeek V4.1 Flash committed 2026-11-03 11:09:25 +08:00
1 parent 74456b9305
commit 9fdbf49841
9 files changed
+278 -37

No files matched your search

+2 -1
View File
@@ -28,7 +28,8 @@ namespace jdi
enum MenuCommand : int
{
CMD_SIGNAL_SOLO = 2, /**< 仅显示该信号。 */
CMD_SIGNAL_CLONE = 5, /**< 克隆该信号(应用「调整」并烘进采样值,时间轴偏移保留)。 */
CMD_SIGNAL_CLONE = 5, /**< 克隆该信号(原始数据,只沿用源信号的时间轴偏移)。 */
CMD_SIGNAL_CLONE_ADJUSTED = 6, /**< 克隆该信号(带调整):沿用源信号的完整「调整」参数,不烘值。 */
CMD_GROUP_SHOW_ALL = 10, /**< 选中该分组全部信号。 */
CMD_GROUP_HIDE_ALL = 11, /**< 取消该分组全部信号。 */
CMD_GROUP_REMOVE = 12, /**< 从工作区移除该分组。 */
+18 -3
View File
@@ -211,8 +211,9 @@ namespace jdi
// ⚠️ 信号右键菜单**刻意保持极简**(用户 2026-10-29 要求):
// 颜色、绘制样式、可见性、显示全部/隐藏全部这些原来放在这里的条目,现在
// 都已被下方**样式自定义区**与分组右键菜单覆盖,重复的入口只会让菜单变长、变乱。
// 现在只保留两件事:
// * 「克隆该信号」(在「仅显示该信号」**之上**);
// 现在只保留三件事:
// * 「克隆该信号」(在「克隆该信号(带调整)」**之上**):原始数据 + 只沿用时间轴偏移;
// * 「克隆该信号(带调整)」:原始数据 + 沿用源信号的**全部**调整参数(用户 2026-11-03 要求);
// * 「仅显示该信号」。
std::vector<MenuItem> items;
@@ -226,6 +227,11 @@ namespace jdi
clone.id = CMD_SIGNAL_CLONE;
items.push_back(clone);
MenuItem cloneAdjusted;
cloneAdjusted.label = L"克隆该信号(带调整)";
cloneAdjusted.id = CMD_SIGNAL_CLONE_ADJUSTED;
items.push_back(cloneAdjusted);
MenuItem solo;
solo.label = L"仅显示该信号";
solo.id = CMD_SIGNAL_SOLO;
@@ -527,7 +533,7 @@ namespace jdi
switch (result.id)
{
case CMD_SIGNAL_CLONE:
// 「克隆该信号」:把原信号的「调整」(除时间轴偏移)烘焙进采样值后插入下方,
// 「克隆该信号」:**不烘值**,原始数据 + 沿用源信号的时间轴偏移(用户 2026-11-03)。
// 具体构建在宿主里完成(需要访问 DataSet 与全部标签页)。
if (m_menuTargetSignal.IsValid() && m_host != nullptr)
{
@@ -536,6 +542,15 @@ namespace jdi
static_cast<LPARAM>(m_menuTargetSignal.signalIndex));
}
break;
case CMD_SIGNAL_CLONE_ADJUSTED:
// 「克隆该信号(带调整)」:**不烘值**,原始数据 + 沿用源信号的**全部**调整参数。
if (m_menuTargetSignal.IsValid() && m_host != nullptr)
{
PostMessageW(m_host, WM_APP + 6,
static_cast<WPARAM>(m_menuTargetSignal.groupIndex),
static_cast<LPARAM>(m_menuTargetSignal.signalIndex));
}
break;
case CMD_SIGNAL_SOLO:
if (m_menuTargetSignal.IsValid())
{