File indexing completed on 2024-05-19 04:26:53

0001 /*
0002  *  SPDX-FileCopyrightText: 2020 Deif Lou <ginoba@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #ifndef LIBKIS_ANGLESELECTOR_H
0007 #define LIBKIS_ANGLESELECTOR_H
0008 
0009 #include "KisAngleSelector.h"
0010 
0011 #include "kritalibkis_export.h"
0012 #include "libkis.h"
0013 
0014 /**
0015  * @brief A wrapper around KisAngleSelector, a widget with several options to
0016  * select an angle. The widget itself is accessed with the widget() function.
0017  * 
0018  * This widget is a combination of a @ref KisAngleGauge and a spin box,
0019  * along with some flipping options
0020  */
0021 class KRITALIBKIS_EXPORT AngleSelector : public QObject
0022 {
0023     Q_OBJECT
0024     Q_DISABLE_COPY(AngleSelector)
0025 
0026 public:
0027     explicit AngleSelector();
0028     ~AngleSelector() override;
0029 
0030 public Q_SLOTS:
0031 
0032     /**
0033      * @brief Get the internal KisAngleSelector as a QWidget, so it may be
0034      * added to a UI
0035      * 
0036      * @return the internal KisAngleSelector as a QWidget
0037      */
0038     QWidget* widget() const;
0039 
0040     /**
0041      * @brief Sets the current angle
0042      * @param newAngle the new angle
0043      * @see angle() const
0044      */
0045     void setAngle(qreal newAngle);
0046     /**
0047      * @brief Sets the current angle to the reset angle
0048      * @see resetAngle() const
0049      * @see setResetAngle(qreal) const
0050      */
0051     void reset();
0052 
0053     /**
0054      * @brief Gets the current angle
0055      * @return The current angle 
0056      * @see setAngle(qreal)
0057      */
0058     qreal angle() const;
0059     /**
0060      * @brief Gets the angle to which multiples the selected angle will snap
0061      * 
0062      * The default snap angle is 15 degrees so the selected angle will snap
0063      * to its multiples (0, 15, 30, 45, etc.)
0064      * @return The angle to which multiples the selected angle will snap
0065      * @see setSnapAngle(qreal)
0066      */
0067     qreal snapAngle() const;
0068     /**
0069      * @brief Gets the angle that is used to reset the current angle
0070      * 
0071      * This angle is used when the user double clicks on the widget
0072      * @return The angle that is used to reset the current angle
0073      * @see setResetAngle(qreal)
0074      */
0075     qreal resetAngle() const;
0076     /**
0077      * @brief Gets the number of decimals (precision) used by the angle
0078      * 
0079      * If you want to simulate integer angles, set it to 0. The default is 2.
0080      * @return The number of decimals being used
0081      * @see setDecimals(int)
0082      */
0083     int decimals() const;
0084     /**
0085      * @brief Gets the maximum value for the angle
0086      * 
0087      * The default is 360
0088      * @return The maximum value for the angle
0089      * @see setMaximum(qreal)
0090      * @see setRange(qreal, qreal)
0091      */
0092     qreal maximum() const;
0093     /**
0094      * @brief Gets the minimum value for the angle
0095      * 
0096      * The default is 0
0097      * @return The minimum value for the angle
0098      * @see setMinimum(qreal)
0099      * @see setRange(qreal, qreal)
0100      */
0101     qreal minimum() const;
0102     /**
0103      * @brief Gets the prefix shown in the spin box
0104      * @return The prefix shown in the spin box
0105      * @see setPrefix(const QString&)
0106      */
0107     QString prefix() const;
0108     /**
0109      * @brief Gets if the angle should wrap pass the minimum or maximum angles
0110      * @return True if the angle should wrap pass the minimum or maximum angles,
0111      * false otherwise
0112      * @see setWrapping(bool)
0113      */
0114     bool wrapping() const;
0115     /**
0116      * @brief Gets the mode in which the flip options should be shown
0117      * 
0118      * The default is Buttons
0119      * @return The mode in which the flip options should be shown.
0120      * @see setFlipOptionsMode(QString)
0121      */
0122     QString flipOptionsMode() const;
0123     /**
0124      * @brief Gets the common height of the widgets inside this angle selector
0125      * @return The height of the internal widgets (angle gauge, spin box, etc.).
0126      *         Returns 0 if each widget has its default height.
0127      * @see setWidgetsHeight(int)
0128      */
0129     int widgetsHeight() const;
0130     /**
0131      * @brief Gets the direction in which the angle increases in the angle gauge
0132      * @return The direction in which the angle increases
0133      * @see setIncreasingDirection(QString)
0134      */
0135     QString increasingDirection() const;
0136     /**
0137      * @brief Gets if the spin box is flat (no border or background)
0138      * @return True if the spin box is flat, false otherwise
0139      * @see useFlatSpinBox(bool)
0140      */
0141     bool isUsingFlatSpinBox() const;
0142     
0143     /**
0144      * @brief Sets the angle to which multiples the selected angle will snap
0145      * @param newSnapAngle the new angle to which multiples the selected angle will snap
0146      * @see snapAngle() const
0147      */
0148     void setSnapAngle(qreal newSnapAngle);
0149     /**
0150      * @brief Sets the angle that is used to reset the current angle
0151      * @param newResetAngle the new angle that is used to reset the current angle
0152      * @see resetAngle() const
0153      */
0154     void setResetAngle(qreal newResetAngle);
0155     /**
0156      * @brief Sets the number of decimals (precision) used by the angle
0157      * @param newNumberOfDecimals the new number of decimals used by the angle
0158      * @see decimals() const
0159      */
0160     void setDecimals(int newNumberOfDecimals);
0161     /**
0162      * @brief Sets the maximum value for the angle
0163      * @param newMaximum the new maximum value for the angle
0164      * @see maximum() const
0165      * @see setRange(qreal, qreal)
0166      */
0167     void setMaximum(qreal newMaximum);
0168     /**
0169      * @brief Sets the minimum value for the angle
0170      * @param newMinimum the new minimum value for the angle
0171      * @see minimum() const
0172      * @see setRange(qreal, qreal)
0173      */
0174     void setMinimum(qreal newMinimum);
0175     /**
0176      * @brief Sets the minimum and maximum values for the angle
0177      * @param newMinimum the new minimum value for the angle
0178      * @param newMaximum the new maximum value for the angle
0179      * @see minimum() const
0180      * @see maximum() const
0181      * @see setMinimum(qreal)
0182      * @see setMaximum(qreal)
0183      */
0184     void setRange(qreal newMinimum, qreal newMaximum);
0185     /**
0186      * @brief Sets the prefix shown in the spin box
0187      * @param newPrefix the new prefix for the spin box
0188      * @see prefix() const
0189      */
0190     void setPrefix(const QString &newPrefix);
0191     /**
0192      * @brief Sets if the angle should wrap pass the minimum or maximum angles
0193      * @param newWrapping true if the angle should wrap pass the minimum or
0194      * maximum angles, false otherwise
0195      * @see wrapping() const
0196      */
0197     void setWrapping(bool newWrapping);
0198     /**
0199      * @brief Sets the mode in which the flip options should be shown
0200      * @param newMode the new mode in which the flip options should be shown
0201      * Valid arguments:
0202      * <ul>
0203      * <li>NoFlipOptions - There are no flip options available</li>
0204      * <li>MenuButton - The flip options are shown as a menu accessible via a options button</li>
0205      * <li>Buttons - The flip options are shown as individual buttons</li>
0206      * <li>ContextMenu - The flip options are shown only as a context menu when right-clicking the gauge widget</li>
0207      * <ul>
0208      * 
0209      * @see flipOptionsMode() const
0210      */
0211     void setFlipOptionsMode(QString newMode);
0212     /**
0213      * @brief Sets the common height of the widgets inside this angle selector.
0214      *        Use 0 to reset widgets to default height.
0215      * @param newHeight the new height of the internal widgets (angle gauge, spin box, etc.)
0216      * @see widgetsHeight() const
0217      */
0218     void setWidgetsHeight(int newHeight);
0219     /**
0220      * @brief Sets the increasing direction in the angle gauge
0221      * @param newIncreasingDirection The new increasing direction
0222      * Valid arguments: CounterClockwise or Clockwise.
0223      * @see increasingDirection() const
0224      */
0225     void setIncreasingDirection(QString newIncreasingDirection);
0226     /**
0227      * @brief Sets if the spin box should be flat
0228      * @param newUseFlatSpinBox True if the spin box should be flat,
0229      * false otherwise
0230      * @see isUsingFlatSpinBox() const
0231      */
0232     void useFlatSpinBox(bool newUseFlatSpinBox);
0233 
0234     /**
0235      * @brief Gets the closest coterminal angle to the provided angle
0236      * that is in the range provided
0237      * 
0238      * A coterminal angle to the provided angle is one that differs
0239      * in size by an integer multiple of a turn (360 degrees)
0240      * @param angle The reference angle for which the function will try to
0241      * find a coterminal angle
0242      * @param minimum The range's lower bound
0243      * @param maximum The range's upper bound
0244      * @param[out] ok This parameter will be set to true if a coterminal
0245      * angle exists in the provided range, or to false otherwise
0246      * @return The closest coterminal angle in the provided range if one exists,
0247      * or the closest value in the range (the minimum or maximum) otherwise.
0248      * If the reference angle is already in the range then it is returned
0249      */
0250     static qreal closestCoterminalAngleInRange(qreal angle, qreal minimum, qreal maximum, bool *ok = nullptr);
0251     /**
0252      * @brief Gets the closest coterminal angle to the provided angle
0253      * that is in the range established
0254      * 
0255      * A coterminal angle to the provided angle is one that differs
0256      * in size by an integer multiple of a turn (360 degrees)
0257      * @param angle The reference angle for which the function will try to
0258      * find a coterminal angle
0259      * @param[out] ok This parameter will be set to true if a coterminal
0260      * angle exists in the specified range, or to false otherwise
0261      * @return The closest coterminal angle in the specified range if one exists,
0262      * or the closest value in the range (the minimum or maximum) otherwise.
0263      * If the reference angle is already in the range then it is returned
0264      */
0265     qreal closestCoterminalAngleInRange(qreal angle, bool *ok = nullptr) const;
0266     /**
0267      * @brief Flips an angle horizontally, vertically, or both
0268      * 
0269      * This function will always try to get the closest angle to the
0270      * provided one that satisfies the flipping requirements
0271      * @param angle The angle to be flipped
0272      * @param orientations Flags indicating in which directions the angle should
0273      * be flipped
0274      * @return The flipped angle
0275      */
0276     static qreal flipAngle(qreal angle, Qt::Orientations orientations);
0277     /**
0278      * @brief Flips an angle horizontally, vertically, or both
0279      * 
0280      * This function will always try to get the closest angle to the
0281      * provided one that satisfies the flipping requirements
0282      * @param angle The angle to be flipped
0283      * @param minimum The lower bound of the valid range
0284      * @param maximum The upper bound of the valid range
0285      * @param orientations Flags indicating in which directions the angle should
0286      * be flipped
0287      * @param[out] ok This parameter will be set to true if the flipped
0288      * angle is in the provided range, or to false otherwise
0289      * @return The flipped angle if it lies in the provided range or the
0290      * closest value in the range (the minimum or maximum) otherwise
0291      */
0292     static qreal flipAngle(qreal angle, qreal minimum, qreal maximum, Qt::Orientations orientations, bool *ok = nullptr);
0293     /**
0294      * @brief Flips the angle horizontally, vertically, or both
0295      * 
0296      * This function will always try to set the closest angle to the
0297      * stablished one that satisfies the flipping requirements
0298      * @param orientations Flags indicating in which directions the angle should
0299      * be flipped
0300      */
0301     void flip(Qt::Orientations orientations);
0302 
0303 Q_SIGNALS:
0304     void angleChanged(qreal angle);
0305 
0306 private:
0307     struct Private;
0308     Private *const d;
0309 
0310 };
0311 
0312 #endif // LIBKIS_ANGLESELECTOR_H