Krita Source Code Documentation
Loading...
Searching...
No Matches
dlg_clonesarray.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2013 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#include "dlg_clonesarray.h"
8
9#include <klocalizedstring.h>
10
12
13#include <kis_debug.h>
14#include <KisViewManager.h>
15#include <kis_image.h>
18#include <kis_node.h>
19#include <kis_group_layer.h>
20#include <kis_clone_layer.h>
21
22
23DlgClonesArray::DlgClonesArray(KisViewManager *viewManager, QWidget *parent)
24 : KoDialog(parent)
25 , m_viewManager(viewManager)
26 , m_applicator(0)
27 , m_baseLayer(m_viewManager->activeLayer())
28{
29 Q_ASSERT(m_baseLayer);
30
31 setCaption(i18n("Create Clones Array"));
34 setObjectName("clones_array_dialog");
35
36 m_page = new WdgClonesArray(this);
37 Q_CHECK_PTR(m_page);
38 m_page->setObjectName("clones_array");
39
40 m_page->columnAngle->setRange(-360, 360);
41 m_page->columnAngle->setFlipOptionsMode(KisAngleSelector::FlipOptionsMode_NoFlipOptions);
42 m_page->rowAngle->setRange(-360, 360);
43 m_page->rowAngle->setFlipOptionsMode(KisAngleSelector::FlipOptionsMode_NoFlipOptions);
44
46 resize(m_page->sizeHint());
47
48 connect(this, SIGNAL(okClicked()), SLOT(okClicked()));
49 connect(this, SIGNAL(applyClicked()), SLOT(applyClicked()));
50 connect(this, SIGNAL(cancelClicked()), SLOT(cancelClicked()));
51
52 connect(m_page->columnXOffset, SIGNAL(valueChanged(int)), SLOT(syncOrthogonalToAngular()));
53 connect(m_page->columnYOffset, SIGNAL(valueChanged(int)), SLOT(syncOrthogonalToAngular()));
54 connect(m_page->rowXOffset, SIGNAL(valueChanged(int)), SLOT(syncOrthogonalToAngular()));
55 connect(m_page->rowYOffset, SIGNAL(valueChanged(int)), SLOT(syncOrthogonalToAngular()));
56
57 connect(m_page->columnDistance, SIGNAL(valueChanged(double)), SLOT(syncAngularToOrthogonal()));
58 connect(m_page->columnAngle, SIGNAL(angleChanged(qreal)), SLOT(syncAngularToOrthogonal()));
59 connect(m_page->rowDistance, SIGNAL(valueChanged(double)), SLOT(syncAngularToOrthogonal()));
60 connect(m_page->rowAngle, SIGNAL(angleChanged(qreal)), SLOT(syncAngularToOrthogonal()));
61
62 connect(m_page->numNegativeColumns, SIGNAL(valueChanged(int)), SLOT(setDirty()));
63 connect(m_page->numPositiveColumns, SIGNAL(valueChanged(int)), SLOT(setDirty()));
64 connect(m_page->numNegativeRows, SIGNAL(valueChanged(int)), SLOT(setDirty()));
65 connect(m_page->numPositiveRows, SIGNAL(valueChanged(int)), SLOT(setDirty()));
66
67 connect(m_page->numNegativeColumns, SIGNAL(valueChanged(int)), SLOT(updateCheckboxAvailability()));
68 connect(m_page->numPositiveColumns, SIGNAL(valueChanged(int)), SLOT(updateCheckboxAvailability()));
69 connect(m_page->numNegativeRows, SIGNAL(valueChanged(int)), SLOT(updateCheckboxAvailability()));
70 connect(m_page->numPositiveRows, SIGNAL(valueChanged(int)), SLOT(updateCheckboxAvailability()));
71
72 connect(m_page->columnPreference, SIGNAL(stateChanged(int)), SLOT(setDirty()));
73
76}
77
82
84{
87 m_page->columnXOffset->setValue(bounds.width());
88 m_page->rowYOffset->setValue(bounds.height());
89 }
90}
91
97
103
105{
106 m_page->columnPreference->setEnabled(
107 m_page->numNegativeColumns->value() > 0 ||
108 m_page->numNegativeRows->value() > 0);
109}
110
112{
114
115 int x, y;
116
117 x = m_page->columnXOffset->value();
118 y = m_page->columnYOffset->value();
119 m_page->columnDistance->setValue((float)sqrt(pow2(x) + pow2(y)));
120 m_page->columnAngle->setAngle(kisRadiansToDegrees(atan2((double) y, (double) x)));
121
122 x = m_page->rowXOffset->value();
123 y = m_page->rowYOffset->value();
124 m_page->rowDistance->setValue((float)sqrt(pow2(x) + pow2(y)));
125 m_page->rowAngle->setAngle(kisRadiansToDegrees(atan2((double) y, (double) x)));
126
128 setDirty();
129}
130
132{
134
135 qreal a, d;
136
137 d = m_page->columnDistance->value();
138 a = kisDegreesToRadians(m_page->columnAngle->angle());
139 m_page->columnXOffset->setValue(qRound(d * cos(a)));
140 m_page->columnYOffset->setValue(qRound(d * sin(a)));
141
142 d = m_page->rowDistance->value();
143 a = kisDegreesToRadians(m_page->rowAngle->angle());
144 m_page->rowXOffset->setValue(qRound(d * cos(a)));
145 m_page->rowYOffset->setValue(qRound(d * sin(a)));
146
148 setDirty();
149}
150
152{
153 m_page->columnXOffset->blockSignals(!value);
154 m_page->columnYOffset->blockSignals(!value);
155 m_page->rowXOffset->blockSignals(!value);
156 m_page->rowYOffset->blockSignals(!value);
157}
158
160{
161 m_page->columnDistance->blockSignals(!value);
162 m_page->columnAngle->blockSignals(!value);
163 m_page->rowDistance->blockSignals(!value);
164 m_page->rowAngle->blockSignals(!value);
165}
166
168{
169 if (!m_applicator || m_isDirty) {
171 }
172
173 Q_ASSERT(m_applicator);
174
175 m_applicator->end();
176 delete m_applicator;
177 m_applicator = 0;
178}
179
184
186{
187 if (m_applicator) {
189 delete m_applicator;
190 m_applicator = 0;
191 }
192}
193
195{
197
198 KisImageSP image = m_viewManager->image();
199
200 if (!m_viewManager->blockUntilOperationsFinished(image)) return;
201
203 new KisProcessingApplicator(image, 0,
206
207 int columnXOffset = m_page->columnXOffset->value();
208 int columnYOffset = m_page->columnYOffset->value();
209 int rowXOffset = m_page->rowXOffset->value();
210 int rowYOffset = m_page->rowYOffset->value();
211 bool rowPreference = !m_page->columnPreference->isChecked();
212
213 int startColumn = -m_page->numNegativeColumns->value();
214 int startRow = -m_page->numNegativeRows->value();
215
216 int endColumn = m_page->numPositiveColumns->value() - 1;
217 int endRow = m_page->numPositiveRows->value() - 1;
218
219 QString positiveGroupName = i18n("+ Array of %1", m_baseLayer->name());
220 KisGroupLayerSP positiveGroupLayer = new KisGroupLayer(image, positiveGroupName, OPACITY_OPAQUE_U8);
222
223 KisGroupLayerSP negativeGroupLayer;
224
225 if (startRow < 0 || startColumn < 0) {
226 QString negativeGroupName = i18n("- Array of %1", m_baseLayer->name());
227 negativeGroupLayer = new KisGroupLayer(image, negativeGroupName, OPACITY_OPAQUE_U8);
229 }
230
231 for (int row = endRow; row >= startRow; row--) {
232 for (int col = endColumn; col >= startColumn; col--) {
233 if (!col && !row) continue;
234
235 bool choosePositiveGroup = rowPreference ? row > 0 || (row == 0 && col > 0) : col > 0 || (col == 0 && row > 0);
236 KisNodeSP parent = choosePositiveGroup ? positiveGroupLayer : negativeGroupLayer;
237
238
239 QString cloneName = i18n("Clone %1, %2", col, row);
240 KisCloneLayerSP clone = new KisCloneLayer(m_baseLayer, image, cloneName, OPACITY_OPAQUE_U8);
241 clone->setX(-row * rowXOffset + col * columnXOffset);
242 clone->setY(-row * rowYOffset + col * columnYOffset);
243
245 }
246 }
247
248 setClean();
249}
250
float value(const T *src, size_t ch)
QVector< KisImageSignalType > KisImageSignalVector
const quint8 OPACITY_OPAQUE_U8
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void updateCheckboxAvailability()
KisProcessingApplicator * m_applicator
KisLayerSP m_baseLayer
void setOrthogonalSignalsEnabled(bool value)
WdgClonesArray * m_page
void setAngularSignalsEnabled(bool value)
~DlgClonesArray() override
QPointer< KisViewManager > m_viewManager
DlgClonesArray(KisViewManager *viewManager, QWidget *parent=0)
@ FlipOptionsMode_NoFlipOptions
There is no flip options available.
The command for adding a layer.
QRect exactBounds() const
void applyCommand(KUndo2Command *command, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
A dialog base class with standard buttons and predefined layouts.
Definition KoDialog.h:116
void setMainWidget(QWidget *widget)
Definition KoDialog.cpp:354
virtual void setCaption(const QString &caption)
Definition KoDialog.cpp:498
void setButtons(ButtonCodes buttonMask)
Definition KoDialog.cpp:195
void enableButtonApply(bool state)
Definition KoDialog.cpp:620
void setDefaultButton(ButtonCode id)
Definition KoDialog.cpp:302
@ Ok
Show Ok button. (this button accept()s the dialog; result set to QDialog::Accepted)
Definition KoDialog.h:127
@ Apply
Show Apply button.
Definition KoDialog.h:128
@ Cancel
Show Cancel-button. (this button reject()s the dialog; result set to QDialog::Rejected)
Definition KoDialog.h:130
#define bounds(x, a, b)
T kisRadiansToDegrees(T radians)
Definition kis_global.h:181
T pow2(const T &x)
Definition kis_global.h:166
T kisDegreesToRadians(T degrees)
Definition kis_global.h:176
QString name() const
KisPaintDeviceSP original() const override=0
KisNodeSP prevSibling() const
Definition kis_node.cpp:402
KisNodeWSP parent
Definition kis_node.cpp:86