Warning, file /graphics/glaxnimate/src/gui/widgets/spin2d.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #include "spin2d.hpp"
0008 
0009 #include <QHBoxLayout>
0010 #include <QStyleOptionSpinBox>
0011 #include <KLocalizedString>
0012 #include "glaxnimate_app.hpp"
0013 
0014 using namespace glaxnimate::gui;
0015 
0016 
0017 Spin2D::Spin2D(QWidget* parent)
0018     : QWidget(parent)
0019 {
0020     QHBoxLayout* lay = new QHBoxLayout(this);
0021     setLayout(lay);
0022     spin_x = new SmallerSpinBox(true, this);
0023     void (QDoubleSpinBox::*sig)(qreal) = &QDoubleSpinBox::valueChanged;
0024     connect(spin_x, sig, this, &Spin2D::x_changed);
0025     lay->addWidget(spin_x);
0026     spin_y = new SmallerSpinBox(true, this);
0027     connect(spin_y, sig, this, &Spin2D::y_changed);
0028     lay->addWidget(spin_y);
0029     lay->setContentsMargins(0, 0, 0, 0);
0030 
0031 }
0032 
0033 Spin2D::Spin2D(bool ratio_lock, QWidget* parent)
0034     : Spin2D(parent)
0035 {
0036     if ( ratio_lock )
0037         enable_ratio_lock();
0038 }
0039 
0040 void Spin2D::enable_ratio_lock()
0041 {
0042     if ( lock )
0043         return;
0044 
0045     lock = new QToolButton(this);
0046     lock->setCheckable(true);
0047 #ifdef Q_OS_ANDROID
0048     lock->setIconSize(QSize(50, 50));
0049 #endif
0050     lock_toggled(false);
0051     connect(lock, &QToolButton::clicked, this, &Spin2D::lock_toggled);
0052     static_cast<QHBoxLayout*>(layout())->addWidget(lock);
0053     retranslate();
0054 }
0055 
0056 int SmallerSpinBox::get_spin_size(const QAbstractSpinBox* box)
0057 {
0058     static int spin_size;
0059     if ( spin_size == 0 )
0060     {
0061         const QFontMetrics fm(box->fontMetrics());
0062         QString s = "999.99";
0063 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
0064         int w = qMax(0, fm.boundingRect(s).width());
0065 #else
0066         int w = qMax(0, fm.horizontalAdvance(s));
0067 #endif
0068         w += 2; // cursor blinking space
0069 
0070         QStyleOptionSpinBox option;
0071         option.initFrom(box);
0072         QSize hint(w, box->height());
0073         option.subControls = QStyle::SC_SpinBoxEditField | QStyle::SC_SpinBoxFrame | QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown;
0074         option.frame = box->hasFrame();
0075         spin_size = box->style()->sizeFromContents(QStyle::CT_SpinBox, &option, hint, box).width();
0076     }
0077 
0078     return spin_size;
0079 }
0080 
0081 void Spin2D::changeEvent(QEvent* e)
0082 {
0083     QWidget::changeEvent(e);
0084     if ( e->type() == QEvent::LanguageChange)
0085     {
0086         retranslate();
0087     }
0088 }
0089 
0090 void Spin2D::retranslate()
0091 {
0092     if ( lock )
0093         lock->setToolTip(i18n("Lock Ratio"));
0094 }
0095 
0096 void Spin2D::lock_toggled(bool on)
0097 {
0098     if ( on )
0099     {
0100         if ( y() != 0 )
0101             ratio = x() / y();
0102         lock->setIcon(QIcon::fromTheme("object-locked"));
0103     }
0104     else
0105     {
0106         lock->setIcon(QIcon::fromTheme("object-unlocked"));
0107     }
0108 }
0109 
0110 bool Spin2D::ratio_lock() const
0111 {
0112     return lock && lock->isChecked();
0113 }
0114 
0115 void Spin2D::set_value(const QPointF& v)
0116 {
0117     set_value(v.x(), v.y());
0118 }
0119 
0120 void Spin2D::set_value(const QSizeF& v)
0121 {
0122     spin_x->setMinimum(0);
0123     spin_y->setMinimum(0);
0124     set_value(v.width(), v.height());
0125 }
0126 
0127 void Spin2D::set_value(const QVector2D& v)
0128 {
0129     spin_x->setSuffix(i18n("%"));
0130     spin_y->setSuffix(i18n("%"));
0131     spin_x->setDecimals(0);
0132     spin_y->setDecimals(0);
0133     set_value(v.x() * 100, v.y() * 100);
0134 }
0135 
0136 void Spin2D::set_value(qreal x, qreal y)
0137 {
0138     bool bx = spin_x->blockSignals(true);
0139     bool by = spin_y->blockSignals(true);
0140     spin_x->setValue(x);
0141     spin_y->setValue(y);
0142     if ( ratio_lock() && y != 0 )
0143         ratio = x / y;
0144     spin_x->blockSignals(bx);
0145     spin_y->blockSignals(by);
0146 }
0147 
0148 qreal Spin2D::x() const
0149 {
0150     return spin_x->value();
0151 }
0152 
0153 qreal Spin2D::y() const
0154 {
0155     return spin_y->value();
0156 }
0157 
0158 QPointF Spin2D::value_point() const
0159 {
0160     return {x(), y()};
0161 }
0162 
0163 QSizeF Spin2D::value_size() const
0164 {
0165     return {x(), y()};
0166 }
0167 
0168 QVector2D Spin2D::value_vector() const
0169 {
0170     return QVector2D(x() / 100, y() / 100);
0171 }
0172 
0173 void Spin2D::x_changed(qreal x)
0174 {
0175     if ( ratio_lock() && ratio != 0)
0176     {
0177         bool b = spin_y->blockSignals(true);
0178         spin_y->setValue(x / ratio);
0179         spin_y->blockSignals(b);
0180     }
0181     Q_EMIT value_changed();
0182 }
0183 
0184 void Spin2D::y_changed(qreal y)
0185 {
0186     if ( ratio_lock() && ratio != 0)
0187     {
0188         bool b = spin_x->blockSignals(true);
0189         spin_x->setValue(y * ratio);
0190         spin_x->blockSignals(b);
0191     }
0192     Q_EMIT value_changed();
0193 }
0194 
0195 void Spin2D::set_decimals(int decimals)
0196 {
0197     spin_x->setDecimals(decimals);
0198     spin_y->setDecimals(decimals);
0199 }