Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_aspect_ratio_locker.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2016 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <QSpinBox>
10#include <QDoubleSpinBox>
11
12#include <KoAspectButton.h>
13
14#include "kis_signals_blocker.h"
15#include "kis_slider_spin_box.h"
19#include "KisAngleSelector.h"
20#include "KisAngleGauge.h"
21
22
24{
25 template <class Slider>
26 SliderWrapper(Slider *slider)
27 : m_slider(QVariant::fromValue(slider)),
28 m_object(slider) {}
29
30 void setValue(qreal value) {
31 if (auto *slider = m_slider.value<KisDoubleParseUnitSpinBox*>()) {
32 // assume value from a KisDoubleParseUnitSpinBox is always provided in Pt
33 slider->changeValuePt(value);
34
35 } else if (auto *slider = m_slider.value<KisDoubleParseSpinBox*>()) {
36 slider->setValue(value);
37
38 } else if (auto *slider = m_slider.value<KisDoubleSliderSpinBox*>()) {
39 slider->setValue(value);
40
41 } else if (auto *slider = m_slider.value<QDoubleSpinBox*>()) {
42 slider->setValue(value);
43
44 } else if (auto *slider = m_slider.value<KisIntParseSpinBox*>()) {
45 slider->setValue(qRound(value));
46
47 } else if (auto *slider = m_slider.value<KisSliderSpinBox*>()) {
48 slider->setValue(qRound(value));
49
50 } else if (auto *slider = m_slider.value<QSpinBox*>()) {
51 slider->setValue(qRound(value));
52
53 } else if (auto *slider = m_slider.value<KisAngleSelector*>()) {
54 slider->setAngle(value);
55
56 } else if (auto *slider = m_slider.value<KisAngleGauge*>()) {
57 slider->setAngle(value);
58 }
59 }
60
61 qreal value() const {
62 qreal result = 0.0;
63
64 if (auto *slider = m_slider.value<KisDoubleParseUnitSpinBox*>()) {
65 result = slider->valuePt();
66 } else if (auto *slider = m_slider.value<KisDoubleParseSpinBox*>()) {
67 result = slider->value();
68
69 } else if (auto *slider = m_slider.value<KisDoubleSliderSpinBox*>()) {
70 result = slider->value();
71
72 } else if (auto *slider = m_slider.value<QDoubleSpinBox*>()) {
73 result = slider->value();
74
75 } else if (auto *slider = m_slider.value<KisIntParseSpinBox*>()) {
76 result = slider->value();
77
78 } else if (auto *slider = m_slider.value<KisSliderSpinBox*>()) {
79 result = slider->value();
80
81 } else if (auto *slider = m_slider.value<QSpinBox*>()) {
82 result = slider->value();
83
84 } else if (auto *slider = m_slider.value<KisAngleSelector*>()) {
85 result = slider->angle();
86
87 } else if (auto *slider = m_slider.value<KisAngleGauge*>()) {
88 result = slider->angle();
89
90 }
91
92 return result;
93 }
94
95 bool isDragging() const {
96 bool result = false;
97
98 if (auto *slider = m_slider.value<KisSliderSpinBox*>()) {
99 result = slider->isDragging();
100
101 } else if (auto *slider = m_slider.value<KisDoubleSliderSpinBox*>()) {
102 result = slider->isDragging();
103 }
104
105 return result;
106 }
107
108 void connectDraggingFinished(QObject *receiver, const char *amember) {
109
110 if (auto *slider = m_slider.value<KisSliderSpinBox*>()) {
111 QObject::connect(slider, SIGNAL(draggingFinished()),
112 receiver, amember);
113
114 } else if (auto *slider = m_slider.value<KisDoubleSliderSpinBox*>()) {
115 QObject::connect(slider, SIGNAL(draggingFinished()),
116 receiver, amember);
117 }
118 }
119
120 QObject* object() const {
121 return m_object;
122 }
123
124private:
125 QVariant m_slider;
126 QObject *m_object;
127};
128
130{
131 QScopedPointer<SliderWrapper> spinOne;
132 QScopedPointer<SliderWrapper> spinTwo;
134
135 qreal aspectRatio = 1.0;
136 bool blockUpdatesOnDrag = false;
137};
138
139
141 : QObject(parent),
142 m_d(new Private)
143{
144}
145
149
150template <class SpinBoxType>
151void KisAspectRatioLocker::connectSpinBoxes(SpinBoxType *spinOne, SpinBoxType *spinTwo, KoAspectButton *aspectButton)
152{
153 m_d->spinOne.reset(new SliderWrapper(spinOne));
154 m_d->spinTwo.reset(new SliderWrapper(spinTwo));
155 m_d->aspectButton = aspectButton;
156
157 if (QVariant::fromValue(spinOne->value()).type() == QVariant::Double) {
158 connect(spinOne, SIGNAL(valueChanged(qreal)), SLOT(slotSpinOneChanged()));
159 connect(spinTwo, SIGNAL(valueChanged(qreal)), SLOT(slotSpinTwoChanged()));
160 } else {
161 connect(spinOne, SIGNAL(valueChanged(int)), SLOT(slotSpinOneChanged()));
162 connect(spinTwo, SIGNAL(valueChanged(int)), SLOT(slotSpinTwoChanged()));
163 }
164
165 m_d->spinOne->connectDraggingFinished(this, SLOT(slotSpinDraggingFinished()));
166 m_d->spinTwo->connectDraggingFinished(this, SLOT(slotSpinDraggingFinished()));
167
168 connect(m_d->aspectButton, SIGNAL(keepAspectRatioChanged(bool)), SLOT(slotAspectButtonChanged()));
170}
171
172template <class AngleBoxType>
173void KisAspectRatioLocker::connectAngleBoxes(AngleBoxType *spinOne, AngleBoxType *spinTwo, KoAspectButton *aspectButton)
174{
175 m_d->spinOne.reset(new SliderWrapper(spinOne));
176 m_d->spinTwo.reset(new SliderWrapper(spinTwo));
177 m_d->aspectButton = aspectButton;
178
179 connect(spinOne, SIGNAL(angleChanged(qreal)), SLOT(slotSpinOneChanged()));
180 connect(spinTwo, SIGNAL(angleChanged(qreal)), SLOT(slotSpinTwoChanged()));
181
182 connect(m_d->aspectButton, SIGNAL(keepAspectRatioChanged(bool)), SLOT(slotAspectButtonChanged()));
184}
185
186
187template KRITAUI_EXPORT void KisAspectRatioLocker::connectSpinBoxes(QSpinBox *spinOne, QSpinBox *spinTwo, KoAspectButton *aspectButton);
188template KRITAUI_EXPORT void KisAspectRatioLocker::connectSpinBoxes(QDoubleSpinBox *spinOne, QDoubleSpinBox *spinTwo, KoAspectButton *aspectButton);
189template KRITAUI_EXPORT void KisAspectRatioLocker::connectSpinBoxes(KisSliderSpinBox *spinOne, KisSliderSpinBox *spinTwo, KoAspectButton *aspectButton);
190template KRITAUI_EXPORT void KisAspectRatioLocker::connectSpinBoxes(KisDoubleSliderSpinBox *spinOne, KisDoubleSliderSpinBox *spinTwo, KoAspectButton *aspectButton);
191template KRITAUI_EXPORT void KisAspectRatioLocker::connectSpinBoxes(KisIntParseSpinBox *spinOne, KisIntParseSpinBox *spinTwo, KoAspectButton *aspectButton);
192template KRITAUI_EXPORT void KisAspectRatioLocker::connectSpinBoxes(KisDoubleParseSpinBox *spinOne, KisDoubleParseSpinBox *spinTwo, KoAspectButton *aspectButton);
193template KRITAUI_EXPORT void KisAspectRatioLocker::connectSpinBoxes(KisDoubleParseUnitSpinBox *spinOne, KisDoubleParseUnitSpinBox *spinTwo, KoAspectButton *aspectButton);
194template KRITAUI_EXPORT void KisAspectRatioLocker::connectAngleBoxes(KisAngleSelector *spinOne, KisAngleSelector *spinTwo, KoAspectButton *aspectButton);
195template KRITAUI_EXPORT void KisAspectRatioLocker::connectAngleBoxes(KisAngleGauge *spinOne, KisAngleGauge *spinTwo, KoAspectButton *aspectButton);
196
198{
199 if (m_d->aspectButton->keepAspectRatio()) {
200 KisSignalsBlocker b(m_d->spinTwo->object());
201 m_d->spinTwo->setValue(m_d->aspectRatio * m_d->spinOne->value());
202 }
203
204 if (!m_d->blockUpdatesOnDrag || !m_d->spinOne->isDragging()) {
205 Q_EMIT sliderValueChanged();
206 }
207}
208
210{
211 if (m_d->aspectButton->keepAspectRatio()) {
212 KisSignalsBlocker b(m_d->spinOne->object());
213 m_d->spinOne->setValue(m_d->spinTwo->value() / m_d->aspectRatio);
214 }
215
216 if (!m_d->blockUpdatesOnDrag || !m_d->spinTwo->isDragging()) {
217 Q_EMIT sliderValueChanged();
218 }
219}
220
222{
223 if (m_d->aspectButton->keepAspectRatio() &&
224 m_d->spinTwo->value() > 0 &&
225 m_d->spinOne->value() > 0) {
226 m_d->aspectRatio = qreal(m_d->spinTwo->value()) / m_d->spinOne->value();
227 } else {
228 m_d->aspectRatio = 1.0;
229 }
230
231 if (!m_d->spinTwo->isDragging()) {
232 Q_EMIT aspectButtonChanged();
233 Q_EMIT aspectButtonToggled(m_d->aspectButton->keepAspectRatio());
234 }
235}
236
238{
239 if (m_d->blockUpdatesOnDrag) {
240 Q_EMIT sliderValueChanged();
241 }
242}
243
245{
246 m_d->blockUpdatesOnDrag = value;
247}
248
float value(const T *src, size_t ch)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
A circular widget that allows to choose an angle.
A widget with several options to select an angle.
void connectSpinBoxes(SpinBoxType *spinOne, SpinBoxType *spinTwo, KoAspectButton *aspectButton)
const QScopedPointer< Private > m_d
void connectAngleBoxes(AngleBoxType *spinOne, AngleBoxType *spinTwo, KoAspectButton *aspectButton)
KisAspectRatioLocker(QObject *parent=0)
void aspectButtonToggled(bool value)
void setBlockUpdateSignalOnDrag(bool block)
The KisDoubleParseSpinBox class is a cleverer doubleSpinBox, able to parse arithmetic expressions.
The KisDoubleParseUnitSpinBox class is an evolution of the.
This class is a spinbox in which you can click and drag to set the value. A slider like bar is displa...
The KisIntParseSpinBox class is a cleverer SpinBox, able to parse arithmetic expressions.
This class is a spinbox in which you can click and drag to set the value. A slider like bar is displa...
QScopedPointer< SliderWrapper > spinTwo
QScopedPointer< SliderWrapper > spinOne
void connectDraggingFinished(QObject *receiver, const char *amember)
void setValue(qreal value)
QObject * object() const
SliderWrapper(Slider *slider)