1 /*
2 * Copyright Disney Enterprises, Inc. All rights reserved.
3 * Copyright (C) 2020 L. E. Segovia <amy@amyspark.me>
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License
7 * and the following modification to it: Section 6 Trademarks.
8 * deleted and replaced with:
9 *
10 * 6. Trademarks. This License does not grant permission to use the
11 * trade names, trademarks, service marks, or product names of the
12 * Licensor and its affiliates, except as required for reproducing
13 * the content of the NOTICE file.
14 *
15 * You may obtain a copy of the License at
16 * http://www.apache.org/licenses/LICENSE-2.0
17 */
18
19 #include <QColorDialog>
20 #include <QDoubleValidator>
21 #include <QGraphicsSceneMouseEvent>
22 #include <QHBoxLayout>
23 #include <QVBoxLayout>
24 #include <QGridLayout>
25 #include <QResizeEvent>
26 #include <QPushButton>
27 #include <QDialogButtonBox>
28 #include <QPainter>
29 #include <QMenu>
30 #include <QLabel>
31 #include <QToolButton>
32
33 #include <SeExpr2/ExprBuiltins.h>
34 #ifdef SEEXPR_USE_QDGUI
35 #include <qdgui/QdColorPickerDialog.h>
36 #endif
37
38 #include "ExprColorSwatch.h"
39
40 // Simple color frame for swatch
ExprColorFrame(SeExpr2::Vec3d value,QWidget * parent)41 ExprColorFrame::ExprColorFrame(SeExpr2::Vec3d value, QWidget *parent) : QFrame(parent), _value(value) {
42 setValue(_value);
43 setFrameStyle(QFrame::Box | QFrame::Plain);
44 QPalette pal = palette();
45 pal.setColor(backgroundRole(), pal.highlight().color());
46 setPalette(pal);
47 setAutoFillBackground(true);
48 }
49
setValue(const SeExpr2::Vec3d & value)50 void ExprColorFrame::setValue(const SeExpr2::Vec3d &value) {
51 _color = QColor(int(255 * value[0] + 0.5), int(255 * value[1] + 0.5), int(255 * value[2] + 0.5));
52 _value = value;
53 update();
54 }
55
getValue() const56 SeExpr2::Vec3d ExprColorFrame::getValue() const { return _value; }
57
paintEvent(QPaintEvent * event)58 void ExprColorFrame::paintEvent(QPaintEvent *event) {
59 Q_UNUSED(event);
60 QPainter p(this);
61 p.fillRect(contentsRect(), _color);
62 }
63
mouseReleaseEvent(QMouseEvent * event)64 void ExprColorFrame::mouseReleaseEvent(QMouseEvent *event) {
65 if (event->button() == Qt::RightButton)
66 deleteSwatchMenu(event->pos());
67 else {
68
69 #ifdef SEEXPR_USE_QDGUI
70 QColor color = QdColorPickerDialog::chooseColorFromDialog(_color, this);
71 #else
72 QColor color = QColorDialog::getColor(_color);
73 #endif
74
75 if (color.isValid()) {
76 _value[0] = color.red() / 255.0;
77 _value[1] = color.green() / 255.0;
78 _value[2] = color.blue() / 255.0;
79 update();
80 _color = color;
81 emit selValChangedSignal(_value);
82 emit swatchChanged(color);
83 }
84 }
85 }
86
deleteSwatchMenu(const QPoint & pos)87 void ExprColorFrame::deleteSwatchMenu(const QPoint &pos) {
88 QMenu *menu = new QMenu(this);
89 QAction *deleteAction = menu->addAction(tr("Delete Swatch"));
90 menu->addAction(tr("Cancel"));
91 QAction *action = menu->exec(mapToGlobal(pos));
92 if (action == deleteAction) emit deleteSwatch(this);
93 }
94
95 // Simple color widget with or without index label
ExprColorWidget(SeExpr2::Vec3d value,int index,bool indexLabel,QWidget * parent)96 ExprColorWidget::ExprColorWidget(SeExpr2::Vec3d value, int index, bool indexLabel, QWidget *parent) : QWidget(parent) {
97 _colorFrame = new ExprColorFrame(value);
98 _colorFrame->setFixedWidth(32);
99 _colorFrame->setFixedHeight(16);
100
101 QVBoxLayout *vbox = new QVBoxLayout();
102 vbox->setContentsMargins(0, 0, 0, 0);
103 vbox->setSpacing(0);
104 vbox->addWidget(_colorFrame);
105
106 if (indexLabel) {
107 QLabel *label = new QLabel(tr("%1").arg(index));
108 vbox->addWidget(label);
109 }
110
111 setLayout(vbox);
112 // emit swatchAdded(index, val);
113 }
114
getColorFrame()115 ExprColorFrame *ExprColorWidget::getColorFrame() { return _colorFrame; }
116
117 // Grid layout of color swatches
ExprColorSwatchWidget(bool indexLabel,QWidget * parent)118 ExprColorSwatchWidget::ExprColorSwatchWidget(bool indexLabel, QWidget *parent)
119 : QWidget(parent), _columns(8), _indexLabel(indexLabel) {
120 QHBoxLayout *hboxLayout = new QHBoxLayout();
121 hboxLayout->setContentsMargins(0, 0, 0, 0);
122 setLayout(hboxLayout);
123
124 QToolButton *addBtn = new QToolButton;
125 addBtn->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
126 QAction *detailAction = new QAction(tr("&Add..."));
127 QIcon detailIcon = QIcon::fromTheme("addlayer", QIcon::fromTheme("list-add"));
128 detailAction->setIcon(detailIcon);
129 addBtn->setDefaultAction(detailAction);
130 addBtn->setFixedHeight(16);
131 QVBoxLayout *swatchControlLayout = new QVBoxLayout();
132 swatchControlLayout->setContentsMargins(0, 0, 0, 0);
133 swatchControlLayout->setAlignment(Qt::AlignLeft | Qt::AlignCenter);
134 QHBoxLayout *addRemoveBtnLayout = new QHBoxLayout();
135 addRemoveBtnLayout->setContentsMargins(0, 0, 0, 0);
136 addRemoveBtnLayout->setSpacing(0);
137 addRemoveBtnLayout->addWidget(addBtn);
138 swatchControlLayout->addLayout(addRemoveBtnLayout);
139 swatchControlLayout->addStretch();
140
141 QHBoxLayout *paletteLayout = new QHBoxLayout();
142 paletteLayout->setContentsMargins(0, 0, 0, 0);
143 QWidget *colorGrid = new QWidget();
144 colorGrid->setMinimumWidth(256);
145 _gridLayout = new QGridLayout();
146 _gridLayout->setContentsMargins(0, 0, 0, 0);
147 _gridLayout->setSpacing(0);
148 paletteLayout->addLayout(_gridLayout);
149 colorGrid->setLayout(paletteLayout);
150
151 hboxLayout->addWidget(colorGrid);
152 hboxLayout->addLayout(swatchControlLayout);
153 hboxLayout->addStretch();
154
155 // SIGNALS
156 connect(addBtn, SIGNAL(triggered(QAction *)), this, SLOT(addNewColor()));
157 }
158
addNewColor()159 void ExprColorSwatchWidget::addNewColor() {
160 SeExpr2::Vec3d val(.5);
161 addSwatch(val, -1);
162 }
163
addSwatch(SeExpr2::Vec3d & val,int index)164 void ExprColorSwatchWidget::addSwatch(SeExpr2::Vec3d &val, int index) {
165 if (index == -1 || index > _gridLayout->count()) index = _gridLayout->count();
166 ExprColorWidget *widget = new ExprColorWidget(val, index, _indexLabel, this);
167 ExprColorFrame *swatchFrame = widget->getColorFrame();
168 _gridLayout->addWidget(widget, index / _columns, index % _columns);
169 connect(swatchFrame, SIGNAL(swatchChanged(QColor)), this, SLOT(internalSwatchChanged(QColor)));
170 connect(swatchFrame, SIGNAL(deleteSwatch(ExprColorFrame *)), this, SLOT(removeSwatch(ExprColorFrame *)));
171 emit swatchAdded(index, val);
172 }
173
internalSwatchChanged(QColor newcolor)174 void ExprColorSwatchWidget::internalSwatchChanged(QColor newcolor) {
175 Q_UNUSED(newcolor);
176 ExprColorFrame *swatchFrame = (ExprColorFrame *)sender();
177 SeExpr2::Vec3d value = swatchFrame->getValue();
178 int index = _gridLayout->indexOf(swatchFrame->parentWidget());
179 emit swatchChanged(index, value);
180 }
181
removeSwatch(ExprColorFrame * widget)182 void ExprColorSwatchWidget::removeSwatch(ExprColorFrame *widget) {
183 QWidget *parentWidget = widget->parentWidget();
184 // Find given widget to remove from grid layout
185 for (int i = 0; i < _gridLayout->count(); i++) {
186 if (_gridLayout->itemAt(i)->widget() == parentWidget) {
187 _gridLayout->removeWidget(parentWidget);
188 parentWidget->deleteLater();
189 emit swatchRemoved(i);
190 break;
191 }
192 }
193 }
194
setSwatchColor(int index,QColor color)195 void ExprColorSwatchWidget::setSwatchColor(int index, QColor color) {
196 if (index >= 0 && index < _gridLayout->count()) {
197 SeExpr2::Vec3d newColor(color.redF(), color.greenF(), color.blueF());
198 QLayoutItem *layoutItem = _gridLayout->itemAt(index);
199 if (layoutItem && layoutItem->widget()) {
200 QWidget *widget = layoutItem->widget();
201 ExprColorFrame *cFrame = ((ExprColorWidget *)widget)->getColorFrame();
202 cFrame->setValue(newColor);
203 }
204 }
205 }
206
getSwatchColor(int index)207 QColor ExprColorSwatchWidget::getSwatchColor(int index) {
208 if (index >= 0 && index < _gridLayout->count()) {
209 QLayoutItem *layoutItem = _gridLayout->itemAt(index);
210 if (layoutItem && layoutItem->widget()) {
211 QWidget *widget = layoutItem->widget();
212 ExprColorFrame *cFrame = ((ExprColorWidget *)widget)->getColorFrame();
213 SeExpr2::Vec3d val = cFrame->getValue();
214 return QColor::fromRgbF(val[0], val[1], val[2], 1);
215 }
216 }
217 return QColor();
218 }
219