File indexing completed on 2024-05-12 16:02:02
0001 /* 0002 * KDE. Krita Project. 0003 * 0004 * SPDX-FileCopyrightText: 2020 Deif Lou <ginoba@gmail.com> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include <cmath> 0010 #include <functional> 0011 0012 #include <QHBoxLayout> 0013 #include <QToolButton> 0014 #include <QAction> 0015 #include <QEvent> 0016 #include <QMenu> 0017 #include <QLineEdit> 0018 #include <QStyleOptionSpinBox> 0019 #include <QStyle> 0020 #include <QContextMenuEvent> 0021 0022 #include <kis_icon_utils.h> 0023 #include <kis_signals_blocker.h> 0024 0025 #include <klocalizedstring.h> 0026 0027 #include "KisAngleSelector.h" 0028 0029 struct KisAngleSelectorSpinBox::Private 0030 { 0031 KisAngleSelectorSpinBox *q; 0032 bool isFlat; 0033 bool hasFocus; 0034 bool isHovered; 0035 QSize cachedSizeHint; 0036 0037 void updateStyleSheet() 0038 { 0039 if (!isFlat || hasFocus || isHovered) { 0040 q->setStyleSheet("QDoubleSpinBox{}"); 0041 } else { 0042 q->setStyleSheet( 0043 "QDoubleSpinBox{background:transparent; border:transparent;}" 0044 "QDoubleSpinBox::up-button{background:transparent; border:transparent;}" 0045 "QDoubleSpinBox::down-button{background:transparent; border:transparent;}" 0046 ); 0047 } 0048 q->lineEdit()->setStyleSheet("QLineEdit{background:transparent;}"); 0049 } 0050 }; 0051 0052 KisAngleSelectorSpinBox::KisAngleSelectorSpinBox(QWidget *parent) 0053 : KisDoubleParseSpinBox(parent) 0054 , m_d(new Private) 0055 { 0056 m_d->q = this; 0057 m_d->isFlat = false; 0058 m_d->hasFocus = false; 0059 m_d->isHovered = false; 0060 m_d->updateStyleSheet(); 0061 } 0062 0063 KisAngleSelectorSpinBox::~KisAngleSelectorSpinBox() 0064 {} 0065 0066 void KisAngleSelectorSpinBox::setRange(double min, double max) 0067 { 0068 m_d->cachedSizeHint = QSize(); 0069 KisDoubleParseSpinBox::setRange(min, max); 0070 } 0071 0072 double KisAngleSelectorSpinBox::valueFromText(const QString & text) const 0073 { 0074 const double v = KisDoubleParseSpinBox::valueFromText(text); 0075 return KisAngleSelector::closestCoterminalAngleInRange(v, minimum(), maximum()); 0076 } 0077 0078 bool KisAngleSelectorSpinBox::isFlat() const 0079 { 0080 return m_d->isFlat; 0081 } 0082 0083 void KisAngleSelectorSpinBox::setFlat(bool newFlat) 0084 { 0085 m_d->isFlat = newFlat; 0086 m_d->updateStyleSheet(); 0087 } 0088 0089 void KisAngleSelectorSpinBox::enterEvent(QEvent *e) 0090 { 0091 m_d->isHovered = true; 0092 m_d->updateStyleSheet(); 0093 KisDoubleParseSpinBox::enterEvent(e); 0094 } 0095 0096 void KisAngleSelectorSpinBox::leaveEvent(QEvent *e) 0097 { 0098 m_d->isHovered = false; 0099 m_d->updateStyleSheet(); 0100 KisDoubleParseSpinBox::leaveEvent(e); 0101 } 0102 0103 void KisAngleSelectorSpinBox::focusInEvent(QFocusEvent *e) 0104 { 0105 m_d->hasFocus = true; 0106 m_d->updateStyleSheet(); 0107 KisDoubleParseSpinBox::focusInEvent(e); 0108 } 0109 0110 void KisAngleSelectorSpinBox::focusOutEvent(QFocusEvent *e) 0111 { 0112 m_d->hasFocus = false; 0113 m_d->updateStyleSheet(); 0114 KisDoubleParseSpinBox::focusOutEvent(e); 0115 } 0116 0117 QSize KisAngleSelectorSpinBox::minimumSizeHint() const 0118 { 0119 if (m_d->cachedSizeHint.isEmpty()) { 0120 ensurePolished(); 0121 0122 const QFontMetrics fm(fontMetrics()); 0123 int h = lineEdit()->minimumSizeHint().height(); 0124 int w = 0; 0125 0126 QString s; 0127 QString fixedContent = prefix() + suffix() + QLatin1Char(' '); 0128 s = textFromValue(minimum()); 0129 s.truncate(18); 0130 s += fixedContent; 0131 #if QT_VERSION >= QT_VERSION_CHECK(5,11,0) 0132 w = qMax(w, fm.horizontalAdvance(s)); 0133 #else 0134 w = qMax(w, fm.width(s)); 0135 #endif 0136 s = textFromValue(maximum()); 0137 s.truncate(18); 0138 s += fixedContent; 0139 #if QT_VERSION >= QT_VERSION_CHECK(5,11,0) 0140 w = qMax(w, fm.horizontalAdvance(s)); 0141 #else 0142 w = qMax(w, fm.width(s)); 0143 #endif 0144 0145 0146 w += 2; // cursor blinking space 0147 0148 QStyleOptionSpinBox option; 0149 initStyleOption(&option); 0150 0151 QSize hint(w, h); 0152 0153 KisDoubleParseSpinBox tmp; 0154 m_d->cachedSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &option, hint, &tmp); 0155 } 0156 0157 return m_d->cachedSizeHint; 0158 } 0159 0160 QSize KisAngleSelectorSpinBox::sizeHint() const 0161 { 0162 return minimumSizeHint(); 0163 } 0164 0165 void KisAngleSelectorSpinBox::refreshStyle() 0166 { 0167 m_d->cachedSizeHint = QSize(); 0168 updateGeometry(); 0169 m_d->updateStyleSheet(); 0170 } 0171 0172 struct KisAngleSelector::Private 0173 { 0174 KisAngleSelector *q; 0175 KisAngleGauge *angleGauge; 0176 KisAngleSelectorSpinBox *spinBox; 0177 QToolButton *toolButtonFlipOptions; 0178 QToolButton *toolButtonFlipHorizontally; 0179 QToolButton *toolButtonFlipVertically; 0180 QToolButton *toolButtonFlipHorizontallyAndVertically; 0181 QAction *actionFlipHorizontally; 0182 QAction *actionFlipVertically; 0183 QAction *actionFlipHorizontallyAndVertically; 0184 QAction *actionResetAngle; 0185 QMenu *menuFlip; 0186 0187 KisAngleSelector::FlipOptionsMode flipOptionsMode; 0188 int angleGaugeSize; 0189 0190 void on_angleGauge_angleChanged(qreal angle); 0191 void on_spinBox_valueChanged(double value); 0192 void on_actionFlipHorizontally_triggered(); 0193 void on_actionFlipVertically_triggered(); 0194 void on_actionFlipHorizontallyAndVertically_triggered(); 0195 void on_actionResetAngle_triggered(); 0196 0197 void resizeAngleGauge(); 0198 }; 0199 0200 KisAngleSelector::KisAngleSelector(QWidget* parent) 0201 : QWidget(parent) 0202 , m_d(new Private) 0203 { 0204 m_d->q = this; 0205 0206 QHBoxLayout *mainLayout = new QHBoxLayout; 0207 mainLayout->setSpacing(5); 0208 mainLayout->setContentsMargins(0, 0, 0, 0); 0209 0210 m_d->angleGauge = new KisAngleGauge(this); 0211 m_d->angleGauge->installEventFilter(this); 0212 0213 m_d->spinBox = new KisAngleSelectorSpinBox(this); 0214 m_d->spinBox->setSuffix(i18nc("Degrees symbol", "˚")); 0215 m_d->spinBox->setRange(0, 360); 0216 m_d->spinBox->setWrapping(true); 0217 0218 m_d->actionFlipHorizontally = new QAction(this); 0219 m_d->actionFlipHorizontally->setText( 0220 i18nc( 0221 "Flips the angle horizontally, around the vertical axis", 0222 "Flip the angle horizontally" 0223 ) 0224 ); 0225 m_d->actionFlipVertically = new QAction(this); 0226 m_d->actionFlipVertically->setText( 0227 i18nc( 0228 "Flips the angle vertically, around the horizontal axis", 0229 "Flip the angle vertically" 0230 ) 0231 ); 0232 m_d->actionFlipHorizontallyAndVertically = new QAction(this); 0233 m_d->actionFlipHorizontallyAndVertically->setText( 0234 i18nc( 0235 "Flips the angle horizontally and vertically", 0236 "Flip the angle horizontally and vertically" 0237 ) 0238 ); 0239 QAction *menuSeparator = new QAction(this); 0240 menuSeparator->setSeparator(true); 0241 m_d->actionResetAngle = new QAction(this); 0242 m_d->actionResetAngle->setText( 0243 i18nc( 0244 "Reset the angle to a predefined value", 0245 "Reset angle" 0246 ) 0247 ); 0248 m_d->menuFlip = new QMenu(this); 0249 m_d->menuFlip->addAction(m_d->actionFlipHorizontally); 0250 m_d->menuFlip->addAction(m_d->actionFlipVertically); 0251 m_d->menuFlip->addAction(m_d->actionFlipHorizontallyAndVertically); 0252 m_d->menuFlip->addAction(menuSeparator); 0253 m_d->menuFlip->addAction(m_d->actionResetAngle); 0254 0255 QHBoxLayout *layoutFlipButtons = new QHBoxLayout; 0256 layoutFlipButtons->setSpacing(1); 0257 layoutFlipButtons->setContentsMargins(0, 0, 0, 0); 0258 0259 m_d->toolButtonFlipOptions = new QToolButton(this); 0260 m_d->toolButtonFlipOptions->setPopupMode(QToolButton::InstantPopup); 0261 m_d->toolButtonFlipOptions->setAutoRaise(true); 0262 m_d->toolButtonFlipOptions->setIcon(KisIconUtils::loadIcon("view-choose")); 0263 m_d->toolButtonFlipOptions->setStyleSheet("QToolButton::menu-indicator { image: none; }"); 0264 m_d->toolButtonFlipOptions->setMenu(m_d->menuFlip); 0265 m_d->toolButtonFlipOptions->setFocusPolicy(Qt::StrongFocus); 0266 0267 m_d->toolButtonFlipHorizontally = new QToolButton(this); 0268 m_d->toolButtonFlipHorizontally->setAutoRaise(true); 0269 m_d->toolButtonFlipHorizontally->setIcon(KisIconUtils::loadIcon("flip_angle_h")); 0270 m_d->toolButtonFlipHorizontally->setIconSize(QSize(20, 20)); 0271 m_d->toolButtonFlipHorizontally->setToolTip(m_d->actionFlipHorizontally->text()); 0272 m_d->toolButtonFlipHorizontally->setFocusPolicy(Qt::StrongFocus); 0273 0274 m_d->toolButtonFlipVertically = new QToolButton(this); 0275 m_d->toolButtonFlipVertically->setAutoRaise(true); 0276 m_d->toolButtonFlipVertically->setIcon(KisIconUtils::loadIcon("flip_angle_v")); 0277 m_d->toolButtonFlipVertically->setIconSize(QSize(20, 20)); 0278 m_d->toolButtonFlipVertically->setToolTip(m_d->actionFlipVertically->text()); 0279 m_d->toolButtonFlipVertically->setFocusPolicy(Qt::StrongFocus); 0280 0281 m_d->toolButtonFlipHorizontallyAndVertically = new QToolButton(this); 0282 m_d->toolButtonFlipHorizontallyAndVertically->setAutoRaise(true); 0283 m_d->toolButtonFlipHorizontallyAndVertically->setIcon(KisIconUtils::loadIcon("flip_angle_hv")); 0284 m_d->toolButtonFlipHorizontallyAndVertically->setIconSize(QSize(20, 20)); 0285 m_d->toolButtonFlipHorizontallyAndVertically->setToolTip(m_d->actionFlipHorizontallyAndVertically->text()); 0286 m_d->toolButtonFlipHorizontallyAndVertically->setFocusPolicy(Qt::StrongFocus); 0287 0288 layoutFlipButtons->addWidget(m_d->toolButtonFlipOptions); 0289 layoutFlipButtons->addWidget(m_d->toolButtonFlipHorizontally); 0290 layoutFlipButtons->addWidget(m_d->toolButtonFlipVertically); 0291 layoutFlipButtons->addWidget(m_d->toolButtonFlipHorizontallyAndVertically); 0292 0293 mainLayout->addWidget(m_d->angleGauge); 0294 mainLayout->addWidget(m_d->spinBox); 0295 mainLayout->addLayout(layoutFlipButtons); 0296 0297 setLayout(mainLayout); 0298 0299 setTabOrder(m_d->angleGauge, m_d->spinBox); 0300 setTabOrder(m_d->spinBox, m_d->toolButtonFlipOptions); 0301 setTabOrder(m_d->toolButtonFlipOptions, m_d->toolButtonFlipHorizontally); 0302 setTabOrder(m_d->toolButtonFlipHorizontally, m_d->toolButtonFlipVertically); 0303 setTabOrder(m_d->toolButtonFlipVertically, m_d->toolButtonFlipHorizontallyAndVertically); 0304 0305 setFlipOptionsMode(FlipOptionsMode_Buttons); 0306 setGaugeSize(0); 0307 0308 using namespace std::placeholders; 0309 connect( 0310 m_d->angleGauge, 0311 &KisAngleGauge::angleChanged, 0312 std::bind(&Private::on_angleGauge_angleChanged, m_d.data(), _1) 0313 ); 0314 connect( 0315 m_d->spinBox, 0316 QOverload<double>::of(&KisDoubleParseSpinBox::valueChanged), 0317 std::bind(&Private::on_spinBox_valueChanged, m_d.data(), _1) 0318 ); 0319 connect( 0320 m_d->actionFlipHorizontally, 0321 &QAction::triggered, 0322 std::bind(&Private::on_actionFlipHorizontally_triggered, m_d.data()) 0323 ); 0324 connect( 0325 m_d->actionFlipVertically, 0326 &QAction::triggered, 0327 std::bind(&Private::on_actionFlipVertically_triggered, m_d.data()) 0328 ); 0329 connect( 0330 m_d->actionFlipHorizontallyAndVertically, 0331 &QAction::triggered, 0332 std::bind(&Private::on_actionFlipHorizontallyAndVertically_triggered, m_d.data()) 0333 ); 0334 connect(m_d->actionResetAngle, SIGNAL(triggered()), SLOT(reset())); 0335 connect(m_d->toolButtonFlipHorizontally, SIGNAL(clicked()), m_d->actionFlipHorizontally, SLOT(trigger())); 0336 connect(m_d->toolButtonFlipVertically, SIGNAL(clicked()), m_d->actionFlipVertically, SLOT(trigger())); 0337 connect(m_d->toolButtonFlipHorizontallyAndVertically, SIGNAL(clicked()), m_d->actionFlipHorizontallyAndVertically, SLOT(trigger())); 0338 } 0339 0340 KisAngleSelector::~KisAngleSelector() 0341 {} 0342 0343 qreal KisAngleSelector::angle() const 0344 { 0345 return m_d->spinBox->value(); 0346 } 0347 0348 qreal KisAngleSelector::snapAngle() const 0349 { 0350 return m_d->angleGauge->snapAngle(); 0351 } 0352 0353 qreal KisAngleSelector::resetAngle() const 0354 { 0355 return m_d->angleGauge->resetAngle(); 0356 } 0357 0358 int KisAngleSelector::decimals() const 0359 { 0360 return m_d->spinBox->decimals(); 0361 } 0362 0363 qreal KisAngleSelector::maximum() const 0364 { 0365 return m_d->spinBox->maximum(); 0366 } 0367 0368 qreal KisAngleSelector::minimum() const 0369 { 0370 return m_d->spinBox->minimum(); 0371 } 0372 0373 QString KisAngleSelector::prefix() const 0374 { 0375 return m_d->spinBox->prefix(); 0376 } 0377 0378 bool KisAngleSelector::wrapping() const 0379 { 0380 return m_d->spinBox->wrapping(); 0381 } 0382 0383 KisAngleSelector::FlipOptionsMode KisAngleSelector::flipOptionsMode() const 0384 { 0385 return m_d->flipOptionsMode; 0386 } 0387 0388 int KisAngleSelector::gaugeSize() const 0389 { 0390 return m_d->angleGaugeSize; 0391 } 0392 0393 KisAngleGauge::IncreasingDirection KisAngleSelector::increasingDirection() const 0394 { 0395 return m_d->angleGauge->increasingDirection(); 0396 } 0397 0398 bool KisAngleSelector::isUsingFlatSpinBox() const 0399 { 0400 return m_d->spinBox->isFlat(); 0401 } 0402 0403 void KisAngleSelector::setAngle(qreal newAngle) 0404 { 0405 KisSignalsBlocker angleGaugeSignalsBlocker(m_d->angleGauge); 0406 KisSignalsBlocker spinBoxSignalsBlocker(m_d->spinBox); 0407 0408 const qreal oldAngle = m_d->spinBox->value(); 0409 0410 m_d->spinBox->setValue(newAngle); 0411 m_d->angleGauge->setAngle(m_d->spinBox->value()); 0412 0413 if (qFuzzyCompare(oldAngle, m_d->spinBox->value())) { 0414 return; 0415 } 0416 0417 emit angleChanged(m_d->spinBox->value()); 0418 } 0419 0420 void KisAngleSelector::setSnapAngle(qreal newSnapAngle) 0421 { 0422 m_d->angleGauge->setSnapAngle(newSnapAngle); 0423 } 0424 0425 void KisAngleSelector::setResetAngle(qreal newResetAngle) 0426 { 0427 m_d->angleGauge->setResetAngle(newResetAngle); 0428 } 0429 0430 void KisAngleSelector::setDecimals(int newNumberOfDecimals) 0431 { 0432 m_d->spinBox->setDecimals(newNumberOfDecimals); 0433 } 0434 0435 void KisAngleSelector::setMaximum(qreal newMaximum) 0436 { 0437 m_d->spinBox->setMaximum(newMaximum); 0438 } 0439 0440 void KisAngleSelector::setMinimum(qreal newMinimum) 0441 { 0442 m_d->spinBox->setMinimum(newMinimum); 0443 } 0444 0445 void KisAngleSelector::setRange(qreal newMinimum, qreal newMaximum) 0446 { 0447 m_d->spinBox->setRange(newMinimum, newMaximum); 0448 } 0449 0450 void KisAngleSelector::setPrefix(const QString &newPrefix) 0451 { 0452 m_d->spinBox->setPrefix(newPrefix); 0453 } 0454 0455 void KisAngleSelector::setWrapping(bool newWrapping) 0456 { 0457 m_d->spinBox->setWrapping(newWrapping); 0458 } 0459 0460 void KisAngleSelector::setFlipOptionsMode(FlipOptionsMode newMode) 0461 { 0462 m_d->flipOptionsMode = newMode; 0463 0464 m_d->toolButtonFlipOptions->setVisible(newMode == FlipOptionsMode_MenuButton); 0465 0466 bool useButtons = newMode == FlipOptionsMode_Buttons; 0467 m_d->toolButtonFlipHorizontally->setVisible(useButtons); 0468 m_d->toolButtonFlipVertically->setVisible(useButtons); 0469 m_d->toolButtonFlipHorizontallyAndVertically->setVisible(useButtons); 0470 0471 bool showMenus = newMode != FlipOptionsMode_NoFlipOptions; 0472 m_d->actionFlipHorizontally->setVisible(showMenus); 0473 m_d->actionFlipVertically->setVisible(showMenus); 0474 m_d->actionFlipHorizontallyAndVertically->setVisible(showMenus); 0475 } 0476 0477 void KisAngleSelector::setGaugeSize(int newGaugeSize) 0478 { 0479 if (newGaugeSize < 0) { 0480 return; 0481 } 0482 m_d->angleGaugeSize = newGaugeSize; 0483 m_d->resizeAngleGauge(); 0484 } 0485 0486 void KisAngleSelector::setIncreasingDirection(KisAngleGauge::IncreasingDirection newIncreasingDirection) 0487 { 0488 m_d->angleGauge->setIncreasingDirection(newIncreasingDirection); 0489 } 0490 0491 void KisAngleSelector::useFlatSpinBox(bool newUseFlatSpinBox) 0492 { 0493 m_d->spinBox->setFlat(newUseFlatSpinBox); 0494 } 0495 0496 void KisAngleSelector::reset() 0497 { 0498 m_d->angleGauge->reset(); 0499 } 0500 0501 qreal KisAngleSelector::closestCoterminalAngleInRange(qreal angle, qreal minimum, qreal maximum, bool *ok) 0502 { 0503 bool hasCoterminalAngleInRange = true; 0504 0505 if (angle < minimum) { 0506 const qreal d = minimum - angle; 0507 const qreal cycles = std::floor(d / 360.0) + 1; 0508 angle += cycles * 360.0; 0509 if (angle > maximum) { 0510 hasCoterminalAngleInRange = false; 0511 angle = minimum; 0512 } 0513 } else if (angle > maximum) { 0514 const qreal d = angle - maximum; 0515 const qreal cycles = std::floor(d / 360.0) + 1; 0516 angle -= cycles * 360.0; 0517 if (angle < minimum) { 0518 hasCoterminalAngleInRange = false; 0519 angle = maximum; 0520 } 0521 } 0522 0523 if (ok) { 0524 *ok = hasCoterminalAngleInRange; 0525 } 0526 return angle; 0527 } 0528 0529 qreal KisAngleSelector::closestCoterminalAngleInRange(qreal angle, bool *ok) const 0530 { 0531 return closestCoterminalAngleInRange(angle, m_d->spinBox->minimum(), m_d->spinBox->maximum(), ok); 0532 } 0533 0534 qreal KisAngleSelector::flipAngle(qreal angle, Qt::Orientations orientations) 0535 { 0536 if ((orientations & Qt::Horizontal) && (orientations & Qt::Vertical)) { 0537 angle += 180.0; 0538 } else if (orientations & Qt::Horizontal) { 0539 qreal a = std::fmod(angle, 360.0); 0540 if (a < 0) { 0541 a += 360.0; 0542 } 0543 if (a > 270.0) { 0544 angle -= 2.0 * (a - 270.0); 0545 } else if (a > 180.0) { 0546 angle += 2.0 * (270.0 - a); 0547 } else if (a > 90.0) { 0548 angle -= 2.0 * (a - 90.0); 0549 } else { 0550 angle += 2.0 * (90.0 - a); 0551 } 0552 } else if (orientations & Qt::Vertical) { 0553 qreal a = std::fmod(angle, 360.0); 0554 if (a < 0) { 0555 a += 360.0; 0556 } 0557 if (a > 270.0) { 0558 angle += 2.0 * (360.0 - a); 0559 } else if (a > 180.0) { 0560 angle -= 2.0 * (a - 180.0); 0561 } else if (a > 90.0) { 0562 angle += 2.0 * (180.0 - a); 0563 } else { 0564 angle -= 2.0 * a; 0565 } 0566 } 0567 0568 return angle; 0569 } 0570 0571 qreal KisAngleSelector::flipAngle(qreal angle, qreal minimum, qreal maximum, Qt::Orientations orientations, bool *ok) 0572 { 0573 return closestCoterminalAngleInRange(flipAngle(angle, orientations), minimum, maximum, ok); 0574 } 0575 0576 void KisAngleSelector::flip(Qt::Orientations orientations) 0577 { 0578 bool ok = false; 0579 qreal flippedAngle = flipAngle(angle(), minimum(), maximum(), orientations, &ok); 0580 if (ok) { 0581 setAngle(flippedAngle); 0582 } 0583 } 0584 0585 bool KisAngleSelector::event(QEvent *e) 0586 { 0587 if (e->type() == QEvent::PaletteChange) { 0588 // For some reason the spinbox, that uses stylesheets, doesn't update 0589 // on palette changes, so we reset the stylesheet to force an update. 0590 // Calling m_d->spinBox->update() doesn't work 0591 m_d->spinBox->refreshStyle(); 0592 } else if (e->type() == QEvent::StyleChange || e->type() == QEvent::FontChange) { 0593 // Temporarily reset the spin box style so that we can get its 0594 // height size hint 0595 m_d->spinBox->refreshStyle(); 0596 m_d->resizeAngleGauge(); 0597 } 0598 return QWidget::event(e); 0599 } 0600 0601 bool KisAngleSelector::eventFilter(QObject *o, QEvent *e) 0602 { 0603 QWidget *w = qobject_cast<QWidget*>(o); 0604 if (w != m_d->angleGauge || !w->isEnabled() || !e || e->type() != QEvent::ContextMenu) { 0605 return false; 0606 } 0607 QContextMenuEvent *cme = static_cast<QContextMenuEvent*>(e); 0608 0609 m_d->menuFlip->exec(cme->globalPos()); 0610 return true; 0611 } 0612 0613 void KisAngleSelector::Private::on_angleGauge_angleChanged(qreal angle) 0614 { 0615 q->setAngle(q->closestCoterminalAngleInRange(angle)); 0616 } 0617 0618 void KisAngleSelector::Private::on_spinBox_valueChanged(double value) 0619 { 0620 KisSignalsBlocker angleGaugeSignalsBlocker(angleGauge); 0621 0622 angleGauge->setAngle(value); 0623 0624 emit q->angleChanged(value); 0625 } 0626 0627 void KisAngleSelector::Private::on_actionFlipHorizontally_triggered() 0628 { 0629 q->flip(Qt::Horizontal); 0630 } 0631 0632 void KisAngleSelector::Private::on_actionFlipVertically_triggered() 0633 { 0634 q->flip(Qt::Vertical); 0635 } 0636 0637 void KisAngleSelector::Private::on_actionFlipHorizontallyAndVertically_triggered() 0638 { 0639 q->flip(Qt::Horizontal | Qt::Vertical); 0640 } 0641 0642 void KisAngleSelector::Private::resizeAngleGauge() 0643 { 0644 if (angleGaugeSize == 0) { 0645 angleGauge->setFixedSize(spinBox->sizeHint().height(), spinBox->sizeHint().height()); 0646 } else { 0647 angleGauge->setFixedSize(angleGaugeSize, angleGaugeSize); 0648 } 0649 }