geopro/src/app/GradientEditWidget.hpp

88 lines
3.2 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.

#pragma once
#include <vector>
#include <QString>
#include <QWidget>
#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<Stop>& stops); // pos 升序,至少 2 个
std::vector<Stop> stops() const; // 升序导出
void reverse(); // 反向:保持各 pos 不变,仅反转颜色序列
void setMinMax(double minValue, double maxValue); // 直方图域 + 读出域
void setSamples(std::vector<double> 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<Node> nodes_;
int nextId_ = 0;
int selectedId_ = -1;
bool dragging_ = false;
double minValue_ = 0.0;
double maxValue_ = 100.0;
std::vector<double> samples_;
};
} // namespace geopro::app