Krita Source Code Documentation
Loading...
Searching...
No Matches
grid_config_widget.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2016 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
8#include "ui_grid_config_widget.h"
9
10#include "kis_grid_config.h"
11#include "kis_guides_config.h"
12#include "kis_debug.h"
15
16#include <kis_icon_utils.h>
17#include <kis_config.h>
18#include <kis_config_notifier.h>
19
20#include <QStandardItem>
21#include <QStandardItemModel>
22
31
33 QWidget(parent),
34 ui(new Ui::GridConfigWidget),
35 m_d(new Private)
36{
37 ui->setupUi(this);
38
39 ui->colorMain->setAlphaChannelEnabled(true);
40 ui->colorSubdivision->setAlphaChannelEnabled(true);
41 ui->colorVertical->setAlphaChannelEnabled(true);
42 ui->colorGuides->setAlphaChannelEnabled(true);
43
44
45 ui->angleLeftAngleSelector->setRange(0, 89);
46 ui->angleRightAngleSelector->setRange(0, 89);
47 ui->angleLeftAngleSelector->setDecimals(4);
48 ui->angleRightAngleSelector->setDecimals(4);
49 ui->angleLeftAngleSelector->setFlipOptionsMode(KisAngleSelector::FlipOptionsMode_NoFlipOptions);
50 ui->angleRightAngleSelector->setFlipOptionsMode(KisAngleSelector::FlipOptionsMode_NoFlipOptions);
51 ui->cellSpacingSpinbox->setSuffix(i18n(" px"));
52 ui->cellSizeSpinbox->setSuffix(i18n(" px"));
53 ui->deleteAllGuidesButton->setIcon(KisIconUtils::loadIcon("edit-delete"));
54 ui->deleteAllGuidesButton->setIconSize(QSize(16, 16));
55
56 ui->chkLeftAngleActive->setChecked(true);
57 ui->chkRightAngleActive->setChecked(true);
58 ui->chkXSpacingActive->setChecked(true);
59 ui->chkYSpacingActive->setChecked(true);
60
61 connect(ui->deleteAllGuidesButton, SIGNAL(clicked()), SLOT(removeAllGuides()));
62
63 ui->gridTypeCombobox->addItem(i18n("Rectangle"));
64 ui->gridTypeCombobox->addItem(i18n("Isometric (Legacy)"));
65 ui->gridTypeCombobox->addItem(i18n("Isometric"));
66
67 ui->gridTypeCombobox->setCurrentIndex(0); // set to rectangle by default
68 slotGridTypeChanged(); // update the UI to hide any elements we don't need
69
70
71 connect(ui->gridTypeCombobox, SIGNAL(currentIndexChanged(int)), SLOT(slotGridTypeChanged()));
72
73 setGridConfig(m_d->gridConfig);
74 setGuidesConfig(m_d->guidesConfig);
75
76 // hide offset UI elements if offset is disabled
77 connect(ui->chkOffset, SIGNAL(toggled(bool)), ui->lblXOffset, SLOT(setVisible(bool)));
78 connect(ui->chkOffset, SIGNAL(toggled(bool)), ui->lblYOffset, SLOT(setVisible(bool)));
79 connect(ui->chkOffset, SIGNAL(toggled(bool)), ui->intXOffset, SLOT(setVisible(bool)));
80 connect(ui->chkOffset, SIGNAL(toggled(bool)), ui->intYOffset, SLOT(setVisible(bool)));
81 connect(ui->chkOffset, SIGNAL(toggled(bool)), ui->offsetAspectButton, SLOT(setVisible(bool)));
82
83
84 ui->lblXOffset->setVisible(false);
85 ui->lblYOffset->setVisible(false);
86 ui->intXOffset->setVisible(false);
87 ui->intYOffset->setVisible(false);
88 ui->offsetAspectButton->setVisible(false);
89
90 connect(ui->chkShowGrid, SIGNAL(stateChanged(int)), SLOT(slotGridGuiChanged()));
91 connect(ui->chkSnapToGrid, SIGNAL(stateChanged(int)), SLOT(slotGridGuiChanged()));
92
93 connect(ui->chkShowGuides, SIGNAL(stateChanged(int)), SLOT(slotGuidesGuiChanged()));
94 connect(ui->chkSnapToGuides, SIGNAL(stateChanged(int)), SLOT(slotGuidesGuiChanged()));
95 connect(ui->chkLockGuides, SIGNAL(stateChanged(int)), SLOT(slotGuidesGuiChanged()));
96
97 connect(ui->chkLeftAngleActive, SIGNAL(stateChanged(int)), SLOT(slotGridGuiChanged()));
98 connect(ui->chkRightAngleActive, SIGNAL(stateChanged(int)), SLOT(slotGridGuiChanged()));
99 connect(ui->chkXSpacingActive, SIGNAL(stateChanged(int)), SLOT(slotGridGuiChanged()));
100 connect(ui->chkYSpacingActive, SIGNAL(stateChanged(int)), SLOT(slotGridGuiChanged()));
101
102 connect(ui->intSubdivision, SIGNAL(valueChanged(int)), SLOT(slotGridGuiChanged()));
103
104 connect(ui->cellSpacingSpinbox, SIGNAL(valueChanged(int)), SLOT(slotGridGuiChanged()));
105 connect(ui->cellSizeSpinbox, SIGNAL(valueChanged(int)), SLOT(slotGridGuiChanged()));
106
107 connect(ui->selectMainStyle, SIGNAL(currentIndexChanged(int)), SLOT(slotGridGuiChanged()));
108 connect(ui->colorMain, SIGNAL(changed(QColor)), SLOT(slotGridGuiChanged()));
109 connect(ui->selectSubdivisionStyle, SIGNAL(currentIndexChanged(int)), SLOT(slotGridGuiChanged()));
110 connect(ui->colorSubdivision, SIGNAL(changed(QColor)), SLOT(slotGridGuiChanged()));
111 connect(ui->selectVerticalStyle, SIGNAL(currentIndexChanged(int)), SLOT(slotGridGuiChanged()));
112 connect(ui->colorVertical, SIGNAL(changed(QColor)), SLOT(slotGridGuiChanged()));
113 connect(ui->selectGuidesStyle, SIGNAL(currentIndexChanged(int)), SLOT(slotGuidesGuiChanged()));
114 connect(ui->colorGuides, SIGNAL(changed(QColor)), SLOT(slotGuidesGuiChanged()));
115
116 ui->chkOffset->setChecked(false);
117
118 connect(ui->chkOffset, SIGNAL(stateChanged(int)), SLOT(slotGridGuiChanged()));
119
120 KisAspectRatioLocker *offsetLocker = new KisAspectRatioLocker(this);
121 offsetLocker->connectSpinBoxes(ui->intXOffset, ui->intYOffset, ui->offsetAspectButton);
122
123 KisAspectRatioLocker *spacingLocker = new KisAspectRatioLocker(this);
124 spacingLocker->connectSpinBoxes(ui->intHSpacing, ui->intVSpacing, ui->spacingAspectButton);
125
126 KisAspectRatioLocker *angleLocker = new KisAspectRatioLocker(this);
127 angleLocker->connectAngleBoxes(ui->angleLeftAngleSelector, ui->angleRightAngleSelector, ui->angleAspectButton);
128
129 connect(offsetLocker, SIGNAL(sliderValueChanged()), SLOT(slotGridGuiChanged()));
130 connect(offsetLocker, SIGNAL(aspectButtonChanged()), SLOT(slotGridGuiChanged()));
131
132 connect(spacingLocker, SIGNAL(sliderValueChanged()), SLOT(slotGridGuiChanged()));
133 connect(spacingLocker, SIGNAL(aspectButtonChanged()), SLOT(slotGridGuiChanged()));
134
135 connect(angleLocker, SIGNAL(sliderValueChanged()), SLOT(slotGridGuiChanged()));
136 connect(angleLocker, SIGNAL(aspectButtonChanged()), SLOT(slotGridGuiChanged()));
137
138 connect(ui->chkShowRulers,SIGNAL(toggled(bool)),SIGNAL(showRulersChanged(bool)));
139
140 connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(slotPreferencesUpdated()));
141}
142
147
149{
150 KisGridConfig currentConfig = fetchGuiGridConfig();
151 if (currentConfig == value) return;
152
154}
155
157{
158 KisGuidesConfig currentConfig = fetchGuiGuidesConfig();
159 if (currentConfig == value) return;
160
162}
163
165{
166 m_d->gridConfig = value;
167 m_d->guiSignalsBlocked = true;
168
169 ui->chkShowGrid->setChecked(m_d->gridConfig.showGrid());
170
171 ui->spacingAspectButton->setKeepAspectRatio(false);
172 ui->intHSpacing->setMaximum(std::numeric_limits<int>::max());
173 ui->intVSpacing->setMaximum(std::numeric_limits<int>::max());
174 ui->intHSpacing->setValue(m_d->gridConfig.spacing().x());
175 ui->intVSpacing->setValue(m_d->gridConfig.spacing().y());
176 ui->intHSpacing->setEnabled(m_d->gridConfig.xSpacingActive());
177 ui->intVSpacing->setEnabled(m_d->gridConfig.ySpacingActive());
178
179 ui->chkXSpacingActive->setChecked(m_d->gridConfig.xSpacingActive());
180 ui->chkYSpacingActive->setChecked(m_d->gridConfig.ySpacingActive());
181
182 // ensure both can't be unchecked at the same time
183 ui->chkXSpacingActive->setEnabled(m_d->gridConfig.ySpacingActive());
184 ui->chkYSpacingActive->setEnabled(m_d->gridConfig.xSpacingActive());
185
186 ui->spacingAspectButton->setKeepAspectRatio(m_d->gridConfig.spacingAspectLocked());
187
188 ui->chkOffset->setChecked(m_d->gridConfig.offsetActive());
189 ui->offsetAspectButton->setKeepAspectRatio(false);
190 ui->intXOffset->setValue(m_d->gridConfig.offset().x());
191 ui->intYOffset->setValue(m_d->gridConfig.offset().y());
192 ui->offsetAspectButton->setKeepAspectRatio(m_d->gridConfig.offsetAspectLocked());
193
194 ui->chkLeftAngleActive->setChecked(m_d->gridConfig.angleLeftActive());
195 ui->chkRightAngleActive->setChecked(m_d->gridConfig.angleRightActive());
196
197 // ensure both can't be unchecked at the same time
198 ui->chkLeftAngleActive->setEnabled(m_d->gridConfig.angleRightActive());
199 ui->chkRightAngleActive->setEnabled(m_d->gridConfig.angleLeftActive());
200
201 ui->intSubdivision->setValue(m_d->gridConfig.subdivision());
202 ui->chkSnapToGrid->setChecked(m_d->gridConfig.snapToGrid());
203 ui->angleAspectButton->setKeepAspectRatio(false);
204 ui->angleLeftAngleSelector->setAngle(m_d->gridConfig.angleLeft());
205 ui->angleRightAngleSelector->setAngle(m_d->gridConfig.angleRight());
206 ui->angleLeftAngleSelector->setEnabled(m_d->gridConfig.angleLeftActive());
207 ui->angleRightAngleSelector->setEnabled(m_d->gridConfig.angleRightActive());
208 ui->angleAspectButton->setKeepAspectRatio(m_d->gridConfig.angleAspectLocked());
209 ui->cellSpacingSpinbox->setValue(m_d->gridConfig.cellSpacing());
210 ui->cellSizeSpinbox->setValue(m_d->gridConfig.cellSize());
211
212 ui->selectMainStyle->setCurrentIndex(int(m_d->gridConfig.lineTypeMain()));
213 ui->selectSubdivisionStyle->setCurrentIndex(int(m_d->gridConfig.lineTypeSubdivision()));
214 ui->selectVerticalStyle->setCurrentIndex(int(m_d->gridConfig.lineTypeVertical()));
215 ui->gridTypeCombobox->setCurrentIndex(int(m_d->gridConfig.gridType()));
216
217 ui->colorMain->setColor(m_d->gridConfig.colorMain());
218 ui->colorSubdivision->setColor(m_d->gridConfig.colorSubdivision());
219 ui->colorVertical->setColor(m_d->gridConfig.colorVertical());
220
221 m_d->guiSignalsBlocked = false;
222
223 Q_EMIT gridValueChanged();
224}
225
227{
228 m_d->guidesConfig = value;
229 m_d->guiSignalsBlocked = true;
230
231 ui->chkShowGuides->setChecked(m_d->guidesConfig.showGuides());
232 ui->chkSnapToGuides->setChecked(m_d->guidesConfig.snapToGuides());
233 ui->chkLockGuides->setChecked(m_d->guidesConfig.lockGuides());
234
235 ui->selectGuidesStyle->setCurrentIndex(int(m_d->guidesConfig.guidesLineType()));
236 ui->colorGuides->setColor(m_d->guidesConfig.guidesColor());
237
238 m_d->guiSignalsBlocked = false;
239
240 Q_EMIT guidesValueChanged();
241}
242
244{
245 return m_d->gridConfig;
246}
247
249{
250 return m_d->guidesConfig;
251}
252
253
255 m_d->guidesConfig.removeAllGuides();
256 Q_EMIT guidesValueChanged();
257}
258
260{
261 KisGridConfig config;
262
263 config.setShowGrid(ui->chkShowGrid->isChecked());
264 config.setSnapToGrid(ui->chkSnapToGrid->isChecked());
265
266 QPoint pt;
267
268 pt.rx() = ui->intHSpacing->value();
269 pt.ry() = ui->intVSpacing->value();
270 config.setSpacing(pt);
271
272 config.setXSpacingActive(ui->chkXSpacingActive->isChecked());
273 config.setYSpacingActive(ui->chkYSpacingActive->isChecked());
274
275 pt.rx() = ui->intXOffset->value();
276 pt.ry() = ui->intYOffset->value();
277 config.setOffset(pt);
278
279 config.setOffsetActive(ui->chkOffset->isChecked());
280
281 config.setSubdivision(ui->intSubdivision->value());
282 config.setAngleLeft(ui->angleLeftAngleSelector->angle());
283 config.setAngleRight(ui->angleRightAngleSelector->angle());
284 config.setAngleLeftActive(ui->chkLeftAngleActive->isChecked());
285 config.setAngleRightActive(ui->chkRightAngleActive->isChecked());
286 config.setCellSpacing(ui->cellSpacingSpinbox->value());
287 config.setCellSize(ui->cellSizeSpinbox->value());
288 config.setGridType(KisGridConfig::GridType(ui->gridTypeCombobox->currentIndex()));
289
290 config.setOffsetAspectLocked(ui->offsetAspectButton->keepAspectRatio());
291 config.setSpacingAspectLocked(ui->spacingAspectButton->keepAspectRatio());
292 config.setAngleAspectLocked(ui->angleAspectButton->keepAspectRatio());
293
294 config.setLineTypeMain(KisGridConfig::LineTypeInternal(ui->selectMainStyle->currentIndex()));
295 config.setLineTypeSubdivision(KisGridConfig::LineTypeInternal(ui->selectSubdivisionStyle->currentIndex()));
296 config.setLineTypeVertical(KisGridConfig::LineTypeInternal(ui->selectVerticalStyle->currentIndex()));
297
298 config.setColorMain(ui->colorMain->color());
299 config.setColorSubdivision(ui->colorSubdivision->color());
300 config.setColorVertical(ui->colorVertical->color());
301
302 return config;
303}
304
306{
307 KisGuidesConfig config = m_d->guidesConfig;
308
309 config.setShowGuides(ui->chkShowGuides->isChecked());
310 config.setSnapToGuides(ui->chkSnapToGuides->isChecked());
311 config.setLockGuides(ui->chkLockGuides->isChecked());
312
313 config.setGuidesLineType(KisGuidesConfig::LineTypeInternal(ui->selectGuidesStyle->currentIndex()));
314 config.setGuidesColor(ui->colorGuides->color());
315
316 return config;
317}
318
320{
321 if (m_d->guiSignalsBlocked) return;
322
323 KisGridConfig currentConfig = fetchGuiGridConfig();
324 if (currentConfig == m_d->gridConfig) return;
325
326 setGridConfigImpl(currentConfig);
327}
328
330{
331 KisConfig cfg(true);
332 enableIsometricLegacyGrid(cfg.useOpenGL()); // Isometric view needs OpenGL
333}
334
336{
337 if (m_d->guiSignalsBlocked) return;
338
339 KisGuidesConfig currentConfig = fetchGuiGuidesConfig();
340 if (currentConfig == m_d->guidesConfig) return;
341
342 setGuidesConfigImpl(currentConfig);
343}
344
346 bool showRectangleControls = ui->gridTypeCombobox->currentIndex() == 0;
347 bool showIsometricLegacyControls = (ui->gridTypeCombobox->currentIndex() == 1) && !showRectangleControls;
348 bool showIsometricControls = (ui->gridTypeCombobox->currentIndex() == 2) && !showRectangleControls;
349
350 // specific rectangle UI controls
351 ui->lblXSpacing->setVisible(showRectangleControls);
352 ui->lblYSpacing->setVisible(showRectangleControls);
353 ui->chkXSpacingActive->setVisible(showRectangleControls);
354 ui->chkYSpacingActive->setVisible(showRectangleControls);
355 ui->intHSpacing->setVisible(showRectangleControls);
356 ui->intVSpacing->setVisible(showRectangleControls);
357 ui->spacingAspectButton->setVisible(showRectangleControls);
358
359 ui->lblSubdivision->setVisible(showRectangleControls || showIsometricControls);
360 ui->intSubdivision->setVisible(showRectangleControls || showIsometricControls);
361 ui->lblSubdivisionStyle->setVisible(showRectangleControls || showIsometricControls);
362 ui->selectSubdivisionStyle->setVisible(showRectangleControls || showIsometricControls);
363 ui->colorSubdivision->setVisible(showRectangleControls || showIsometricControls);
364
365 // specific isometric UI controls
366 ui->angleAspectButton->setVisible(showIsometricLegacyControls || showIsometricControls);
367 ui->leftAngleLabel->setVisible(showIsometricLegacyControls || showIsometricControls);
368 ui->chkLeftAngleActive->setVisible(showIsometricLegacyControls || showIsometricControls);
369 ui->rightAngleLabel->setVisible(showIsometricLegacyControls || showIsometricControls);
370 ui->chkRightAngleActive->setVisible(showIsometricLegacyControls || showIsometricControls);
371 ui->angleLeftAngleSelector->setVisible(showIsometricLegacyControls || showIsometricControls);
372 ui->angleRightAngleSelector->setVisible(showIsometricLegacyControls || showIsometricControls);
373 ui->cellSpacingLabel->setVisible(showIsometricLegacyControls);
374 ui->cellSpacingSpinbox->setVisible(showIsometricLegacyControls);
375 ui->cellSizeLabel->setVisible(showIsometricControls);
376 ui->cellSizeSpinbox->setVisible(showIsometricControls);
377
378 ui->lblVerticalStyle->setVisible(showIsometricControls);
379 ui->selectVerticalStyle->setVisible(showIsometricControls);
380 ui->colorVertical->setVisible(showIsometricControls);
381
382 // disable snapping for isometric grid type for now
383 // remember if we had snapping enabled if it was on the rectangle mode
384 if (!showRectangleControls) {
385 m_isGridEnabled = ui->chkSnapToGrid->isChecked();
386 ui->chkSnapToGrid->setEnabled(false);
387 ui->chkSnapToGrid->setChecked(false);
388 } else {
389 ui->chkSnapToGrid->setEnabled(true);
390 ui->chkSnapToGrid->setChecked(m_isGridEnabled);
391 }
392
394}
395
397{
398 return ui->chkShowRulers->isChecked();
399}
400
402{
403 // this is related to bug: https://bugs.kde.org/show_bug.cgi?id=392526
404 // not sure if it's still relevant?
406
407 // Isometric (Legacy) grids disabled if OpenGL is disabled
408 QStandardItemModel *model = qobject_cast<QStandardItemModel*>(ui->gridTypeCombobox->model());
409 QStandardItem *item = model->item(1); // isometric (legacy) option
410
411 // item->setFlags(m_isIsometricGridEnabled ? item->flags() & ~Qt::ItemIsEnabled:
412 // item->flags() | Qt::ItemIsEnabled);
413
414
415 item->setEnabled(m_isIsometricGridEnabled);
416
418 item->setText(i18n("Isometric (Legacy)"));
419 } else {
420 item->setText(i18n("Isometric (Legacy - requires OpenGL)"));
421
422 // change drop down index to Rectangular in case it was previously set to isometric
423 ui->gridTypeCombobox->setCurrentIndex(0);
424 }
425}
426
428{
429 ui->chkShowRulers->setChecked(value);
430}
431
float value(const T *src, size_t ch)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
GridConfigWidget(QWidget *parent=0)
const QScopedPointer< Private > m_d
void guidesValueChanged()
void setGuidesConfig(const KisGuidesConfig &value)
KisGuidesConfig fetchGuiGuidesConfig() const
void showRulersChanged(bool)
void setGridConfigImpl(const KisGridConfig &value)
KisGridConfig fetchGuiGridConfig() const
void enableIsometricLegacyGrid(bool value)
void setGridConfig(const KisGridConfig &value)
Ui::GridConfigWidget * ui
KisGridConfig gridConfig() const
KisGuidesConfig guidesConfig() const
void setGuidesConfigImpl(const KisGuidesConfig &value)
void setShowRulers(bool value)
void gridValueChanged()
@ FlipOptionsMode_NoFlipOptions
There is no flip options available.
void connectSpinBoxes(SpinBoxType *spinOne, SpinBoxType *spinTwo, KoAspectButton *aspectButton)
void connectAngleBoxes(AngleBoxType *spinOne, AngleBoxType *spinTwo, KoAspectButton *aspectButton)
static KisConfigNotifier * instance()
bool useOpenGL(bool defaultValue=false) const
void setOffsetActive(bool value)
void setSnapToGrid(bool value)
void setAngleLeft(qreal angle)
void setSubdivision(int value)
void setXSpacingActive(bool value)
void setOffset(const QPoint &value)
void setLineTypeMain(LineTypeInternal value)
void setColorSubdivision(const QColor &value)
void setAngleLeftActive(bool value)
void setCellSpacing(int spacing)
void setColorVertical(const QColor &value)
void setGridType(GridType type)
void setLineTypeVertical(LineTypeInternal value)
void setLineTypeSubdivision(LineTypeInternal value)
void setAngleRight(qreal angle)
void setYSpacingActive(bool value)
void setSpacingAspectLocked(bool value)
void setSpacing(const QPoint &value)
void setOffsetAspectLocked(bool value)
void setCellSize(int spacing)
void setAngleRightActive(bool value)
void setShowGrid(bool value)
void setColorMain(const QColor &value)
void setAngleAspectLocked(bool value)
void setShowGuides(bool value)
void setSnapToGuides(bool value)
void setGuidesColor(const QColor &value)
void setLockGuides(bool value)
void setGuidesLineType(LineTypeInternal value)
QIcon loadIcon(const QString &name)