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

0001 /*
0002  * SPDX-FileCopyrightText: 2010 Justin Noel <justin@ics.com>
0003  * SPDX-FileCopyrightText: 2021 Deif Lou <ginoba@gmail.com>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #ifndef LIBKIS_SLIDERSPINBOX_H
0009 #define LIBKIS_SLIDERSPINBOX_H
0010 
0011 #include "kis_slider_spin_box.h"
0012 #include "IntParseSpinBox.h"
0013 #include "DoubleParseSpinBox.h"
0014 
0015 #include "kritalibkis_export.h"
0016 #include "libkis.h"
0017 
0018 template <typename SpinBoxTypeTP, typename BaseSpinBoxTypeTP>
0019 class KisSliderSpinBoxPrivate;
0020 
0021 /**
0022  * @brief This class is a wrapper around KisSliderSpinBox, a spinbox in which 
0023  * you can click and drag to set the value, with a slider like bar displayed
0024  * inside. The widget itself is accessed with the widget() function.
0025  * 
0026  * The value can be set by click and dragging with the mouse or pen or by
0027  * typing in with the keyboard. To enter the edit mode, in which the keyboard
0028  * can be used, one has to right-click inside the spinbox or click and hold
0029  * the pointer inside or press the enter key. To leave the edit mode, one
0030  * can press the enter key again, in which case the value is committed, or
0031  * press the escape key, in which case the value is rejected.
0032  * 
0033  * When dragging with the pointer, one can fine tune the value by dragging
0034  * far away vertically from the spinbox. The farther the pointer is, the
0035  * slower the value will change. If the pointer is inside the spinbox plus
0036  * a certain margin, the value will not be scaled.
0037  * By pressing the shift key the slow down will be even more pronounced and
0038  * by pressing the control key the value will snap to the increment set by
0039  * @ref setFastSliderStep. The two keys can be used at the same time.
0040  * 
0041  * A "soft range" can be set to make the slider display only a sub-range of the
0042  * spinbox range. This way one can have a large range but display and set with
0043  * the pointer and with more precision only the most commonly used sub-set
0044  * of values.
0045  * A value outside the "soft range" can be set by entering the edit
0046  * mode and using the keyboard.
0047  * The "soft range" is considered valid if the "soft maximum" is greater than
0048  * the "soft minimum".
0049  */
0050 class KRITALIBKIS_EXPORT SliderSpinBox : public IntParseSpinBox
0051 {
0052     Q_OBJECT
0053     Q_DISABLE_COPY(SliderSpinBox)
0054 
0055 
0056 public:
0057     explicit SliderSpinBox();
0058     ~SliderSpinBox() override;
0059 
0060 public Q_SLOTS:
0061 
0062     /**
0063      * @brief Get the internal KisSliderSpinBox as a QWidget, so it may be
0064      * added to a UI
0065      * 
0066      * @return the internal KisSliderSpinBox as a QWidget
0067      */
0068     QWidget* widget() const;
0069 
0070     /**
0071      * @brief Get the value to which multiples the spinbox value snaps when
0072      * the control key is pressed
0073      * 
0074      * @return the value to which multiples the spinbox value snaps when
0075      * the control key is pressed
0076      * @see setFastSliderStep(int)
0077      */
0078     int fastSliderStep() const;
0079     /**
0080      * @brief Get the minimum value of the "soft range"
0081      * @return the minimum value of the "soft range"
0082      * @see setSoftMinimum(int) 
0083      * @see setSoftRange(int, int) 
0084      * @see softMaximum() const 
0085      */
0086     int softMinimum() const;
0087     /**
0088      * @brief Get the maximum value of the "soft range"
0089      * @return the maximum value of the "soft range"
0090      * @see setSoftMaximum(int) 
0091      * @see setSoftRange(int, int) 
0092      * @see softMinimum) const 
0093      */
0094     int softMaximum() const;
0095     /**
0096      * @brief Get if the user is currently dragging the slider with the pointer
0097      * @return true if the user is currently dragging the slider with the
0098      * pointer, false otherwise
0099      */
0100     bool isDragging() const;
0101     /**
0102      * @brief Set the value
0103      * @param newValue the new value
0104      */
0105     void setValue(int newValue);
0106     /**
0107      * @brief Set the minimum and the maximum values of the range, computing
0108      * a new "fast slider step" based on the range if required
0109      * 
0110      * The soft range will be adapted to fit inside the range
0111      * @param newMinimum the new minimum value
0112      * @param newMaximum the new maximum value
0113      * @param computeNewFastSliderStep true if a new "fast slider step"
0114      * must be computed based on the range
0115      * @see setMinimum(int)
0116      * @see setMaximum(int)
0117      */
0118     void setRange(int newMinimum, int newMaximum, bool computeNewFastSliderStep = true);
0119     /**
0120      * @brief Set the minimum value of the range
0121      * 
0122      * The soft range will be adapted to fit inside the range
0123      * @param newMinimum the new minimum value
0124      * @param computeNewFastSliderStep true if a new "fast slider step"
0125      * must be computed based on the range
0126      * @see setRange(int,int)
0127      * @see setMaximum(int)
0128      */
0129     void setMinimum(int newMinimum, bool computeNewFastSliderStep = true);
0130     /**
0131      * @brief Set the maximum value of the range
0132      * 
0133      * The soft range will be adapted to fit inside the range
0134      * @param newMaximum the new maximum value
0135      * @param computeNewFastSliderStep true if a new "fast slider step"
0136      * must be computed based on the range
0137      * @see setRange(int,int)
0138      * @see setMinimum(int)
0139      */
0140     void setMaximum(int newMaximum, bool computeNewFastSliderStep = true);
0141     /**
0142      * @brief Set the exponent used by a power function to modify the values
0143      * as a function of the horizontal position.
0144      * 
0145      * This allows having more values concentrated in one side of the
0146      * slider than the other
0147      * @param newExponentRatio the new exponent to be used by the power function
0148      */
0149     void setExponentRatio(qreal newExponentRatio);
0150     /**
0151      * @brief Set if the spinbox should not emit signals when dragging the
0152      * slider.
0153      * 
0154      * This is useful to prevent multiple updates when changing the value if
0155      * the update operation is costly.
0156      * A valueChanged signal will be emitted when the pointer is released from
0157      * the slider.
0158      * @param newBlockUpdateSignalOnDrag true if the spinbox should not emit
0159      * signals when dragging the slider. false otherwise
0160      */
0161     void setBlockUpdateSignalOnDrag(bool newBlockUpdateSignalOnDrag);
0162     /**
0163      * @brief Set the value to which multiples the spinbox value snaps when
0164      * the control key is pressed
0165      * @param newFastSliderStep value to which multiples the spinbox value
0166      * snaps when the control key is pressed
0167      * @see fastSliderStep() const
0168      */
0169     void setFastSliderStep(int newFastSliderStep);
0170     /**
0171      * @brief Set the minimum and the maximum values of the soft range
0172      * @param newSoftMinimum the new minimum value
0173      * @param newSoftMaximum the new maximum value
0174      * @see setSoftMinimum(int)
0175      * @see setSoftMaximum(int)
0176      * @see softMinimum() const
0177      * @see softMaximum() const
0178      */
0179     void setSoftRange(int newSoftMinimum, int newSoftMaximum);
0180     /**
0181      * @brief Set the minimum value of the soft range
0182      * @param newSoftMinimum the new minimum value
0183      * @see setSoftRange(int,int)
0184      * @see setSoftMaximum(int)
0185      * @see softMinimum() const
0186      * @see softMaximum() const
0187      */
0188     void setSoftMinimum(int newSoftMinimum);
0189     /**
0190      * @brief Set the maximum value of the soft range
0191      * @param newSoftMaximum the new maximum value
0192      * @see setSoftRange(int,int)
0193      * @see setSoftMinimum(int)
0194      * @see softMinimum() const
0195      * @see softMaximum() const
0196      */
0197     void setSoftMaximum(int newSoftMaximum);
0198 
0199 Q_SIGNALS:
0200     void draggingFinished();
0201 
0202 private:
0203     struct Private;
0204     Private *const d;
0205 };
0206 
0207 /**
0208  * @brief This class is a wrapper around KisDoubleSliderSpinBox, a spinbox in
0209  * which you can click and drag to set the value, with a slider like bar
0210  * displayed inside. The widget itself is accessed with the widget() function.
0211  * 
0212  * @see SliderSpinBox
0213  */
0214 class KRITALIBKIS_EXPORT DoubleSliderSpinBox : public DoubleParseSpinBox
0215 {
0216     Q_OBJECT
0217     Q_DISABLE_COPY(DoubleSliderSpinBox)
0218 
0219 public:
0220     explicit DoubleSliderSpinBox();
0221     ~DoubleSliderSpinBox() override;
0222 
0223 public Q_SLOTS:
0224 
0225     /**
0226      * @brief Get the internal KisDoubleSliderSpinBox as a QWidget, so it may be
0227      * added to a UI
0228      * 
0229      * @return the internal KisDoubleSliderSpinBox as a QWidget
0230      */
0231     QWidget* widget() const;
0232 
0233     qreal fastSliderStep() const;
0234     qreal softMinimum() const;
0235     qreal softMaximum() const;
0236     bool isDragging() const;
0237     void setValue(qreal newValue);
0238     /**
0239      * @brief Set the minimum and the maximum values of the range
0240      * 
0241      * The soft range will be adapted to fit inside the range
0242      * The number of decimals used can be changed with the newNumberOfDecimals
0243      * parameter
0244      * @param newMinimum the new minimum value
0245      * @param newMaximum the new maximum value
0246      * @param newNumberOfDecimals the new number of decimals
0247      * @param computeNewFastSliderStep true if a new "fast slider step"
0248      * must be computed based on the range
0249      * @see setMinimum(qreal)
0250      * @see setMaximum(qreal)
0251      */
0252     void setRange(qreal newMinimum, qreal newMaximum, int newNumberOfDecimals = 0, bool computeNewFastSliderStep = true);
0253     void setMinimum(qreal newMinimum, bool computeNewFastSliderStep = true);
0254     void setMaximum(qreal newMaximum, bool computeNewFastSliderStep = true);
0255     void setExponentRatio(qreal newExponentRatio);
0256     void setBlockUpdateSignalOnDrag(bool newBlockUpdateSignalOnDrag);
0257     void setFastSliderStep(qreal newFastSliderStep);
0258     void setSoftRange(qreal newSoftMinimum, qreal newSoftMaximum);
0259     void setSoftMinimum(qreal newSoftMinimum);
0260     void setSoftMaximum(qreal newSoftMaximum);
0261 
0262 Q_SIGNALS:
0263     void draggingFinished();
0264 
0265 private:
0266     struct Private;
0267     Private *const d;
0268 };
0269 
0270 #endif // LIBKIS_SLIDERSPINBOX_H