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

+25 -4
View File
@@ -355,17 +355,38 @@ namespace jdi
bool makeVisible, int& newIndex);
/**
* @brief 克隆一条信号:把它的「调整」(系数 / 绝对值 / 镜像 / Y 偏移)烘焙进采样值,
* 时间轴偏移保留在样式上,名称前置 `*`,插入到原信号下方。
* @brief 克隆一条信号(**不烘值**,只沿用源信号的时间轴偏移)。
*
* 烘值规则与「构建为新信号」完全一致,因此克隆曲线与原信号重合;区别只是
* 克隆**保留原外观**(颜色 / 透明度 / 线宽 / 绘制样式),便于“冻住当前效果继续调”。
* 语义(用户 2026-11-03 明确要求):
* * 采样值 = 源信号的**原始数据**(不做任何烘焙);
* * 名称 = `*` + 源信号名,插入到原信号下方;
* * 样式:沿用源信号的外观(颜色 / 透明度 / 线宽 / 绘制样式)**与时间轴偏移**
* (`offsetTime` 只能留在样式上,无法烘进采样值),
* 而**公式映射 / 系数 / 绝对值 / 镜像 / Y 偏移一律恢复默认**。
*
* 于是「克隆该信号」得到的是一条“去掉所有数值调整、但仍在同一个时刻显示”的原始信号,
* 便于与源信号叠加对比。
*
* @param [IN] sourceRef 源信号引用。
* @return 克隆成功返回 true。
*/
bool CloneSignal(const SignalRef& sourceRef);
/**
* @brief 克隆一条信号(**带调整**:完整沿用源信号的调整参数,不烘值)。
*
* 语义(用户 2026-11-03 明确要求):
* * 采样值 = 源信号的**原始数据**(不做任何烘焙);
* * 名称 = `*` + 源信号名,插入到原信号下方;
* * 样式:**完整复制**源信号的调整参数(公式映射 / 系数 / Y 偏移 / 时间轴偏移 /
* 水平与垂直镜像 / 绝对值)以及外观(颜色 / 透明度 / 线宽 / 绘制样式)。
*
* 因此新信号与源信号**逐像素重合**,且可以在新信号上继续独立修改调整而不影响源信号。
*
* @param [IN] sourceRef 源信号引用。
* @return 克隆成功返回 true。
*/
bool CloneSignalAdjusted(const SignalRef& sourceRef);
/**
* @brief 弹出“打开数据文件”对话框并加载所选文件。
*/