File indexing completed on 2024-05-12 16:02:28
0001 /* This file is part of the KDE project 0002 * 0003 * SPDX-FileCopyrightText: 2010 Justin Noel <justin@ics.com> 0004 * SPDX-FileCopyrightText: 2021 Deif Lou <ginoba@gmail.com> 0005 * 0006 * SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #ifndef KISSLIDERSPINBOX_H 0010 #define KISSLIDERSPINBOX_H 0011 0012 #include <QScopedPointer> 0013 0014 #include <kis_int_parse_spin_box.h> 0015 #include <kis_double_parse_spin_box.h> 0016 0017 #include <kritawidgetutils_export.h> 0018 0019 template <typename SpinBoxTypeTP, typename BaseSpinBoxTypeTP> 0020 class KisSliderSpinBoxPrivate; 0021 0022 /** 0023 * @brief This class is a spinbox in which you can click and drag to set 0024 * the value. A slider like bar is displayed inside. 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 KRITAWIDGETUTILS_EXPORT KisSliderSpinBox : public KisIntParseSpinBox 0051 { 0052 Q_OBJECT 0053 public: 0054 KisSliderSpinBox(QWidget * parent = nullptr); 0055 ~KisSliderSpinBox() override; 0056 0057 /** 0058 * @brief Get the value to which multiples the sinbox value snaps when 0059 * the control key is pressed 0060 * 0061 * @return the value to which multiples the spinbox value snaps when 0062 * the control key is pressed 0063 * @see setFastSliderStep(int) 0064 */ 0065 int fastSliderStep() const; 0066 /** 0067 * @brief Get the minimum value of the "soft range" 0068 * @return the minimum value of the "soft range" 0069 * @see setSoftMinimum(int) 0070 * @see setSoftRange(int, int) 0071 * @see softMaximum() const 0072 */ 0073 int softMinimum() const; 0074 /** 0075 * @brief Get the maximum value of the "soft range" 0076 * @return the maximum value of the "soft range" 0077 * @see setSoftMaximum(int) 0078 * @see setSoftRange(int, int) 0079 * @see softMinimum) const 0080 */ 0081 int softMaximum() const; 0082 /** 0083 * @brief Get if the user is currently dragging the slider with the pointer 0084 * @return true if the user is currently dragging the slider with the 0085 * pointer, false otherwise 0086 */ 0087 bool isDragging() const; 0088 /** 0089 * @brief Set the value 0090 * @param newValue the new value 0091 */ 0092 QSize sizeHint() const override; 0093 QSize minimumSizeHint() const override; 0094 void setValue(int newValue); 0095 /** 0096 * @brief Set the minimum and the maximum values of the range, computing 0097 * a new "fast slider step" based on the range if required 0098 * 0099 * The soft range will be adapted to fit inside the range 0100 * @param newMinimum the new minimum value 0101 * @param newMaximum the new maximum value 0102 * @param computeNewFastSliderStep true if a new "fast slider step" 0103 * must be computed based on the range 0104 * @see setMinimum(int) 0105 * @see setMaximum(int) 0106 */ 0107 void setRange(int newMinimum, int newMaximum, bool computeNewFastSliderStep = true); 0108 /** 0109 * @brief Set the minimum value of the range 0110 * 0111 * The soft range will be adapted to fit inside the range 0112 * @param newMinimum the new minimum value 0113 * @param computeNewFastSliderStep true if a new "fast slider step" 0114 * must be computed based on the range 0115 * @see setRange(int,int) 0116 * @see setMaximum(int) 0117 */ 0118 void setMinimum(int newMinimum, bool computeNewFastSliderStep = true); 0119 /** 0120 * @brief Set the maximum value of the range 0121 * 0122 * The soft range will be adapted to fit inside the range 0123 * @param newMaximum the new maximum 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 setMinimum(int) 0128 */ 0129 void setMaximum(int newMaximum, bool computeNewFastSliderStep = true); 0130 /** 0131 * @brief Set the exponent used by a power function to modify the values 0132 * as a function of the horizontal position. 0133 * 0134 * This allows having more values concentrated in one side of the 0135 * slider than the other 0136 * @param newExponentRatio the new exponent to be used by the power function 0137 */ 0138 void setExponentRatio(qreal newExponentRatio); 0139 /** 0140 * @brief Set if the spinbox should not emit signals when dragging the 0141 * slider. 0142 * 0143 * This is useful to prevent multiple updates when changing the value if 0144 * the update operation is costly. 0145 * A valueChanged signal will be emitted when the pointer is released from 0146 * the slider. 0147 * @param newBlockUpdateSignalOnDrag true if the spinbox should not emit 0148 * signals when dragging the slider. false otherwise 0149 */ 0150 void setBlockUpdateSignalOnDrag(bool newBlockUpdateSignalOnDrag); 0151 /** 0152 * @brief Set the value to which multiples the sinbox value snaps when 0153 * the control key is pressed 0154 * @param newFastSliderStep value to which multiples the spinbox value 0155 * snaps when the control key is pressed 0156 * @see fastSliderStep() const 0157 */ 0158 void setFastSliderStep(int newFastSliderStep); 0159 /** 0160 * @brief Does nothing currently 0161 */ 0162 void setPageStep(int newPageStep); 0163 /** 0164 * @brief Set the minimum and the maximum values of the soft range 0165 * @param newSoftMinimum the new minimum value 0166 * @param newSoftMaximum the new maximum value 0167 * @see setSoftMinimum(int) 0168 * @see setSoftMaximum(int) 0169 * @see softMinimum() const 0170 * @see softMaximum() const 0171 */ 0172 void setSoftRange(int newSoftMinimum, int newSoftMaximum); 0173 /** 0174 * @brief Set the minimum value of the soft range 0175 * @param newSoftMinimum the new minimum value 0176 * @see setSoftRange(int,int) 0177 * @see setSoftMaximum(int) 0178 * @see softMinimum() const 0179 * @see softMaximum() const 0180 */ 0181 void setSoftMinimum(int newSoftMinimum); 0182 /** 0183 * @brief Set the maximum value of the soft range 0184 * @param newSoftMaximum the new maximum value 0185 * @see setSoftRange(int,int) 0186 * @see setSoftMinimum(int) 0187 * @see softMinimum() const 0188 * @see softMaximum() const 0189 */ 0190 void setSoftMaximum(int newSoftMaximum); 0191 0192 Q_SIGNALS: 0193 void draggingFinished(); 0194 0195 protected: 0196 virtual void setInternalValue(int value, bool blockUpdateSignal); 0197 void setPrivateValue(int value); 0198 0199 private: 0200 template <typename SpinBoxTypeTP, typename BaseSpinBoxTypeTP> 0201 friend class KisSliderSpinBoxPrivate; 0202 QScopedPointer<KisSliderSpinBoxPrivate<KisSliderSpinBox, KisIntParseSpinBox>> d; 0203 }; 0204 0205 /** 0206 * @brief This class is a spinbox in which you can click and drag to set 0207 * the value. A slider like bar is displayed inside. 0208 * 0209 * @see KisSliderSpinBox 0210 */ 0211 class KRITAWIDGETUTILS_EXPORT KisDoubleSliderSpinBox : public KisDoubleParseSpinBox 0212 { 0213 Q_OBJECT 0214 public: 0215 KisDoubleSliderSpinBox(QWidget * parent = nullptr); 0216 ~KisDoubleSliderSpinBox() override; 0217 0218 qreal fastSliderStep() const; 0219 qreal softMinimum() const; 0220 qreal softMaximum() const; 0221 bool isDragging() const; 0222 QSize sizeHint() const override; 0223 QSize minimumSizeHint() const override; 0224 void setValue(qreal newValue); 0225 /** 0226 * @brief Set the minimum and the maximum values of the range 0227 * 0228 * The soft range will be adapted to fit inside the range 0229 * The number of decimals used can be changed with the newNumberOfDecimals 0230 * parameter 0231 * @param newMinimum the new minimum value 0232 * @param newMaximum the new maximum value 0233 * @param newNumberOfDecimals the new number of decimals 0234 * @param computeNewFastSliderStep true if a new "fast slider step" 0235 * must be computed based on the range 0236 * @see setMinimum(qreal) 0237 * @see setMaximum(qreal) 0238 */ 0239 void setRange(qreal newMinimum, qreal newMaximum, int newNumberOfDecimals = 0, bool computeNewFastSliderStep = true); 0240 void setMinimum(qreal newMinimum, bool computeNewFastSliderStep = true); 0241 void setMaximum(qreal newMaximum, bool computeNewFastSliderStep = true); 0242 void setExponentRatio(qreal newExponentRatio); 0243 void setBlockUpdateSignalOnDrag(bool newBlockUpdateSignalOnDrag); 0244 void setFastSliderStep(qreal newFastSliderStep); 0245 void setSoftRange(qreal newSoftMinimum, qreal newSoftMaximum); 0246 void setSoftMinimum(qreal newSoftMinimum); 0247 void setSoftMaximum(qreal newSoftMaximum); 0248 0249 protected: 0250 virtual void setInternalValue(qreal newValue, bool newBlockUpdateSignal); 0251 void setPrivateValue(qreal newValue); 0252 0253 Q_SIGNALS: 0254 void draggingFinished(); 0255 0256 private: 0257 template <typename SpinBoxTypeTP, typename BaseSpinBoxTypeTP> 0258 friend class KisSliderSpinBoxPrivate; 0259 QScopedPointer<KisSliderSpinBoxPrivate<KisDoubleSliderSpinBox, KisDoubleParseSpinBox>> d; 0260 }; 0261 0262 #endif //kISSLIDERSPINBOX_H