#pragma once #include #include #include #include "model/ColorScale.hpp" // core::Rgba namespace geopro::app { // 连续渐变编辑画布(1:1 复刻 colorLevelConfigurator.js):从上到下依次为 // 顶部留白(40) → 直方图(高100,灰柱) → 间距10 → 色带(高20) → 间距10 → // 滑轨黑线 → 手柄(9px方块,落在滑轨上)。 // 交互:双击滑轨空白加断点(色=该处采样);拖动中间手柄改位置;选中后 Delete/右键删除; // 首尾手柄锁定(不可拖/删/选)。断点 pos∈[0,1],导出按 pos 升序。 class GradientEditWidget : public QWidget { Q_OBJECT public: struct Stop { double pos; geopro::core::Rgba color; }; explicit GradientEditWidget(QWidget* parent = nullptr); void setStops(const std::vector& stops); // pos 升序,至少 2 个 std::vector stops() const; // 升序导出 void reverse(); // 反向:保持各 pos 不变,仅反转颜色序列 void setMinMax(double minValue, double maxValue); // 直方图域 + 读出域 void setSamples(std::vector samples); // 直方图样本 // 改当前选中手柄颜色(复刻 updateColorById)。无选中则无操作。 void setSelectedColor(const geopro::core::Rgba& color); bool hasSelection() const { return selectedId_ >= 0; } QSize sizeHint() const override { return QSize(560, 220); } signals: void changed(); // 选中/拖动时携带当前手柄信息(复刻 onHandleClick / onHandleMove + getHandleInfo)。 // colorHex 形如 "#RRGGBB";valueText=值.toFixed(2);percentText="xx.x%"。 void handleSelected(QString colorHex, QString valueText, QString percentText); void selectionCleared(); // 点击空白清除选中 protected: void paintEvent(QPaintEvent*) override; void mousePressEvent(QMouseEvent*) override; void mouseMoveEvent(QMouseEvent*) override; void mouseDoubleClickEvent(QMouseEvent*) override; void mouseReleaseEvent(QMouseEvent*) override; void keyPressEvent(QKeyEvent*) override; private: struct Node { double pos; geopro::core::Rgba color; int id; }; int hitHandle(const QPointF& p) const; // 命中手柄 id,否则 -1 bool isEndpoint(int id) const; // 首尾(按 pos 升序) bool isOnSliderLine(const QPointF& p) const; // 落在滑轨线附近 double posToX(double pos) const; // 手柄左边缘 x double xToPos(double x) const; geopro::core::Rgba sample(double pos) const; // 色带连续插值取色 void sortNodes(); void emitChangedRepaint(); void emitHandleInfo(const Node& n); // 发选中/拖动信息信号 double histTop() const; // 直方图顶 y double colorBarTop() const; double sliderLineY() const; double trackLeft() const; // 轨道左 x = RECT_SIZE double trackWidth() const; // 轨道宽 = width - RECT_SIZE*2 std::vector nodes_; int nextId_ = 0; int selectedId_ = -1; bool dragging_ = false; double minValue_ = 0.0; double maxValue_ = 100.0; std::vector samples_; }; } // namespace geopro::app