KSeExpr 6.0.0.0
ExprControlCollection.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2011-2019 Disney Enterprises, Inc.
2// SPDX-License-Identifier: LicenseRef-Apache-2.0
3// SPDX-FileCopyrightText: 2020 L. E. Segovia <amy@amyspark.me>
4// SPDX-License-Identifier: GPL-3.0-or-later
5/*
6* @file ExprControlCollection.cpp
7* @brief Manages/creates a bunch of ExprControls by using expression text
8* @author aselle
9*/
10
11#include <QPushButton>
12#include <KSeExpr/Utils.h>
13
14#include "Debug.h"
15#include "Editable.h"
16#include "ExprAddDialog.h"
18
19ExprControlCollection::ExprControlCollection(QWidget* parent, bool showAddButton)
20 : QWidget(parent), showAddButton(showAddButton) {
21 controlLayout = new QVBoxLayout();
22 controlLayout->setContentsMargins({});
23 controlLayout->setSpacing(0);
24 controlLayout->insertStretch(-1, 100);
25
26 if (showAddButton) {
27 auto* button = new QPushButton(tr("Add new variable"));
28 button->setFocusPolicy(Qt::NoFocus);
29 auto *buttonLayout = new QHBoxLayout();
30 buttonLayout->insertStretch(-1, 100);
31 buttonLayout->addWidget(button, 0);
32 controlLayout->addLayout(buttonLayout);
33 connect(button, SIGNAL(clicked()), SLOT(addControlDialog()));
34 }
35 setLayout(controlLayout);
36}
37
39
41 auto *dialog = new ExprAddDialog(count, this);
42 if (dialog->exec()) {
43 QString s;
44 switch (dialog->tabWidget->currentIndex()) {
45 case 0:
46 s = QString::fromLatin1("%1 = curve(%2,0,0,4,1,1,4);\n")
47 .arg(dialog->variableName->text())
48 .arg(dialog->curveLookup->text());
49 break;
50 case 1:
51 s = QString::fromLatin1("%1 = ccurve(%2,0,[0,0,0],4,1,[1,1,1],4);\n")
52 .arg(dialog->variableName->text())
53 .arg(dialog->colorCurveLookup->text());
54 break;
55 case 2:
56 s = QString::fromLatin1("%1 = %2; # %3,%4\n")
57 .arg(dialog->variableName->text())
58 .arg(dialog->intDefault->text())
59 .arg(dialog->intMin->text())
60 .arg(dialog->intMax->text());
61 break;
62 case 3:
63 s = QString::fromLatin1("%1 = %2; # %3, %4\n")
64 .arg(dialog->variableName->text())
65 .arg(dialog->floatDefault->text())
66 .arg(KSeExpr::Utils::atof(dialog->floatMin->text().toStdString()), 0, 'f', 3)
67 .arg(KSeExpr::Utils::atof(dialog->floatMax->text().toStdString()), 0, 'f', 3);
68 break;
69 case 4:
70 s = QString::fromLatin1("%1 = [%2,%3,%4]; # %5, %6\n")
71 .arg(dialog->variableName->text())
72 .arg(dialog->vectorDefault0->text())
73 .arg(dialog->vectorDefault1->text())
74 .arg(dialog->vectorDefault2->text())
75 .arg(KSeExpr::Utils::atof(dialog->vectorMin->text().toStdString()), 0, 'f', 3)
76 .arg(KSeExpr::Utils::atof(dialog->vectorMax->text().toStdString()), 0, 'f', 3);
77 break;
78 case 5:
79 s = QString::fromLatin1("%1 = [%2,%3,%4];\n")
80 .arg(dialog->variableName->text())
81 .arg(dialog->color.redF())
82 .arg(dialog->color.greenF())
83 .arg(dialog->color.blueF());
84 break;
85 case 6:
86 s = QString::fromLatin1("%1 = swatch(%2,%3);\n")
87 .arg(dialog->variableName->text())
88 .arg(dialog->swatchLookup->text())
89 .arg(QString::fromLatin1(dialog->initSwatch()));
90 break;
91 case 7:
92 s = QString::fromLatin1("%1 = \"%2\"; #%3 %4\n")
93 .arg(dialog->variableName->text())
94 .arg(dialog->stringDefaultWidget->text())
95 .arg(dialog->stringTypeWidget->currentText())
96 .arg(dialog->stringNameWidget->text());
97 break;
98 }
99 emit insertString(s);
100 }
101}
102
103bool ExprControlCollection::rebuildControls(const QString& expressionText, std::vector<QString>& variables) {
104 // parse a new editable expression so we can check if we need to make new controls
105 auto *newEditable = new EditableExpression;
106 newEditable->setExpr(expressionText.toStdString());
107
108 // check for new variables
109
110 bool newVariables = true;
111 if (editableExpression && editableExpression->getVariables() == newEditable->getVariables()) newVariables = false;
112 if (newVariables) {
113 const std::vector<std::string>& vars = newEditable->getVariables();
114 variables.clear();
115 for (const auto & var : vars) {
116 variables.push_back(QString::fromLatin1("$%1").arg(QString::fromStdString(var)));
117 }
118 }
119
120 if (newEditable->size() == 0 && !editableExpression) return false;
121
123 // controls match so we only need to update positions (i.e. if the user typed and shifted some controls)
124 editableExpression->updateString(*newEditable);
125 delete newEditable;
126 } else {
127 // controls did not match
128
129 // delete old controls
130 for (auto & _control : _controls) {
131 controlLayout->removeWidget(_control);
132 delete _control;
133 }
134 _linkedId = -1;
135 _controls.clear();
136
137 // swap to new editable expression
138 delete editableExpression;
139 editableExpression = newEditable;
140
141 // build new controls
142 for (size_t i = 0; i < editableExpression->size(); i++) {
143 Editable* editable = (*editableExpression)[i];
144 ExprControl* widget = nullptr;
145 // Create control "factory" (but since its only used here...)
146 if (auto* x = dynamic_cast<NumberEditable*>(editable))
147 widget = new NumberControl(i, x);
148 else if (auto *x = dynamic_cast<VectorEditable *>(editable))
149 widget = new VectorControl(i, x);
150 else if (auto *x = dynamic_cast<StringEditable *>(editable))
151 widget = new StringControl(i, x);
152 else if (auto *x = dynamic_cast<CurveEditable *>(editable))
153 widget = new CurveControl(i, x);
154 else if (auto *x = dynamic_cast<ColorCurveEditable *>(editable))
155 widget = new CCurveControl(i, x);
156 else if (auto *x = dynamic_cast<ColorSwatchEditable *>(editable))
157 widget = new ColorSwatchControl(i, x);
158 else {
159 dbgSeExpr << "KSeExpr editor logic error, cannot find a widget for the given editable";
160 }
161 if (widget) {
162 // successfully made widget
163 int insertPoint = controlLayout->count() - 1;
164 if (showAddButton) insertPoint--;
165 controlLayout->insertWidget(insertPoint, widget);
166 _controls.push_back(widget);
167 connect(widget, SIGNAL(controlChanged(int)), SLOT(singleControlChanged(int)));
168 connect(widget, SIGNAL(linkColorEdited(int, QColor)), SLOT(linkColorEdited(int, QColor)));
169 connect(widget, SIGNAL(linkColorLink(int)), SLOT(linkColorLink(int)));
170 } else {
171 dbgSeExpr << "Expr Editor Logic ERROR did not make widget";
172 }
173 }
174 }
175 return newVariables;
176}
177
181
183 _linkedId = id;
184 for (auto & _control : _controls) {
185 _control->linkDisconnect(_linkedId);
186 }
187}
188
189void ExprControlCollection::linkColorEdited(int id, QColor color) {
190 if (id == _linkedId) emit linkColorOutput(color);
191}
192
194 // TODO: fix
195 if (_linkedId < 0 || _linkedId >= (int)_controls.size()) return;
196 _controls[_linkedId]->setColor(color);
197}
198
199void ExprControlCollection::updateText(const int, QString& text) {
200 if (editableExpression) text = QString::fromStdString(editableExpression->getEditedExpr());
201}
202
#define dbgSeExpr
Definition Debug.h:17
Control for editing a color ramp curve.
A control for editing color swatches.
Control for editing a normal curve ramp.
Factors a SeExpr into an editable expression with controls (i.e. value boxes, curve boxes)
size_t size() const
Return the count of editable parameters.
void setExpr(const std::string &expr)
Set's expressions and parses it into "control editable form".
std::string getEditedExpr() const
Return a reconstructed expression using all the editable's current values.
bool controlsMatch(const EditableExpression &other) const
Check if the other editable expression has editables that all match i.e. the controls are same.
void updateString(const EditableExpression &other)
Update the string refered to into the controls (this is only valid if controlsmatch)
const std::vector< std::string > & getVariables() const
Get list of commentsø
This class is the UI for adding widgets.
void controlChanged(int id)
Notification that a specific control was changed.
void updateText(int id, QString &text)
Request new text, given taking into account control id's new values.
bool rebuildControls(const QString &expressionText, std::vector< QString > &variables)
Rebuild the controls given the new expressionText. Return any local variables found.
void insertString(const QString &controlString)
void singleControlChanged(int id)
Notification when by a control whenever it is edited.
void linkColorOutput(QColor color)
Gives information about when a link color was changed.
ExprControlCollection(QWidget *parent=nullptr, bool showAddButton=true)
void addControlDialog()
When a user clicks "Add new variable" button.
std::vector< ExprControl * > _controls
void linkColorLink(int id)
Notification by a control that a new color link is desired.
void linkColorEdited(int id, QColor color)
Notification by a control that a color is edited (when it is linked)
EditableExpression * editableExpression
void linkColorInput(QColor color)
Base class for all controls for Expressions.
Definition ExprControl.h:25
Number slider for either float or int data.
A control for editing strings, filenames, and directories.
A vector or color control (named vector because it edits a KSeExpr::Vec3d literal)
double_t atof(const char *num)
Definition Utils.cpp:51