15 #include <QColorDialog>
16 #include <QDialogButtonBox>
17 #include <QDoubleValidator>
18 #include <QFormLayout>
19 #include <QGraphicsSceneMouseEvent>
20 #include <QHBoxLayout>
23 #include <QPushButton>
24 #include <QResizeEvent>
25 #include <QToolButton>
26 #include <QVBoxLayout>
38 , _interp(
T_CURVE::kMonotoneSpline)
60 setSceneRect(-9, -2, width, height);
71 for (
const auto & _cv :
_cvs)
81 auto newIndex =
_cvs.size() - 1;
113 if (((event->key() == Qt::Key_Backspace) || (event->key() == Qt::Key_Delete)) && (
_selectedItem >= 0)) {
122 QPointF pos = mouseEvent->scenePos();
124 QList<QGraphicsItem *> itemList = items(pos);
125 if (itemList.empty()) {
129 }
else if (itemList[0]->zValue() == 2) {
132 for (
int i = 0; i < numCircle; i++) {
134 if (obj == itemList[0]) {
143 if (mouseEvent->buttons() == Qt::LeftButton) {
145 double myx = pos.x() /
_width;
161 QPointF point = mouseEvent->scenePos();
179 auto *menu =
new QMenu(event->widget());
180 QAction *deleteAction = menu->addAction(tr(
"Delete Point"));
181 QAction *action = menu->exec(event->screenPos());
182 if (action == deleteAction)
189 Q_UNUSED(mouseEvent);
244 buf.append(QString::fromLatin1(
"P6\n%1 %2\n255\n").arg(
_width).arg(
_height));
246 _pixmap.loadFromData(buf,
"PPM");
256 QByteArray pixmap(len, 127);
258 double paramInc = 1.0 / (
_width - 2);
259 double param = 0.5 * paramInc;
261 char *ptr = pixmap.data();
265 for (
int i = 1; i <
_width - 1; i++) {
277 for (
int i = 1; i <
_height - 1; i++) {
278 memcpy(pixmap.data() + (i *
_width * 3), pixmap.data() + ((i - 1) *
_width * 3),
_width * 3);
282 memset(pixmap.data(), 0,
_width * 3);
295 _baseRectW->setStyleSheet(
"background-color: transparent;");
312 const int numCV =
_cvs.size();
313 for (
int i = 0; i < numCV; i++) {
317 pen = QPen(QColor(255, 170, 0), 1.0);
319 pen = QPen(Qt::black, 1.0);
323 circle->setFlag(QGraphicsItem::ItemIsMovable,
true);
324 circle->setZValue(2);
339 p.fillRect(contentsRect(),
_color);
351 _color = QColor(
int(255 * value[0] + 0.5),
int(255 * value[1] + 0.5),
int(255 * value[2] + 0.5));
365 QColor color = QColorDialog::getColor(
_color);
366 if (color.isValid()) {
367 _value[0] = color.red() / 255.0;
368 _value[1] = color.green() / 255.0;
369 _value[2] = color.blue() / 255.0;
370 setPalette(QPalette(color));
380 , _selPosEdit(nullptr)
381 , _selValEdit(nullptr)
382 , _interpComboBox(nullptr)
384 auto *mainLayout =
new QHBoxLayout();
385 mainLayout->setMargin(0);
387 auto *edits =
new QWidget;
388 auto *editsLayout =
new QFormLayout;
389 editsLayout->setMargin(0);
390 edits->setLayout(editsLayout);
393 auto *posValidator =
new QDoubleValidator(0.0, 1.0, 6,
_selPosEdit);
396 if (pLabel.isEmpty()) {
397 posLabel = tr(
"Selected Position:");
405 _selValEdit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
407 if (vLabel.isEmpty()) {
408 valLabel = tr(
"Selected Color:");
415 if (iLabel.isEmpty()) {
416 interpLabel = tr(
"Interp:");
418 interpLabel = iLabel;
430 curveView->setFrameShape(QFrame::StyledPanel);
431 curveView->setFrameShadow(QFrame::Sunken);
432 curveView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
433 curveView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
435 curveView->setScene(
_scene);
436 curveView->setTransform(QTransform().scale(1, -1));
437 curveView->setRenderHints(QPainter::Antialiasing);
439 mainLayout->addWidget(edits);
440 mainLayout->addWidget(curveView);
442 auto *expandButton =
new QToolButton(
this);
443 expandButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
444 QIcon expandIcon = QIcon::fromTheme(
"arrow-right", QIcon::fromTheme(
"go-next"));
445 auto *detailAction =
new QAction(expandIcon, tr(
"&Expand..."));
446 expandButton->setDefaultAction(detailAction);
447 mainLayout->addWidget(expandButton);
449 connect(expandButton, SIGNAL(triggered(QAction *)),
this, SLOT(
openDetail()));
451 mainLayout->setStretchFactor(curveView, 100);
452 setLayout(mainLayout);
467 connect(curveView, SIGNAL(resizeSignal(
int,
int)),
_scene, SLOT(resize(
int,
int)));
475 posStr.setNum(pos,
'f', 3);
478 emit
swatchChanged(QColor::fromRgbF(val[0], val[1], val[2], 1));
487 _selPosEdit->setText(QString(tr(
"%1")).arg(pos, 0,
'f', 3));
498 KSeExpr::Vec3d newColor(color.redF(), color.greenF(), color.blueF());
506 return QColor::fromRgbF(val[0], val[1], val[2], 1);
516 auto *dialog =
new QDialog();
517 dialog->setMinimumWidth(1024);
518 dialog->setMinimumHeight(400);
523 for (
const auto& i : data)
524 curve->addPoint(i._pos, i._val, i._interp);
526 auto *layout =
new QVBoxLayout();
527 dialog->setLayout(layout);
528 layout->addWidget(
curve);
530 dialog->setLayout(layout);
531 layout->addWidget(
curve);
532 auto *buttonbar =
new QDialogButtonBox();
533 buttonbar->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
534 connect(buttonbar, SIGNAL(accepted()), dialog, SLOT(accept()));
535 connect(buttonbar, SIGNAL(rejected()), dialog, SLOT(reject()));
536 layout->addWidget(buttonbar);
538 if (dialog->exec() == QDialog::Accepted) {
541 const auto &dataNew =
curve->_scene->_cvs;
542 for (
const auto &i : dataNew)
543 addPoint(i._pos, i._val, i._interp);
static constexpr std::array< int, 514 > p
void interpChanged(int interp)
void removePoint(int index)
QGraphicsProxyWidget * _baseRect
KSeExpr::Curve< KSeExpr::Vec3d > T_CURVE
void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) override
void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) override
std::vector< QGraphicsEllipseItem * > _circleObjects
void selPosChanged(double pos)
void selValChanged(const KSeExpr::Vec3d &val)
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override
void keyPressEvent(QKeyEvent *event) override
void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) override
std::vector< T_CURVE::CV > _cvs
void addPoint(double x, KSeExpr::Vec3d y, T_INTERP interp, bool select=true)
T_CURVE::InterpType T_INTERP
void cvSelected(double x, KSeExpr::Vec3d y, T_INTERP interp)
void resize(int width, int height)
ExprCSwatchFrame(KSeExpr::Vec3d value, QWidget *parent=nullptr)
KSeExpr::Vec3d getValue() const
void swatchChanged(QColor color)
void paintEvent(QPaintEvent *event) override
void setValue(const KSeExpr::Vec3d &value)
void selValChangedSignal(KSeExpr::Vec3d value)
void mousePressEvent(QMouseEvent *event) override
void internalSwatchChanged(QColor color)
void addPoint(double x, KSeExpr::Vec3d y, T_INTERP interp, bool select=false)
void swatchChanged(QColor color)
void setSwatchColor(QColor color)
QComboBox * _interpComboBox
ExprCSwatchFrame * _selValEdit
ExprColorCurve(QWidget *parent=nullptr, QString pLabel=QString(), QString vLabel=QString(), QString iLabel=QString(), bool expandable=true)
void cvSelectedSlot(double pos, KSeExpr::Vec3d val, T_INTERP interp)
void selValChangedSignal(KSeExpr::Vec3d val)
void selPosChangedSignal(double pos)
Interpolation curve class for double->double and double->Vec3D.
InterpType
Supported interpolation types.
void preparePoints()
Prepares points for evaluation (sorts and computes boundaries, clamps extrema)
T getValue(double param) const
Evaluates curve and returns full value.
void addPoint(double position, const T &val, InterpType type)
Adds a point to the curve.
CV getLowerBoundCV(double param) const
KSeExpr::CurveFuncX curve
double max(double x, double y)
double min(double x, double y)
double clamp(double x, double lo, double hi)
Vec< double, 3, false > Vec3d