feat(ui): 双光标样式统一与配色、光标滞留视野外、差值标签与拖拽、选区放大交互与提示
1) 光标 2 的样式与光标 1 完全一致,并改用更鲜艳的颜色 - 原先光标 2 用朝上的三角把手,观感突兀;现两条光标统一为同款朝下三角 - 主题新增 cursorAlt 并改用 Solarized 洋红 #D33682(原青色偏灰),与光标 1 的 橙色 #CB4B16 同属暖色且更醒目,靠颜色而非形状区分 2) 光标允许滞留在网格可视区域之外(不再被强行夹回视野) - 删除"视图变化后夹取光标"的逻辑(时间轴选区放大、适应视图、按网格时间轴展开、 平移时都不再移动光标);仅在拖拽光标本身时才使用 ClampCursorToView(which) - 新增 CursorDisplayX(which):光标在视野外时把它的显示位置"钉"在最近的网格边缘, 取值标注与时间读数因此始终可见;数据点改为边缘三角指示(指向光标实际方向) - 命中测试改用"显示横坐标",因此被钉在边缘的光标仍可抓住拖回 3) 光标读数增加细描边,避免与背景/曲线颜色过于接近 - 新增 DrawLabelOutline():按文字颜色取反色做 1px 半透明描边, 网格内的取值胶囊、光标时间读数、差值标签统一使用 4) 双光标差值显示(时间轴上方居中,自适应单位,可拖拽、可编辑) - 新增 FormatDuration()/FormatDurationNumber()/ChosenDurationUnit(): 在 h / min / s / ms / us / ns / ps 之间自动选择单位(数值落在 [1,1000)) - 差值标签位于两条时间读数的中点,样式与时间读数一致 - 双击进入编辑:输入值采用**当前显示单位**;确认后**前方(时间较小)光标不动**, 后方光标移动到"前方 + 输入差值" - 标签支持左右拖拽(新增 PlotDragMode::CURSOR_SPAN_MOVE):两条光标整体平移、间隔不变 5) 双光标内容重叠时的层次与差值标签位置 - 新增 m_activeCursor:最后操作过(拖拽/单击/编辑)的光标其内容绘制在上层, 两条光标的竖线、取值胶囊、时间读数都按此顺序绘制 - 差值标签改为按**两条时间读数的实际净空**判断:放不下时自动落到主时间轴内部 (原先按光标线间距判断,光标被钉到边缘时会用差值标签盖住时间读数) 6) 选区放大的光标形状与颜色 - 未开始框选时不再改变鼠标形状(保持箭头);按下但未拖动时为十字 IDC_CROSS; 确定为时间轴选区后为左右箭头、Y 轴选区后为上下箭头 - 两种方向的选区统一使用强调色(原先 Y 轴选区用警示红,观感不一致) - 新增 Application::UpdateDragCursor():Windows 在鼠标捕获期间不派发 WM_SETCURSOR, 必须在 WM_MOUSEMOVE / WM_LBUTTONDOWN 后主动刷新光标形状,否则形状不会变化 7) 提示浮层加大并支持"停留后淡出",光标模式不再提示 - 提示字号由 uiSmall 改为 ui,胶囊 30px 高、内边距更大 - 新增停留 1300ms + 淡出 500ms 的时间控制;宿主用 WM_TIMER(33ms) 驱动重绘, 淡出结束自动 KillTimer(文字走 GDI 不支持 alpha,改为向胶囊底色混色实现淡出) - 「光标」三段式切换不再显示任何提示 验证([1].CSV 11 信号,窗口 1725x996,125% DPI): - 双光标:橙 0.63 / 洋红 0.7812,同款把手;底部时间读数 + 居中差值 "151.2 ms" - 放大到不含光标的区间:光标不移动,取值以边缘三角 + 胶囊贴边显示 - 拖拽差值标签:两光标从 0.63/0.7812 整体平移到 0.424202/0.575402,差值仍为 151.2 ms - 差值编辑:输入 300(显示单位为 ms)→ 前方光标保持 0.63,后方移动到 0.93 - 重叠层次:差值设为 0 时洋红(活动)在上;单击光标线后橙色(活动)在上 - 光标形状:未框选 ARROW / 按下 CROSS / 横向 SIZEWE / 纵向 SIZENS(cursor.ps1 实测) - 提示浮层:出现后约 1.3s 开始淡出、约 1.8s 消失;右键放弃选区后视图不变且模式保持选中 - 空闲 CPU 0.00%;make clean; make all 无警告无错误
This commit is contained in:
1 parent
388d3b6441
commit
eaf5b9cadf
5 files changed
+500
-117
No files matched your search
@@ -26,6 +26,7 @@ namespace jdi
|
||||
RUBBER_SELECT, /**< 选区放大:按拖拽方向决定横向(时间轴)或纵向(幅值轴)选区。 */
|
||||
SCROLL_LANES, /**< 拖动网格滚动条。 */
|
||||
CURSOR_MOVE, /**< 拖拽时间光标。 */
|
||||
CURSOR_SPAN_MOVE, /**< 拖拽双光标差值标签:两条光标整体平移,间隔不变。 */
|
||||
MOVE_SIGNAL /**< 拖拽信号曲线到其它网格。 */
|
||||
};
|
||||
|
||||
@@ -46,6 +47,7 @@ namespace jdi
|
||||
{
|
||||
NONE = 0, /**< 未处于输入状态。 */
|
||||
CURSOR_TIME, /**< 编辑时间光标位置。 */
|
||||
CURSOR_SPAN, /**< 编辑双光标之间的时间差(前方光标不动,后方光标随之移动)。 */
|
||||
LANE_Y_MAX, /**< 编辑某网格的 Y 轴最大值。 */
|
||||
LANE_Y_MIN, /**< 编辑某网格的 Y 轴最小值。 */
|
||||
SIGNAL_NAME /**< 编辑图例中某信号的显示名称。 */
|
||||
@@ -257,6 +259,15 @@ namespace jdi
|
||||
*/
|
||||
float LaneContentHeight() const { return m_laneContentHeight; }
|
||||
|
||||
/**
|
||||
* @brief 提示浮层是否仍在显示(含淡出阶段)。
|
||||
*
|
||||
* 宿主可在返回 true 时保持定时重绘,使提示能"停留后淡出"。
|
||||
*
|
||||
* @return 需要继续重绘返回 true。
|
||||
*/
|
||||
bool HintNeedsAnimation() const;
|
||||
|
||||
/**
|
||||
* @brief 清除已启用的时间光标。
|
||||
*/
|
||||
@@ -641,6 +652,13 @@ namespace jdi
|
||||
*/
|
||||
float CursorX(int which) const;
|
||||
|
||||
/**
|
||||
* @brief 计算指定光标在屏幕上的**显示**横坐标(滞留在可视区外时贴到网格边缘)。
|
||||
* @param [IN] which 光标序号(1 或 2)。
|
||||
* @return 显示横坐标。
|
||||
*/
|
||||
float CursorDisplayX(int which) const;
|
||||
|
||||
/**
|
||||
* @brief 计算指定光标时间读数标签的矩形。
|
||||
* @param [IN] which 光标序号(1 或 2)。
|
||||
@@ -659,11 +677,25 @@ namespace jdi
|
||||
/**
|
||||
* @brief 将两条光标的时间夹取到当前可见时间范围内。
|
||||
*
|
||||
* 缩放/平移/自适应会改变可见区间,若不夹取,光标会落到视图之外并“消失”,
|
||||
* 表现为“放大后无法再拖动光标”。
|
||||
* ⚠️ 现在**只在拖拽光标时**使用。视图变化(平移/放大/自适应)必须**不**移动光标:
|
||||
* 光标允许滞留在网格可视区域之外,此时仅把它的取值/时间读数贴在网格边缘显示。
|
||||
*
|
||||
* @param [IN] which 要夹取的光标序号(1 或 2)。
|
||||
*/
|
||||
void ClampCursorToView();
|
||||
void ClampCursorToView(int which);
|
||||
|
||||
/**
|
||||
* @brief 计算双光标之间的时间差(绝对值)。
|
||||
* @return 时间差;非双光标模式返回 0。
|
||||
*/
|
||||
double CursorSpan() const;
|
||||
|
||||
/**
|
||||
* @brief 计算双光标差值标签的矩形(时间轴上方、两条时间读数的中间位置)。
|
||||
* @param [OUT] insideAxis 为 true 时表示两条光标过近,标签落在主时间轴内部。
|
||||
* @return 标签矩形;非双光标模式返回空矩形。
|
||||
*/
|
||||
gd::RectF CursorSpanRect(bool& insideAxis) const;
|
||||
/**
|
||||
* @brief 获取指定光标对应的显示颜色。
|
||||
* @param [IN] which 光标序号(1 或 2)。
|
||||
@@ -672,11 +704,19 @@ namespace jdi
|
||||
std::uint32_t CursorColor(int which) const;
|
||||
|
||||
/**
|
||||
* @brief 设置并显示一条临时提示(在绘图区底部以浮层方式绘制)。
|
||||
* @param [IN] text 提示文本;传空串则清除提示。
|
||||
* @brief 设置并显示一条临时提示(在绘图区底部以浮层方式绘制,短暂停留后淡出)。
|
||||
* @param [IN] text 提示文本;传空串则立即清除提示。
|
||||
*/
|
||||
void SetHint(const std::wstring& text);
|
||||
|
||||
/**
|
||||
* @brief 画文字时给底色胶囊加一层与文字反色的细描边,提升与背景/曲线的对比度。
|
||||
* @param [IN] rect 胶囊矩形。
|
||||
* @param [IN] radius 圆角半径。
|
||||
* @param [IN] textDark 文字是否用深色。
|
||||
*/
|
||||
void DrawLabelOutline(gd::Graphics& g, const gd::RectF& rect, float radius, bool textDark);
|
||||
|
||||
/**
|
||||
* @brief 精确检测鼠标位置是否命中某条可见信号曲线。
|
||||
* @param [IN] x 客户区横坐标。
|
||||
@@ -837,7 +877,12 @@ namespace jdi
|
||||
int m_dragMouseY = 0; /**< 拖拽过程中鼠标的当前纵坐标(虚影跟随)。 */
|
||||
bool m_cursorHover = false; /**< 鼠标是否悬停在某条时间光标上。 */
|
||||
int m_hoverCursor = 0; /**< 悬停/拖拽中的光标序号(1 或 2,0 表示无)。 */
|
||||
int m_activeCursor = 1; /**< 最近操作过的光标:内容重叠时它绘制在上层。 */
|
||||
int m_editCursor = 1; /**< 内联输入所作用的 Time 光标序号。 */
|
||||
double m_editDurationUnit = 1.0; /**< 差值编辑时采用的显示单位(秒)。 */
|
||||
int m_spanDragStartX = 0; /**< 差值标签拖拽起点横坐标。 */
|
||||
double m_spanDragTime1 = 0.0; /**< 差值标签拖拽起始时两条光标的时间。 */
|
||||
double m_spanDragTime2 = 0.0;
|
||||
PlotEditTarget m_editTarget = PlotEditTarget::NONE; /**< 当前内联输入目标。 */
|
||||
TextEdit m_edit; /**< 输入框编辑模型(光标/选区/剪贴板)。 */
|
||||
int m_editLane = -1; /**< 内联输入所作用的网格下标。 */
|
||||
@@ -851,6 +896,8 @@ namespace jdi
|
||||
int m_mouseX = 0; /**< 最近一次鼠标横坐标(用于悬停提示定位)。 */
|
||||
int m_mouseY = 0; /**< 最近一次鼠标纵坐标(用于悬停提示定位)。 */
|
||||
std::wstring m_hintText; /**< 临时提示文本(空表示不显示)。 */
|
||||
std::uint64_t m_hintShownAt = 0; /**< 提示出现的时刻(毫秒,GetTickCount64)。 */
|
||||
gd::RectF m_cursorSpanRect; /**< 最近一次绘制时差值标签的矩形(用于命中拖拽/双击)。 */
|
||||
std::vector<LaneVisual> m_lanes; /**< 当前网格绘制信息集合。 */
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user