ctkDoubleSpinBox.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) Kitware Inc.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0.txt
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. =========================================================================*/
  14. #ifndef __ctkDoubleSpinBox_h
  15. #define __ctkDoubleSpinBox_h
  16. // Qt includes
  17. #include <QMetaType>
  18. #include <QString>
  19. #include <QWidget>
  20. class QDoubleSpinBox;
  21. class QEvent;
  22. class QKeyEvent;
  23. class QLineEdit;
  24. class QObject;
  25. // CTK includes
  26. #include "ctkWidgetsExport.h"
  27. class ctkDoubleSpinBoxPrivate;
  28. class ctkValueProxy;
  29. /// \brief Custom SpinBox
  30. /// The ctkDoubleSpinBox internaly uses a QDoubleSpinBox while it retain controls
  31. /// over it.
  32. /// \sa ctkDoubleSlider, ctkSliderWidget, ctkRangeSlider
  33. class CTK_WIDGETS_EXPORT ctkDoubleSpinBox : public QWidget
  34. {
  35. Q_OBJECT
  36. Q_ENUMS(SetMode)
  37. Q_FLAGS(DecimalsOption DecimalsOptions)
  38. Q_ENUMS(SizeHintPolicy)
  39. Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
  40. Q_PROPERTY(bool frame READ hasFrame WRITE setFrame)
  41. Q_PROPERTY(QString prefix READ prefix WRITE setPrefix)
  42. Q_PROPERTY(QString suffix READ suffix WRITE setSuffix)
  43. Q_PROPERTY(QString cleanText READ cleanText)
  44. /// This property holds the precision of the spin box, in decimals.
  45. /// Sets how many decimals the spinbox will use for displaying and
  46. /// interpreting doubles.
  47. /// If the flag DecimalsByShortcuts is set, decimals can be increased/decreased by
  48. /// Ctrl+/Ctrl-, Ctrl0 restores the original decimals value.
  49. /// If the flag DecimalsAsMax and/or DecimalsAsMin are set, decimals behave also
  50. /// as the max and/or min number of decimals settable by DecimalsByShortcuts,
  51. /// DecimalsByKey and DecimalsByValue.
  52. /// 2 by default.
  53. /// \sa decimalsOption, decimals(), setDecimals(), decimalsChanged
  54. Q_PROPERTY(int decimals READ decimals WRITE setDecimals NOTIFY decimalsChanged)
  55. /// This property provides more controls over the decimals.
  56. /// The default (DecimalsByShortcuts|InsertDecimals) behaves as a QDoubleSpinbox
  57. /// with an explicit control of decimals via shortcuts.
  58. /// \sa DecimalsOptions, decimals
  59. Q_PROPERTY(DecimalsOptions decimalsOption READ decimalsOption WRITE setDecimalsOption)
  60. Q_PROPERTY(double minimum READ minimum WRITE setMinimum)
  61. Q_PROPERTY(double maximum READ maximum WRITE setMaximum)
  62. Q_PROPERTY(double singleStep READ singleStep WRITE setSingleStep)
  63. /// \sa setMode, decimals
  64. Q_PROPERTY(double value READ value WRITE setValue NOTIFY valueChanged USER true)
  65. /// This property controls how setValue behaves.
  66. /// \sa SetMode, setMode(), setSetMode(), value
  67. Q_PROPERTY(SetMode setMode READ setMode WRITE setSetMode)
  68. /// This property controls whether decreasing the value by the mouse
  69. /// button or mouse wheel increases the value of the widget, and inverts the
  70. /// control similarly in the other way round or not. The property is switched off by
  71. /// default.
  72. /// \sa invertedControls(), setInvertedControls()
  73. Q_PROPERTY(bool invertedControls READ invertedControls WRITE setInvertedControls)
  74. /// This property controls the size hint of the spinbox.
  75. /// SizeHintByMinMax by default
  76. /// SizeHintPolicy, sizeHintPolicy(), setSizeHintPolicy()
  77. Q_PROPERTY(SizeHintPolicy sizeHintPolicy READ sizeHintPolicy WRITE setSizeHintPolicy)
  78. public:
  79. /// SetMode enums for the spinbox behavior.
  80. /// SetAlways:
  81. /// No check is made and the given parameters is directly set
  82. /// on the internal QDoubleSpinBox.
  83. /// SetIfDifferent:
  84. /// Default mode, the given parameter is checked agains the
  85. /// current internal value and only set if they are different.
  86. /// For double, the comparison is based on the input parameters rounded
  87. /// with the current number of decimals (see round()).
  88. /// \sa setMode(), setSetMode(), round()
  89. enum SetMode
  90. {
  91. SetAlways,
  92. SetIfDifferent,
  93. };
  94. /// DecimalsOption enums the input style of the spinbox decimals.
  95. /// Default option is DecimalsByShortcuts.
  96. /// \sa decimals(), currentDecimals()
  97. enum DecimalsOption
  98. {
  99. /// Behaves just like a QDoubleSpinBox. The maximum number of decimals
  100. /// allowed is given by decimals().
  101. FixedDecimals = 0x000,
  102. /// When the spinbox has focus, entering the shortcut "CTRL +"
  103. /// adds decimals to the current number of decimals. "CTRL -" decreases the
  104. /// number of decimals and "CTRL 0" returns it to its original decimals()
  105. /// value.
  106. DecimalsByShortcuts = 0x001,
  107. /// Allow the number of decimals to be controlled by adding/removing digits
  108. /// with key strokes.
  109. /// \sa InsertDecimals, ReplaceDecimals
  110. DecimalsByKey = 0x002,
  111. /// Allow the number of decimals to be controlled by the value set by
  112. /// setValue().
  113. DecimalsByValue = 0x004,
  114. /// This flag controls whether inserted intermediate decimals increase the
  115. /// number of decimals (on) or not (off).
  116. /// It is incompatible with the ReplaceDecimals flag.
  117. /// \sa DecimalsByKey.
  118. InsertDecimals = 0x008,
  119. /// This flag controls whether inserted intermediate decimals replace the
  120. /// existing decimals (on) or not (off). This is similar to Insert but just
  121. /// for decimal digits.
  122. /// It is incompatible with the InsertDecimals flag.
  123. /// \sa DecimalsByKey, InsertDecimals
  124. ReplaceDecimals = 0x010,
  125. /// Use the "decimals" property as a maximum limit for the number of
  126. /// decimals.
  127. DecimalsAsMax = 0x020,
  128. /// Use the "decimals" property as a minimum limit for the number of
  129. /// decimals.
  130. DecimalsAsMin = 0x040,
  131. /// Even if the number of decimals is 0, it enforces the decimal to be visible
  132. /// (e.g. "0." )
  133. /// \sa decimals
  134. DecimalPointAlwaysVisible = 0x080
  135. };
  136. Q_DECLARE_FLAGS(DecimalsOptions, DecimalsOption)
  137. enum SizeHintPolicy
  138. {
  139. SizeHintByMinMax,
  140. SizeHintByValue
  141. };
  142. typedef QWidget Superclass;
  143. /// Constructor, creates a ctkDoubleSpinBox. The look and feel
  144. /// are the same as of a QDoubleSpinBox
  145. explicit ctkDoubleSpinBox(QWidget* parent = 0);
  146. explicit ctkDoubleSpinBox(ctkDoubleSpinBox::SetMode mode, QWidget* parent = 0);
  147. virtual ~ctkDoubleSpinBox();
  148. /// Get the spinbox current value
  149. /// \sa setValue(), cleanText()
  150. double value() const;
  151. /// Get the spinbox current displayed value
  152. /// \sa value(), cleanText(), setValue(), displayedValue()
  153. double displayedValue() const;
  154. /// Set the displayed value if there is no proxy installed.
  155. /// If there is a proxy installed, then it allows to modify the proxy value.
  156. /// If there is no value proxy installed, then it's just a setter to the
  157. /// value property.
  158. /// \sa displayedValue(), setValue(), value(), setValueProxy()
  159. void setDisplayedValue(double displayValue);
  160. /// Get the spinbox current text. This includes any prefix or suffix.
  161. /// \sa prefix(), suffix()
  162. QString text() const;
  163. /// Get the spinbox current text. This excludes any prefix or suffix.
  164. /// \sa value()
  165. QString cleanText() const;
  166. /// Set/Get the spinbox alignement
  167. Qt::Alignment alignment () const;
  168. void setAlignment (Qt::Alignment flag);
  169. /// Set/Get the frame
  170. void setFrame(bool frame);
  171. bool hasFrame() const;
  172. /// Add/Get a prefix to the displayed value. For example, one might want to
  173. /// add the $ sign.
  174. /// \sa suffix(), text()
  175. QString prefix() const;
  176. void setPrefix(const QString &prefix);
  177. /// Add/Get a suffix to the displayed value. For example, one might want to
  178. /// add the F (fahrenheit) sign.
  179. /// \sa prefix(), text()
  180. QString suffix() const;
  181. void setSuffix(const QString &suffix);
  182. /// Set/Get the single step. This represents by how much the value will
  183. /// decrease or increase when clicking the spinbox arrow or using stepUp or
  184. /// stepDown(). Default is 1.0.
  185. /// \sa setUp(), stepDown(), setDecimals().
  186. double singleStep() const;
  187. void setSingleStep(double value);
  188. /// Set/Get the range of the spinbox. Default range is [0.0, 9.9].
  189. double minimum() const;
  190. void setMinimum(double min);
  191. double maximum() const;
  192. void setMaximum(double max);
  193. void setRange(double min, double max);
  194. /// Set/Get number of displayed decimals.
  195. /// For a spinbox dealing only with integers, set this to 0.
  196. /// \sa ctkDoubleSpinBox::DecimalsOption
  197. int decimals() const;
  198. /// Returns the rounded value according to the number of decimals of
  199. /// the spinbox.
  200. /// \sa decimals()
  201. double round(double value) const;
  202. /// Get a pointer on the spinbox used internally. It can be useful to
  203. /// change display properties for example. To use with caution.
  204. /// \sa QDoubleSpinBox, lineEdit()
  205. QDoubleSpinBox* spinBox() const;
  206. /// Get a pointer on the line edit of the spinbox.
  207. /// \sa QLineEdit, spinBox()
  208. QLineEdit* lineEdit()const;
  209. /// Set the spinbox mode when using a set*() method.
  210. //// \sa round(), setValue(), setValueIfDifferent(), setValueAlways()
  211. ctkDoubleSpinBox::SetMode setMode() const;
  212. void setSetMode(SetMode mode);
  213. /// Set/Get the option used to input the decimals.
  214. /// \sa ctkDoubleSpinBox::DecimalsOption
  215. ctkDoubleSpinBox::DecimalsOptions decimalsOption();
  216. void setDecimalsOption(ctkDoubleSpinBox::DecimalsOptions option);
  217. /// This property holds whether or not the spin box inverts its wheel and key
  218. /// events.
  219. /// If this property is false, scrolling the mouse wheel "up" and using keys
  220. /// like page up will increase the spinbox's value towards its maximum.
  221. /// Otherwise pressing page up will move value towards the slider's minimum.
  222. void setInvertedControls(bool invertedControls);
  223. bool invertedControls() const;
  224. /// Set the sizeHintPolicy property value.
  225. /// \sa sizeHintPolicy
  226. void setSizeHintPolicy(SizeHintPolicy newSizeHintPolicy);
  227. /// Return the sizeHintPolicy property value.
  228. /// \sa sizeHintPolicy
  229. SizeHintPolicy sizeHintPolicy()const;
  230. /// Install or remove a value proxy filter. The value proxy decouples the
  231. /// displayed value from the value retrieved by the value property.
  232. /// For example, the value proxy can allow one to display celsius in the
  233. /// spinbox while the value retrieved from the value property and signals
  234. /// are in farenheit.
  235. /// To remove the proxy, simply install a new empty proxy. The proxy
  236. /// installation/removal is silent.
  237. /// \sa installValueProxy(), valueProxy()
  238. void setValueProxy(ctkValueProxy* proxy);
  239. ctkValueProxy* valueProxy() const;
  240. /// Reimplemented to respect the sizeHintPolicy property value.
  241. /// \sa sizeHintPolicy
  242. virtual QSize sizeHint()const;
  243. /// Reimplemented to respect the sizeHintPolicy property value.
  244. /// \sa sizeHintPolicy
  245. virtual QSize minimumSizeHint()const;
  246. public Q_SLOTS:
  247. /// Set the value of the spinbox following the current mode.
  248. /// \sa setMode(), value(), setValueIfDifferent(), setValueAlways()
  249. void setValue(double value);
  250. /// Set the value of the spinbox followin the SetIfDifferent mode.
  251. /// \sa value(), setValue(), setMode(), setValueAlways()
  252. void setValueIfDifferent(double value);
  253. /// Set the value of the spinbox following the SetAlways mode.
  254. /// \sa value(), setValue(), setMode(), setValueIfDifferent()
  255. void setValueAlways(double value);
  256. /// Increase/Decrease the current value by a single step.
  257. /// \sa value(), singleStep()
  258. void stepUp();
  259. void stepDown();
  260. /// Set the decimals property value.
  261. /// \sa decimals
  262. void setDecimals(int decimal);
  263. Q_SIGNALS:
  264. /// Emitted everytime the spinbox value is modified
  265. /// \sa QDoubleSpinBox::valueChanged()
  266. void valueChanged(double);
  267. void valueChanged(const QString &);
  268. /// Simple broadcast of the QAbstractSpinbox::editingFinished
  269. /// \sa QAbstractSpinbox::editingFinished
  270. void editingFinished();
  271. /// Signal emitted when the decimals of the displayed are changed.
  272. void decimalsChanged(int);
  273. protected:
  274. QScopedPointer<ctkDoubleSpinBoxPrivate> d_ptr;
  275. /// Reimplemented to support shortcuts.
  276. virtual void keyPressEvent(QKeyEvent* event);
  277. /// Reimplemented to support shortcuts on the double spinbox.
  278. virtual bool eventFilter(QObject *obj, QEvent *event);
  279. friend class ctkCoordinatesWidgetPrivate;
  280. private:
  281. Q_DECLARE_PRIVATE(ctkDoubleSpinBox);
  282. Q_DISABLE_COPY(ctkDoubleSpinBox);
  283. };
  284. Q_DECLARE_METATYPE(ctkDoubleSpinBox::SetMode)
  285. Q_DECLARE_OPERATORS_FOR_FLAGS(ctkDoubleSpinBox::DecimalsOptions)
  286. #endif //__ctkDoubleSpinBox_h