Dial.qml 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2016 The Qt Company Ltd.
  4. ** Contact: https://www.qt.io/licensing/
  5. **
  6. ** This file is part of the Qt Quick Extras module of the Qt Toolkit.
  7. **
  8. ** $QT_BEGIN_LICENSE:LGPL$
  9. ** Commercial License Usage
  10. ** Licensees holding valid commercial Qt licenses may use this file in
  11. ** accordance with the commercial license agreement provided with the
  12. ** Software or, alternatively, in accordance with the terms contained in
  13. ** a written agreement between you and The Qt Company. For licensing terms
  14. ** and conditions see https://www.qt.io/terms-conditions. For further
  15. ** information use the contact form at https://www.qt.io/contact-us.
  16. **
  17. ** GNU Lesser General Public License Usage
  18. ** Alternatively, this file may be used under the terms of the GNU Lesser
  19. ** General Public License version 3 as published by the Free Software
  20. ** Foundation and appearing in the file LICENSE.LGPL3 included in the
  21. ** packaging of this file. Please review the following information to
  22. ** ensure the GNU Lesser General Public License version 3 requirements
  23. ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
  24. **
  25. ** GNU General Public License Usage
  26. ** Alternatively, this file may be used under the terms of the GNU
  27. ** General Public License version 2.0 or (at your option) the GNU General
  28. ** Public license version 3 or any later version approved by the KDE Free
  29. ** Qt Foundation. The licenses are as published by the Free Software
  30. ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
  31. ** included in the packaging of this file. Please review the following
  32. ** information to ensure the GNU General Public License requirements will
  33. ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
  34. ** https://www.gnu.org/licenses/gpl-3.0.html.
  35. **
  36. ** $QT_END_LICENSE$
  37. **
  38. ****************************************************************************/
  39. import QtQuick 2.2
  40. import QtQuick.Controls 1.4
  41. import QtQuick.Controls.Styles 1.4
  42. import QtQuick.Controls.Private 1.0
  43. import QtQuick.Extras 1.4
  44. import QtQuick.Extras.Private 1.0
  45. /*!
  46. \qmltype Dial
  47. \inqmlmodule QtQuick.Extras
  48. \since 5.5
  49. \ingroup extras
  50. \ingroup extras-interactive
  51. \brief A circular dial that is rotated to set a value.
  52. \image dial.png A Dial
  53. The Dial is similar to a traditional dial knob that is found on devices
  54. such as stereos or industrial equipment. It allows the user to specify a
  55. value within a range.
  56. Like CircularGauge, Dial can display tickmarks to give an indication of
  57. the current value. When a suitable stepSize is combined with
  58. \l {DialStyle::}{tickmarkStepSize},
  59. the dial "snaps" to each tickmark.
  60. You can create a custom appearance for a Dial by assigning a
  61. \l {DialStyle}.
  62. */
  63. Control {
  64. id: dial
  65. activeFocusOnTab: true
  66. style: Settings.styleComponent(Settings.style, "DialStyle.qml", dial)
  67. /*!
  68. \qmlproperty real Dial::value
  69. The angle of the handle along the dial, in the range of
  70. \c 0.0 to \c 1.0.
  71. The default value is \c{0.0}.
  72. */
  73. property alias value: range.value
  74. /*!
  75. \qmlproperty real Dial::minimumValue
  76. The smallest value allowed by the dial.
  77. The default value is \c{0.0}.
  78. \sa value, maximumValue
  79. */
  80. property alias minimumValue: range.minimumValue
  81. /*!
  82. \qmlproperty real Dial::maximumValue
  83. The largest value allowed by the dial.
  84. The default value is \c{1.0}.
  85. \sa value, minimumValue
  86. */
  87. property alias maximumValue: range.maximumValue
  88. /*!
  89. \qmlproperty real Dial::hovered
  90. This property holds whether the button is being hovered.
  91. */
  92. readonly property alias hovered: mouseArea.containsMouse
  93. /*!
  94. \qmlproperty real Dial::stepSize
  95. The default value is \c{0.0}.
  96. */
  97. property alias stepSize: range.stepSize
  98. /*!
  99. \internal
  100. Determines whether the dial can be freely rotated past the zero marker.
  101. The default value is \c false.
  102. */
  103. property bool __wrap: false
  104. /*!
  105. This property specifies whether the dial should gain active focus when
  106. pressed.
  107. The default value is \c false.
  108. \sa pressed
  109. */
  110. property bool activeFocusOnPress: false
  111. /*!
  112. \qmlproperty bool Dial::pressed
  113. Returns \c true if the dial is pressed.
  114. \sa activeFocusOnPress
  115. */
  116. readonly property alias pressed: mouseArea.pressed
  117. /*!
  118. This property determines whether or not the dial displays tickmarks,
  119. minor tickmarks, and labels.
  120. For more fine-grained control over what is displayed, the following
  121. style components of
  122. \l {DialStyle} can be used:
  123. \list
  124. \li \l {DialStyle::}{tickmark}
  125. \li \l {DialStyle::}{minorTickmark}
  126. \li \l {DialStyle::}{tickmarkLabel}
  127. \endlist
  128. The default value is \c true.
  129. */
  130. property bool tickmarksVisible: true
  131. Keys.onLeftPressed: value -= stepSize
  132. Keys.onDownPressed: value -= stepSize
  133. Keys.onRightPressed: value += stepSize
  134. Keys.onUpPressed: value += stepSize
  135. Keys.onPressed: {
  136. if (event.key === Qt.Key_Home) {
  137. value = minimumValue;
  138. event.accepted = true;
  139. } else if (event.key === Qt.Key_End) {
  140. value = maximumValue;
  141. event.accepted = true;
  142. }
  143. }
  144. RangeModel {
  145. id: range
  146. minimumValue: 0.0
  147. maximumValue: 1.0
  148. stepSize: 0
  149. value: 0
  150. }
  151. MouseArea {
  152. id: mouseArea
  153. hoverEnabled: true
  154. parent: __panel.background.parent
  155. anchors.fill: parent
  156. onPositionChanged: {
  157. if (pressed) {
  158. value = valueFromPoint(mouseX, mouseY);
  159. }
  160. }
  161. onPressed: {
  162. if (!__style.__dragToSet)
  163. value = valueFromPoint(mouseX, mouseY);
  164. if (activeFocusOnPress)
  165. dial.forceActiveFocus();
  166. }
  167. function bound(val) { return Math.max(minimumValue, Math.min(maximumValue, val)); }
  168. function valueFromPoint(x, y)
  169. {
  170. var yy = height / 2.0 - y;
  171. var xx = x - width / 2.0;
  172. var angle = (xx || yy) ? Math.atan2(yy, xx) : 0;
  173. if (angle < Math.PI/ -2)
  174. angle = angle + Math.PI * 2;
  175. var range = maximumValue - minimumValue;
  176. var value;
  177. if (__wrap)
  178. value = (minimumValue + range * (Math.PI * 3 / 2 - angle) / (2 * Math.PI));
  179. else
  180. value = (minimumValue + range * (Math.PI * 4 / 3 - angle) / (Math.PI * 10 / 6));
  181. return bound(value)
  182. }
  183. }
  184. }