「调整」数值符号规则 + 边沿统计按帧推进(含首帧公平分摊)+ 浮动面板排版与弱峰复位控件
一、「调整」类数值的符号(SignalPanel) 1. FormatSignedNumber:0 不再显示 `+`(旧实现恒带符号 → `+0.00`),Y 轴偏移默认值显示 0.00。 2. FormatGainText:非 0 正值带 `+`、负值带 `-`、0 不带符号;仅用于非编辑态显示, 进入编辑的初始文本仍为无符号纯数值。 3. 新增 FormatOffsetTimeText:`Δt:` 后按正负带符号(Δt:+5s 60ms / Δt:-5s 60ms / Δt:0s), 打开面板 / CMD_OFFSET_TIME 提交 / CMD_OFFSET_RESET 三处统一走它。 二、边沿统计:按帧预算 + 每状态公平配额 (用户报告:按住横向光标不动时统计停在“统计中…”不更新;改中心轴参数回车后不动鼠标时停在部分值) 根因:预算按 GetTickCount64() 分桶,而系统时钟粒度约 15.6ms;RequestEdgeScanFrame 的 PostMessage 自持重绘把帧率拉高 ⇒ 同一 tick 内连画多帧却完全不推进。 1. Paint 开头 ++m_edgeScanFrame; m_edgeScanBudget = kEdgeScanPairsPerFrame;(按帧重置), 删除 m_edgeScanTick。 2. 每个状态各自持有每帧配额(pumpedFrame/pumpedPairs):perState = max(60000, 1.2M/share), share = max(kEdgeScanFairShare=6, m_edgeScans.size())。 注意:不能直接用 size() 分摊 —— 状态在同一帧内逐个创建,第一个那一刻 size()==1 会独占整额, 同帧后面新建的状态全部被截断为 0 配额(即“只有第一条信号推进”)。 实测(合成 5 信号 × 200 万采样、同一网格):首帧 5 个状态全部推进;9 帧内全部扫完(期间不注入 任何鼠标消息);数值与独立参考实现逐位一致;阈值变化后就地重置、随后“停住不动”仍精确扫完。 三、浮动面板排版 1. 信号名宽度上限 kEdgePanelNameMaxWidth=150 逻辑像素:宽度计算与绘制都用 min(实测, 上限) + UiEllipsize(300 字符名字只比单字符宽 44px,旧实现要多 5100px)。 2. 统计信息两列等宽(新增 EdgeRisingText/EdgeFallingText/EdgeCountsPending):面板宽度按 2×max(两列文本宽)+kEdgePanelStatColumnGap 预留,绘制时两列各占 (可用宽−间距)/2 ⇒ 多条信号的 “上升沿/下降沿”列起点固定、严格垂直对齐。 3. 未完成时 rising 与 falling 两个数字后面都带 `…`(旧实现只在整行末尾追加一次, 视觉上只跟在“下降沿”的数字后面)。 四、弱峰调整面板 1. 每行滑块右侧新增复位控件(复用还原图标绘制 PaintPanelResetIcon):悬停高亮 + IDC_HAND + 一次性提示;点击恢复幅度 0 / 迭代 1 且 maxIterations 回到初始上限 10。 EdgePanelLayout 新增 rowLevelResets/rowIterResets(并进 PanelSlotKey),两行按钮共用同一 X。 2. 迭代次数上限输入框的空内容提示改为“输入上限(当前N)”。 3. 滑块标签去掉多余的 %/N(kWeakPeakLevelLabel=调整幅度;新增 kWeakPeakIterationsSliderLabel= 迭代次数;MEAN / CENTER 输入框的“迭代次数 N”保持不变)。 五、验证(全部离屏;进程/线程 BELOW_NORMAL、窗口 SW_HIDE、不注入真实鼠标键盘) - 新增 .preflight/perf/panelcheck_main.cpp:46/46 通过(符号规则走真实菜单路径;按帧推进 / 不饿死 / 精确性 / 自持驱动;两列等宽预留(含未完成时两处 …);名字上限; 弱峰复位控件位置 / 对齐 / 点击恢复默认值与上限)。 - 既有 verify_main.cpp:47/47(另 2 条为本机 .preflight 未随远端同步的旧规则断言)。 - make release 零警告。 规则同步:Documents/agent_mem.md 新增 §9.26,§11.2 新增第 43–48 条硬约束,变更日志补一行。
This commit is contained in:
1 parent
65f7625dce
commit
fba40ee1a2
4 files changed
+564
-80
No files matched your search
@@ -193,24 +193,65 @@ namespace jdi
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 带正负符号的数值文本:正数也带 `+`(非编辑态显示偏移量时使用)。
|
||||
* @brief 带正负符号的数值文本(非编辑态显示偏移量时使用)。
|
||||
*
|
||||
* 规则(用户明确要求):**正数带 `+`、负数带 `-`、0 不带任何符号**。
|
||||
* (旧实现 0 也会显示 `+0.00`,用户报告“偏移调整的 Y 轴输入框默认值为 0 时也显示了正号,这不正确”。)
|
||||
* @param [IN] value 数值。
|
||||
* @return 形如 `+1.50` / `-0.25` / `+0.00` 的文本。
|
||||
* @return 形如 `+1.50` / `-0.25` / `0.00` 的文本。
|
||||
*/
|
||||
std::wstring FormatSignedNumber(double value)
|
||||
{
|
||||
const std::wstring text = FormatNumberText(std::fabs(value));
|
||||
return ((value < 0.0) ? L"-" : L"+") + text;
|
||||
if (value > 0.0)
|
||||
{
|
||||
return L"+" + text;
|
||||
}
|
||||
if (value < 0.0)
|
||||
{
|
||||
return L"-" + text;
|
||||
}
|
||||
return text; // 0:不带符号
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 把系数格式化为界面文本(与偏移量同一套两位小数规则)。
|
||||
* @brief 把系数格式化为界面文本(与偏移量同一套两位小数规则 + 显式正号)。
|
||||
*
|
||||
* 规则(用户明确要求):“系数调整”输入框**非编辑态**显示时,非 0 正值前面加 `+`,
|
||||
* 负值按原样显示负号,0 不带符号。编辑态仍用不带符号的纯数值(见 `FormatNumberText`)。
|
||||
* @param [IN] gain 系数。
|
||||
* @return 显示文本。
|
||||
*/
|
||||
std::wstring FormatGainText(float gain)
|
||||
{
|
||||
return FormatNumberText(static_cast<double>(gain));
|
||||
const double value = static_cast<double>(gain);
|
||||
if (value > 0.0)
|
||||
{
|
||||
return L"+" + FormatNumberText(value);
|
||||
}
|
||||
return FormatNumberText(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 「时间轴」偏移的非编辑态显示文本(`Δt:` + 带正负号的复合单位间隔)。
|
||||
*
|
||||
* 规则(用户明确要求):在 `Δt:` 冒号后的时间显示值**前面加上正负号**,
|
||||
* 只有值为 0 时不显示符号。示例:`Δt:+1h 1min 2s` / `Δt:-5s 60ms` / `Δt:0s`。
|
||||
*(`FormatDurationCompound` 内部取绝对值,因此符号由这里补上。)
|
||||
* @param [IN] seconds 时间偏移(秒,可为负)。
|
||||
* @return 显示文本。
|
||||
*/
|
||||
std::wstring FormatOffsetTimeText(double seconds)
|
||||
{
|
||||
if (seconds > 0.0)
|
||||
{
|
||||
return L"Δt:+" + FormatDurationCompound(seconds);
|
||||
}
|
||||
if (seconds < 0.0)
|
||||
{
|
||||
return L"Δt:-" + FormatDurationCompound(seconds);
|
||||
}
|
||||
return L"Δt:" + FormatDurationCompound(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2012,13 +2053,15 @@ namespace jdi
|
||||
gainHeader.id = CMD_GAIN_RESET; // 点击标题栏右侧的还原图标 → 系数重置为 1
|
||||
items.push_back(gainHeader);
|
||||
|
||||
// 非编辑态带正号(用户明确要求);进入编辑后的初始文本用不带符号的纯数值。
|
||||
const std::wstring gainText = FormatGainText(style->gain);
|
||||
const std::wstring gainEditText = FormatNumberText(static_cast<double>(style->gain));
|
||||
MenuItem gainEdit;
|
||||
gainEdit.kind = MenuItemKind::EDIT;
|
||||
gainEdit.label.clear(); // 不显示说明文字:输入框独占整行
|
||||
gainEdit.id = CMD_GAIN_EDIT;
|
||||
gainEdit.value = gainText;
|
||||
gainEdit.editValue = gainText;
|
||||
gainEdit.editValue = gainEditText;
|
||||
gainEdit.filter = EditFilter::NUMBER;
|
||||
items.push_back(gainEdit);
|
||||
|
||||
@@ -2039,13 +2082,13 @@ namespace jdi
|
||||
items.push_back(offsetY);
|
||||
|
||||
// 「时间轴」:把采样沿时间轴平移(画在 t + offsetTime)。
|
||||
// 非编辑态显示与双光标差值同一套复合单位文本;编辑态显示以秒为单位的数值,
|
||||
// 并在输入框最右侧提示单位 `s`。
|
||||
// 非编辑态显示与双光标差值同一套复合单位文本,并**带正负号**(用户明确要求);
|
||||
// 编辑态显示以秒为单位的数值,并在输入框最右侧提示单位 `s`。
|
||||
MenuItem offsetTime;
|
||||
offsetTime.kind = MenuItemKind::EDIT;
|
||||
offsetTime.label = L"时间轴";
|
||||
offsetTime.id = CMD_OFFSET_TIME;
|
||||
offsetTime.value = L"Δt:" + FormatDurationCompound(style->offsetTime);
|
||||
offsetTime.value = FormatOffsetTimeText(style->offsetTime);
|
||||
offsetTime.editValue = FormatNumberText(style->offsetTime);
|
||||
offsetTime.editSuffix = L"s";
|
||||
offsetTime.filter = EditFilter::NUMBER;
|
||||
@@ -2907,7 +2950,8 @@ namespace jdi
|
||||
}
|
||||
if (m_menu != nullptr)
|
||||
{
|
||||
m_menu->UpdateItemValue(CMD_GAIN_EDIT, FormatGainText(style->gain), FormatGainText(style->gain));
|
||||
m_menu->UpdateItemValue(CMD_GAIN_EDIT, FormatGainText(style->gain),
|
||||
FormatNumberText(static_cast<double>(style->gain)));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -2936,7 +2980,7 @@ namespace jdi
|
||||
if (m_menu != nullptr)
|
||||
{
|
||||
m_menu->UpdateItemValue(CMD_OFFSET_TIME,
|
||||
L"Δt:" + FormatDurationCompound(style->offsetTime),
|
||||
FormatOffsetTimeText(style->offsetTime),
|
||||
FormatNumberText(style->offsetTime));
|
||||
}
|
||||
return false;
|
||||
@@ -2959,7 +3003,8 @@ namespace jdi
|
||||
style->gain = 1.0f;
|
||||
if (m_menu != nullptr)
|
||||
{
|
||||
m_menu->UpdateItemValue(CMD_GAIN_EDIT, FormatGainText(style->gain), FormatGainText(style->gain));
|
||||
m_menu->UpdateItemValue(CMD_GAIN_EDIT, FormatGainText(style->gain),
|
||||
FormatNumberText(static_cast<double>(style->gain)));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -2974,9 +3019,10 @@ namespace jdi
|
||||
style->offsetTime = 0.0;
|
||||
if (m_menu != nullptr)
|
||||
{
|
||||
m_menu->UpdateItemValue(CMD_OFFSET_Y, FormatSignedNumber(0.0), L"0.00");
|
||||
m_menu->UpdateItemValue(CMD_OFFSET_TIME, L"Δt:" + FormatDurationCompound(0.0),
|
||||
L"0.00");
|
||||
m_menu->UpdateItemValue(CMD_OFFSET_Y, FormatSignedNumber(0.0),
|
||||
FormatNumberText(0.0));
|
||||
m_menu->UpdateItemValue(CMD_OFFSET_TIME, FormatOffsetTimeText(0.0),
|
||||
FormatNumberText(0.0));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
Reference in new issue
Block a user