- 信号悬停提示改为"锚定在首次出现位置":新增 m_hoverAnchorX/Y, PaintSignalInteraction 用锚点而非当前鼠标位置;同时补回 OnMouseMove 里 漏写的 m_hoverSignal 赋值(该行缺失会导致悬停提示完全不显示)。 - 选区放大(RUBBER_SELECT)的提示文字按阶段切换: 开启开关 -> 「横向或纵向拖动以放大选择区域,ESC退出选区模式」; 左键按下不显示提示;开始拖动后维持「右键取消选区,ESC退出选区模式」; 松开左键后淡出。新增 SetHintSticky/ReleaseHint(m_hintSticky 期间阻塞淡出), HintNeedsAnimation() 驱动宿主的淡出定时器。 - 两个时间光标统一为同一颜色与样式(去掉 theme.cursorAlt,仅保留 theme.cursor); 光标把手统一为同一形状。工具栏按钮文案动态化: 未选中「光标」/ 单光标「光标x1」/ 双光标「光标x2」 (Toolbar::SetActionLabel 返回是否变化,变化时 Application::Relayout() 以重算按钮宽度)。 - 取值胶囊避让重叠:PaintCursor 先把两条时间读数标签与 Δt 标签的矩形预填进 m_cursorLabelRects,取值标签逐条检测重叠并向下/向上让位, 多信号数据点重合或过近时读数不再互相覆盖。 两光标靠近时,光标 2 的时间读数标签自动上移一层叠放,避免互相覆盖。 - 双光标时间读数与 Δt 差值标签支持拖拽,并区分悬停与拖拽: 悬停显示手形(IDC_HAND),拖拽统一使用抓握图标(IDC_SIZEALL, 用 m_dragOnLabel 与"直接在光标线上抓取"的左右箭头区分); Δt 标签拖拽时两条光标整体平移,差值保持不变。 - Δt 差值显示样式与光标时间读数一致,文案为「Δt <时间差值>」,单位复合化: >= 60s 一路整合到 h/min/s(3662s -> 「1h 1min 2s」);1~60s 显示整秒, 非整数时补 ms(5.06s -> 「5s 60ms」,5s -> 「5s」);< 1s 逐级降到 ms/us/ns/ps 且只降一级,顶级单位为 ps 时不再降级并保留小数(「5.123 ps」)。 - 双击 Δt 进入编辑时数值量级始终为秒(例如显示 1min 时编辑框为 60.0), 修正进入高级单位后(如 1.5min)编辑框只显示 1.5 的问题。 验证(使用 TestData/VERY_BIG_DATA.CSV,1.77GB / 5 信号): - 悬停提示停留在首次出现位置,网格内继续移动鼠标不再跟随。 - 选区放大提示:开启/按下/拖动/松开四个阶段的文案与淡出均符合预期。 - 工具栏文案 光标 / 光标x1 / 光标x2 正常;两光标样式与颜色完全一致。 - 5 条信号合并网格时取值标签全部完整可见,无覆盖。 - 光标形态探测:时间读数标签与 Δt 标签悬停 HAND、拖拽 SIZEALL; 直接在光标线上拖拽仍为 SIZEWE。 - Δt 分别输入 3662 / 5.06 / 5.123e-12 秒得到「Δt 1h 1min 2s」/ 「Δt 5s 60ms」/「Δt 5.11591 ps」;整数秒显示「Δt 5s」。 - 双击 Δt(显示 15s 457.214ms)编辑框内容为 15.4572(秒)。 - Δt 标签拖拽 (-320px):光标 64.4051/79.8623 -> 30.743/46.2002,差值保持 15.4572。 - 两光标靠近时时间读数标签上下叠放、Δt 标签落位正确,取值标签不重叠。 - [1].CSV 回归正常;make clean && make all 无警告无错误。
133 lines
4.0 KiB
C++
133 lines
4.0 KiB
C++
#ifndef __THEME_HPP__
|
|
#define __THEME_HPP__
|
|
|
|
#include <windows.h>
|
|
#include <objidl.h>
|
|
#include <gdiplus.h>
|
|
|
|
#include <cstdint>
|
|
|
|
/// @brief GDI+ 命名空间短别名,便于在界面代码中引用绘图类型。
|
|
namespace gd = Gdiplus;
|
|
|
|
namespace jdi
|
|
{
|
|
|
|
/**
|
|
* @brief 将 0xAARRGGBB 颜色值转换为 GDI+ 颜色对象。
|
|
* @param [IN] argb 颜色值。
|
|
* @return GDI+ 颜色对象。
|
|
*/
|
|
inline gd::Color ToGdiColor(std::uint32_t argb)
|
|
{
|
|
return gd::Color(static_cast<BYTE>((argb >> 24) & 0xFFu), static_cast<BYTE>((argb >> 16) & 0xFFu),
|
|
static_cast<BYTE>((argb >> 8) & 0xFFu), static_cast<BYTE>(argb & 0xFFu));
|
|
}
|
|
|
|
/**
|
|
* @brief 由 0xRRGGBB 构造不透明的 0xAARRGGBB 颜色值。
|
|
* @param [IN] rgb RGB 颜色值。
|
|
* @return 不透明颜色值。
|
|
*/
|
|
inline std::uint32_t MakeArgb(std::uint32_t rgb)
|
|
{
|
|
return 0xFF000000u | (rgb & 0x00FFFFFFu);
|
|
}
|
|
|
|
/**
|
|
* @brief 替换颜色值的 Alpha 通道。
|
|
* @param [IN] argb 原颜色值。
|
|
* @param [IN] alpha 新的 Alpha 值(0-255)。
|
|
* @return 新的颜色值。
|
|
*/
|
|
inline std::uint32_t WithAlpha(std::uint32_t argb, unsigned int alpha)
|
|
{
|
|
return (argb & 0x00FFFFFFu) | ((static_cast<std::uint32_t>(alpha) & 0xFFu) << 24);
|
|
}
|
|
|
|
/**
|
|
* @brief 在两个颜色之间做线性插值。
|
|
* @param [IN] fromColor 起始颜色。
|
|
* @param [IN] toColor 结束颜色。
|
|
* @param [IN] ratio 插值比例,0 返回起始色,1 返回结束色。
|
|
* @return 插值后的颜色值。
|
|
*/
|
|
inline std::uint32_t MixColor(std::uint32_t fromColor, std::uint32_t toColor, double ratio)
|
|
{
|
|
if (ratio < 0.0)
|
|
{
|
|
ratio = 0.0;
|
|
}
|
|
if (ratio > 1.0)
|
|
{
|
|
ratio = 1.0;
|
|
}
|
|
|
|
std::uint32_t result = 0;
|
|
for (int shift = 0; shift <= 24; shift += 8)
|
|
{
|
|
const double a = static_cast<double>((fromColor >> shift) & 0xFFu);
|
|
const double b = static_cast<double>((toColor >> shift) & 0xFFu);
|
|
const std::uint32_t mixed = static_cast<std::uint32_t>(a + (b - a) * ratio + 0.5);
|
|
result |= ((mixed & 0xFFu) << shift);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @brief 界面主题色板(Solarised Light 派生)。
|
|
*/
|
|
struct Theme
|
|
{
|
|
std::uint32_t windowBg = 0; /**< 窗口底色。 */
|
|
std::uint32_t toolbarBg = 0; /**< 顶部工具栏底色。 */
|
|
std::uint32_t panelBg = 0; /**< 侧边面板底色。 */
|
|
std::uint32_t cardBg = 0; /**< 面板内卡片底色。 */
|
|
std::uint32_t statusBg = 0; /**< 底部状态栏底色。 */
|
|
std::uint32_t plotBg = 0; /**< 绘图区底色。 */
|
|
std::uint32_t border = 0; /**< 常规描边色。 */
|
|
std::uint32_t borderStrong = 0; /**< 强调描边色。 */
|
|
|
|
std::uint32_t text = 0; /**< 正文文字色。 */
|
|
std::uint32_t textStrong = 0; /**< 强调文字色。 */
|
|
std::uint32_t textMuted = 0; /**< 次要文字色。 */
|
|
std::uint32_t textOnAccent = 0; /**< 强调色之上的文字色。 */
|
|
|
|
std::uint32_t accent = 0; /**< 主题强调色。 */
|
|
std::uint32_t accentSoft = 0; /**< 强调色的浅色版本。 */
|
|
std::uint32_t hover = 0; /**< 悬停底色。 */
|
|
std::uint32_t pressed = 0; /**< 按下底色。 */
|
|
std::uint32_t selection = 0; /**< 选中底色。 */
|
|
|
|
std::uint32_t gridWeak = 0; /**< 次级网格线颜色。 */
|
|
std::uint32_t gridStrong = 0; /**< 主要网格线颜色。 */
|
|
std::uint32_t axisLine = 0; /**< 坐标轴线颜色。 */
|
|
std::uint32_t cursor = 0; /**< 时间光标颜色(单/双光标共用同一样式)。 */
|
|
std::uint32_t readoutBg = 0; /**< 数值读数底色。 */
|
|
std::uint32_t danger = 0; /**< 警示色。 */
|
|
std::uint32_t warning = 0; /**< 提示色。 */
|
|
};
|
|
|
|
/**
|
|
* @brief 获取当前使用的主题(Solarised Light)。
|
|
* @return 主题常引用。
|
|
*/
|
|
const Theme& SolarizedLight();
|
|
|
|
/**
|
|
* @brief 获取波形默认配色表。
|
|
* @param [OUT] count 配色数量输出。
|
|
* @return 颜色数组首地址。
|
|
*/
|
|
const std::uint32_t* SignalPalette(int& count);
|
|
|
|
/**
|
|
* @brief 获取波形默认配色数量。
|
|
* @return 配色数量。
|
|
*/
|
|
int SignalColorCount();
|
|
|
|
} // namespace jdi
|
|
|
|
#endif // __THEME_HPP__
|