Pencil2D Animation
Download Community News Docs Contribute
  • Overview
  • Articles
  • Code
  •  
  • Class List
  • Class Index
  • Class Hierarchy
  • Class Members
  • File List
Loading...
Searching...
No Matches
  • app
  • src
strokeoptionswidget.cpp
1#include "strokeoptionswidget.h"
2#include "ui_strokeoptionswidget.h"
3
4#include "editor.h"
5#include "pencilsettings.h"
6#include "basetool.h"
7#include "stroketool.h"
8#include "polylinetool.h"
9#include "util.h"
10
11#include "toolmanager.h"
12#include "layermanager.h"
13
14StrokeOptionsWidget::StrokeOptionsWidget(Editor* editor, QWidget *parent) :
15 BaseWidget(parent),
16 ui(new Ui::StrokeOptionsWidget)
17{
18 ui->setupUi(this);
19
20 mEditor = editor;
21
22 initUI();
23
24 setContentsMargins(0,0,0,0);
25}
26
27StrokeOptionsWidget::~StrokeOptionsWidget()
28{
29 delete ui;
30}
31
32void StrokeOptionsWidget::initUI()
33{
34 StrokeTool* strokeTool = mEditor->tools()->currentStrokeTool();
35 if (strokeTool == nullptr) { return; }
36
37 const StrokeToolProperties p = strokeTool->strokeToolProperties();
38
39 auto widthInfo = p.getInfo(StrokeToolProperties::WIDTH_VALUE);
40 ui->sizeSlider->init(tr("Width"), SpinSlider::EXPONENT, widthInfo.minReal(), widthInfo.maxReal());
41
42 auto featherInfo = p.getInfo(StrokeToolProperties::FEATHER_VALUE);
43 ui->featherSlider->init(tr("Feather"), SpinSlider::LOG, featherInfo.minReal(), featherInfo.maxReal());
44
45 mCurrentTool = strokeTool;
46
47 makeConnectionFromUIToModel();
48}
49
50void StrokeOptionsWidget::updateUI()
51{
52 StrokeTool* strokeTool = mEditor->tools()->currentStrokeTool();
53 if (strokeTool == nullptr) { return; }
54
55 Q_ASSERT(strokeTool);
56
57 updateToolConnections(strokeTool);
58
59 setVisibility(strokeTool);
60
61 const StrokeToolProperties& p = strokeTool->strokeToolProperties();
62
63 if (strokeTool->isPropertyEnabled(StrokeToolProperties::WIDTH_VALUE))
64 {
65 PropertyInfo info = p.getInfo(StrokeToolProperties::WIDTH_VALUE);
66 QSignalBlocker b(ui->sizeSlider);
67 ui->sizeSlider->setRange(info.minReal(), info.maxReal());
68 QSignalBlocker b2(ui->sizeSpinBox);
69 ui->sizeSpinBox->setRange(info.minReal(), info.maxReal());
70
71 setWidthValue(info.realValue());
72 }
73 if (strokeTool->isPropertyEnabled(StrokeToolProperties::FEATHER_VALUE))
74 {
75 auto info = p.getInfo(StrokeToolProperties::FEATHER_VALUE);
76 QSignalBlocker b3(ui->featherSlider);
77 ui->featherSlider->setRange(info.minReal(), info.maxReal());
78 QSignalBlocker b4(ui->featherSpinBox);
79 ui->featherSpinBox->setRange(info.minReal(), info.maxReal());
80
81 setFeatherValue(info.realValue());
82 }
83
84 if (strokeTool->isPropertyEnabled(StrokeToolProperties::FEATHER_ENABLED)) {
85 setFeatherEnabled(p.featherEnabled());
86 }
87
88 if (strokeTool->isPropertyEnabled(StrokeToolProperties::PRESSURE_ENABLED)) {
89 setPressureEnabled(p.pressureEnabled());
90 }
91
92 if (strokeTool->isPropertyEnabled(StrokeToolProperties::INVISIBILITY_ENABLED)) {
93 setPenInvisibilityEnabled(p.invisibilityEnabled());
94 }
95
96 if (strokeTool->isPropertyEnabled(StrokeToolProperties::ANTI_ALIASING_ENABLED)) {
97 setAntiAliasingEnabled(p.AntiAliasingEnabled());
98 }
99
100 if (strokeTool->isPropertyEnabled(StrokeToolProperties::STABILIZATION_VALUE)) {
101 setStabilizerLevel(p.stabilizerLevel());
102 }
103
104 if (strokeTool->isPropertyEnabled(StrokeToolProperties::FILLCONTOUR_ENABLED)) {
105 setFillContourEnabled(p.fillContourEnabled());
106 }
107
108 if (strokeTool->type() == POLYLINE) {
109 const PolylineToolProperties polyP = static_cast<const PolylineTool*>(strokeTool)->settings();
110 setClosedPathEnabled(polyP.closedPathEnabled());
111 setBezierPathEnabled(polyP.bezierPathEnabled());
112 }
113}
114
115void StrokeOptionsWidget::updateToolConnections(BaseTool* tool)
116{
117 if (mCurrentTool) {
118 disconnect(mCurrentTool, nullptr, this, nullptr);
119 }
120
121 StrokeTool* strokeTool = static_cast<StrokeTool*>(tool);
122 mCurrentTool = strokeTool;
123
124 makeConnectionFromModelToUI(strokeTool);
125}
126
127void StrokeOptionsWidget::makeConnectionFromModelToUI(StrokeTool* strokeTool)
128{
129 connect(strokeTool, &StrokeTool::widthChanged, this, &StrokeOptionsWidget::setWidthValue);
130 connect(strokeTool, &StrokeTool::featherChanged, this, &StrokeOptionsWidget::setFeatherValue);
131 connect(strokeTool, &StrokeTool::featherEnabledChanged, this, &StrokeOptionsWidget::setFeatherEnabled);
132 connect(strokeTool, &StrokeTool::pressureEnabledChanged, this, &StrokeOptionsWidget::setPressureEnabled);
133 connect(strokeTool, &StrokeTool::stabilizationLevelChanged, this, &StrokeOptionsWidget::setStabilizerLevel);
134 connect(strokeTool, &StrokeTool::antiAliasingEnabledChanged, this, &StrokeOptionsWidget::setAntiAliasingEnabled);
135 connect(strokeTool, &StrokeTool::fillContourEnabledChanged, this, &StrokeOptionsWidget::setFillContourEnabled);
136 connect(strokeTool, &StrokeTool::invisibleStrokeEnabledChanged, this, &StrokeOptionsWidget::setPenInvisibilityEnabled);
137
138 if (strokeTool->type() == POLYLINE) {
139 PolylineTool* polyline = static_cast<PolylineTool*>(strokeTool);
140 connect(polyline, &PolylineTool::bezierPathEnabledChanged, this, &StrokeOptionsWidget::setBezierPathEnabled);
141 connect(polyline, &PolylineTool::closePathChanged, this, &StrokeOptionsWidget::setClosedPathEnabled);
142 }
143}
144
145void StrokeOptionsWidget::makeConnectionFromUIToModel()
146{
147 auto spinboxValueChanged = static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged);
148
149 connect(ui->useBezierBox, &QCheckBox::clicked, [=](bool enabled) {
150 PolylineTool* tool = static_cast<PolylineTool*>(mCurrentTool);
151 tool->setUseBezier(enabled);
152 });
153
154 connect(ui->useClosedPathBox, &QCheckBox::clicked, [=](bool enabled) {
155 PolylineTool* tool = static_cast<PolylineTool*>(mCurrentTool);
156 tool->setClosePath(enabled);
157 });
158 connect(ui->usePressureBox, &QCheckBox::clicked, [=](bool enabled) {
159 mCurrentTool->setPressureEnabled(enabled);
160 });
161
162 connect(ui->makeInvisibleBox, &QCheckBox::clicked, [=](bool enabled) {
163 mCurrentTool->setStrokeInvisibleEnabled(enabled);
164 });
165
166 connect(ui->useFeatherBox, &QCheckBox::clicked, [=](bool enabled) {
167 mCurrentTool->setFeatherEnabled(enabled);
168 });
169
170 connect(ui->useAABox, &QCheckBox::clicked, [=](bool enabled) {
171 mCurrentTool->setAntiAliasingEnabled(enabled);
172 });
173
174 connect(ui->fillContourBox, &QCheckBox::clicked, [=](bool enabled) {
175 mCurrentTool->setFillContourEnabled(enabled);
176 });
177
178 connect(ui->sizeSlider, &SpinSlider::valueChanged, [=](qreal value) {
179 mCurrentTool->setWidth(value);
180 });
181
182 connect(ui->sizeSpinBox, spinboxValueChanged, [=](qreal value) {
183 mCurrentTool->setWidth(value);
184 });
185
186 connect(ui->featherSlider, &SpinSlider::valueChanged, [=](qreal value) {
187 mCurrentTool->setFeather(value);
188 });
189
190 connect(ui->featherSpinBox, spinboxValueChanged, [=](qreal value) {
191 mCurrentTool->setFeather(value);
192 });
193
194 clearFocusOnFinished(ui->sizeSpinBox);
195 clearFocusOnFinished(ui->featherSpinBox);
196
197 connect(ui->inpolLevelsCombo, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), [=](int value) {
198 mCurrentTool->setStablizationLevel(value);
199 });
200}
201
202void StrokeOptionsWidget::setVisibility(BaseTool* tool)
203{
204 ui->sizeSlider->setVisible(tool->isPropertyEnabled(StrokeToolProperties::WIDTH_VALUE));
205 ui->sizeSpinBox->setVisible(tool->isPropertyEnabled(StrokeToolProperties::WIDTH_VALUE));
206 ui->featherSlider->setVisible(tool->isPropertyEnabled(StrokeToolProperties::FEATHER_VALUE));
207 ui->featherSpinBox->setVisible(tool->isPropertyEnabled(StrokeToolProperties::FEATHER_VALUE));
208 ui->useFeatherBox->setVisible(tool->isPropertyEnabled(StrokeToolProperties::FEATHER_ENABLED));
209 ui->usePressureBox->setVisible(tool->isPropertyEnabled(StrokeToolProperties::PRESSURE_ENABLED));
210 ui->makeInvisibleBox->setVisible(tool->isPropertyEnabled(StrokeToolProperties::INVISIBILITY_ENABLED));
211 ui->useAABox->setVisible(tool->isPropertyEnabled(StrokeToolProperties::ANTI_ALIASING_ENABLED));
212 ui->stabilizerLabel->setVisible(tool->isPropertyEnabled(StrokeToolProperties::STABILIZATION_VALUE));
213 ui->inpolLevelsCombo->setVisible(tool->isPropertyEnabled(StrokeToolProperties::STABILIZATION_VALUE));
214 ui->fillContourBox->setVisible(tool->isPropertyEnabled(StrokeToolProperties::FILLCONTOUR_ENABLED));
215 ui->useBezierBox->setVisible(tool->isPropertyEnabled(PolylineToolProperties::BEZIERPATH_ENABLED));
216 ui->useClosedPathBox->setVisible(tool->isPropertyEnabled(PolylineToolProperties::CLOSEDPATH_ENABLED));
217}
218
219void StrokeOptionsWidget::setWidthValue(qreal width)
220{
221 QSignalBlocker b(ui->sizeSlider);
222 ui->sizeSlider->setValue(width);
223
224 QSignalBlocker b2(ui->sizeSpinBox);
225 ui->sizeSpinBox->setValue(width);
226}
227
228void StrokeOptionsWidget::setFeatherValue(qreal featherValue)
229{
230 QSignalBlocker b(ui->featherSlider);
231 ui->featherSlider->setValue(featherValue);
232
233 QSignalBlocker b2(ui->featherSpinBox);
234 ui->featherSpinBox->setValue(featherValue);
235}
236
237void StrokeOptionsWidget::setFeatherEnabled(bool enabled)
238{
239 QSignalBlocker b(ui->useFeatherBox);
240 ui->useFeatherBox->setChecked(enabled);
241}
242
243void StrokeOptionsWidget::setPenInvisibilityEnabled(bool enabled)
244{
245 QSignalBlocker b(ui->makeInvisibleBox);
246 ui->makeInvisibleBox->setChecked(enabled);
247}
248
249void StrokeOptionsWidget::setPressureEnabled(bool enabled)
250{
251 QSignalBlocker b(ui->usePressureBox);
252 ui->usePressureBox->setChecked(enabled);
253}
254
255void StrokeOptionsWidget::setAntiAliasingEnabled(bool enabled)
256{
257 QSignalBlocker b(ui->useAABox);
258 ui->useAABox->setChecked(enabled);
259}
260
261void StrokeOptionsWidget::setStabilizerLevel(int level)
262{
263 QSignalBlocker b(ui->inpolLevelsCombo);
264 ui->inpolLevelsCombo->setCurrentIndex(level);
265}
266
267void StrokeOptionsWidget::setFillContourEnabled(bool enabled)
268{
269 QSignalBlocker b(ui->fillContourBox);
270 ui->fillContourBox->setChecked(enabled);
271}
272
273void StrokeOptionsWidget::setBezierPathEnabled(bool enabled)
274{
275 QSignalBlocker b(ui->useBezierBox);
276 ui->useBezierBox->setChecked(enabled);
277}
278
279void StrokeOptionsWidget::setClosedPathEnabled(bool enabled)
280{
281 QSignalBlocker b(ui->useClosedPathBox);
282 ui->useClosedPathBox->setChecked(enabled);
283}
BaseTool
Definition: basetool.h:47
BaseWidget
Definition: basewidget.h:24
Editor
Definition: editor.h:71
PolylineTool
Definition: polylinetool.h:26
StrokeOptionsWidget
Definition: strokeoptionswidget.h:20
StrokeTool
Definition: stroketool.h:35
QAbstractButton::clicked
void clicked(bool checked)
QComboBox
QComboBox::activated
void activated(int index)
QDoubleSpinBox
QDoubleSpinBox::valueChanged
void valueChanged(double d)
QObject::connect
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QObject::tr
QString tr(const char *sourceText, const char *disambiguation, int n)
QSignalBlocker
QWidget
QWidget::enabled
enabled
QWidget::setupUi
void setupUi(QWidget *widget)
QWidget::width
width
PolylineToolProperties
This struct is an example of how we can share properties among tools rather than duplicating logic,...
Definition: toolproperties.h:454
PropertyInfo
Definition: toolproperties.h:30
StrokeToolProperties
Definition: toolproperties.h:395
Generated on Wed Dec 24 2025 23:46:02 for Pencil2D by doxygen 1.9.6 based on revision 1be63043db1f7fc0545528fc3b6d5098a552755b