Files
Just-DataInspector/Utilities/Inc/ColorPickerPopup.hpp
T
DeepSeek V4.1 Flash dbe9b904ab fix: 重构样式区交互与布局,修复拾色浮窗穿透与自定义颜色记忆
样式编辑区统一为固定四行网格(颜色 / 样式 / 透明度 / 线宽):
- 四行共用同一内容列宽度,宽度带上下限(面板拉宽时不再无限延伸),
  标签列与内容列作为整体在面板内居中,行标签统一按整行垂直居中,
  修复“颜色”字样与色块存在高低差的问题。
- 颜色行的色块间距按剩余空间自适应,使该行与其它三行等宽对齐。
- 线宽改为与透明度同款的滑块(0.5–10 px),从原先的“预设 + 数值旋钮”
  调整为置于样式区最下方的滑块,保留双击数值直接键入的能力。

自定义颜色浮窗(ColorPickerPopup):
- 拖动滑块时不再与下方图层(尤其是绘图区平移/框选)产生交互:
  拾色浮窗内的按下会被完整消费并抓取鼠标,不再下传。
- 打开浮窗时光标正确显示为横向调整(IDC_SIZEWE),其余区域为箭头。
- 新增自定义颜色记忆:SignalStyle 记录 customColor,从自定义色切换到
  预设色后再次点击加号方格即可直接回到上次的自定义颜色;
  加号方格始终以该颜色填充(与预设色块同尺寸、同外框)。
- 打开浮窗时以记忆色为初始取值,不再重新从预设色起步。

透明度:
- 预设色块与自定义颜色方格同样叠加不透明度显示,
  修复此前透明度只影响自定义颜色预览的问题。

其他:
- 左侧面板宽度上限由 560 收紧至 400,避免样式控件被拉得过长。
- 移除只写不读的色块尺寸缓存与已废弃的线宽步进接口。

验证:真实鼠标输入逐项核对(拾色浮窗拖拽后绘图区视图范围与时间轴完全
不变、滑块光标 SIZEWE、自定义色 #0071C4 在切换预设后仍可一键恢复、
透明度 21% 时全部预设色块同步变淡、线宽滑块 8.1 px / 双击键入 5 设为
5.0 px、面板最窄与最宽两种极限下四行均不溢出且等宽)。
make clean && make all 零错误零警告。
2026-09-29 18:06:34 +08:00

168 lines
5.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef __COLOR_PICKER_POPUP_HPP__
#define __COLOR_PICKER_POPUP_HPP__
#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>
#include <array>
#include <cstdint>
#include "PaintUtil.hpp"
#include "Theme.hpp"
namespace jdi
{
/**
* @brief 浮动式 RGB 自定义颜色拾取器。
*
* 与弹出菜单一致,不创建独立窗口,而是作为宿主绘制的最后一步直接画到后备缓冲区,
* 以浮动面板的形式出现在触发控件附近;取值变化实时生效,点击面板外部即收起。
*/
class ColorPickerPopup
{
public:
ColorPickerPopup();
/**
* @brief 绑定字体与主题资源。
* @param [IN] fonts 字体集合,需在弹出面板生命周期内保持有效。
* @param [IN] theme 主题配色,需在弹出面板生命周期内保持有效。
*/
void Setup(const UiFonts* fonts, const Theme* theme);
/**
* @brief 设置 DPI 缩放比例。
* @param [IN] scale 缩放比例(1.0 对应 96 DPI)。
*/
void SetScale(float scale);
/**
* @brief 在指定位置打开拾色面板。
* @param [IN] bounds 宿主客户区矩形,用于把面板限制在窗口内。
* @param [IN] anchor 触发控件矩形(客户区坐标),面板会紧贴其下方或上方展开。
* @param [IN] color 初始颜色(0xAARRGGBB,仅取 RGB 分量)。
*/
void Open(const gd::RectF& bounds, const gd::RectF& anchor, std::uint32_t color);
/**
* @brief 关闭拾色面板。
*/
void Close();
/**
* @brief 判断拾色面板是否处于打开状态。
* @return 打开返回 true。
*/
bool IsOpen() const { return m_open; }
/**
* @brief 获取当前取色结果。
* @return 0xAARRGGBB 颜色值(Alpha 固定为不透明)。
*/
std::uint32_t CurrentColor() const;
/**
* @brief 取出并清除“取值已变化”标记。
* @param [OUT] color 变化后的颜色。
* @return 自上次调用以来取值发生过变化返回 true。
*/
bool TakeChanged(std::uint32_t& color);
/**
* @brief 绘制拾色面板(应在宿主绘制的最后一步调用)。
* @param [IN,OUT] g 绘图上下文。
*/
void Paint(gd::Graphics& g);
/**
* @brief 处理鼠标移动(含滑块拖拽)。
* @param [IN] x 客户区横坐标。
* @param [IN] y 客户区纵坐标。
* @return 需要重绘返回 true。
*/
bool OnMouseMove(int x, int y);
/**
* @brief 处理鼠标左键按下。
* @param [IN] x 客户区横坐标。
* @param [IN] y 客户区纵坐标。
* @return 事件已被消费返回 true。
*/
bool OnLButtonDown(int x, int y);
/**
* @brief 处理鼠标左键抬起。
* @return 需要重绘返回 true。
*/
bool OnLButtonUp();
/**
* @brief 处理键盘按键(Esc 收起)。
* @param [IN] key 虚拟键码。
* @return 事件已被消费返回 true。
*/
bool OnKeyDown(WPARAM key);
/**
* @brief 判断坐标是否落在拾色面板内部。
* @param [IN] x 客户区横坐标。
* @param [IN] y 客户区纵坐标。
* @return 落在内部返回 true。
*/
bool ContainsPoint(int x, int y) const;
/**
* @brief 查询该坐标应使用的系统光标。
* @param [IN] x 客户区横坐标。
* @param [IN] y 客户区纵坐标。
* @return 系统光标句柄;面板未打开时返回空指针。
*/
HCURSOR QueryCursor(int x, int y) const;
private:
/**
* @brief 依据锚点矩形与客户区计算面板矩形与内部控件矩形。
* @param [IN] bounds 宿主客户区矩形。
* @param [IN] anchor 触发控件矩形。
*/
void BuildLayout(const gd::RectF& bounds, const gd::RectF& anchor);
/**
* @brief 查询坐标命中的滑块下标。
* @param [IN] x 客户区横坐标。
* @param [IN] y 客户区纵坐标。
* @return 滑块下标(0=R,1=G,2=B),未命中返回 -1。
*/
int SliderAtPoint(int x, int y) const;
/**
* @brief 应用滑块拖拽位置到对应通道。
* @param [IN] index 滑块下标。
* @param [IN] x 客户区横坐标。
*/
void ApplySlider(int index, float x);
const UiFonts* m_fonts = nullptr; /**< 字体资源。 */
const Theme* m_theme = nullptr; /**< 主题资源。 */
float m_scale = 1.0f; /**< DPI 缩放比例。 */
bool m_open = false; /**< 是否处于打开状态。 */
bool m_changed = false; /**< 取值是否发生变化。 */
int m_draggingSlider = -1; /**< 正在拖拽的滑块下标,-1 表示未拖拽。 */
int m_hoverSlider = -1; /**< 当前悬停的滑块下标。 */
std::array<double, 3> m_channels = {0.0, 0.0, 0.0}; /**< RGB 分量(0-1)。 */
gd::RectF m_rect; /**< 面板整体矩形。 */
gd::RectF m_titleRect; /**< 标题区域。 */
std::array<gd::RectF, 3> m_tracks; /**< 滑块轨道矩形。 */
std::array<gd::RectF, 3> m_values; /**< 数值文本矩形。 */
gd::RectF m_previewRect; /**< 预览色块矩形。 */
gd::RectF m_hexRect; /**< 十六进制文本矩形。 */
};
} // namespace jdi
#endif // __COLOR_PICKER_POPUP_HPP__