ToggleButtonStyle.qml 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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 QtGraphicalEffects 1.0
  41. import QtQuick.Controls.Styles 1.4
  42. import QtQuick.Extras 1.4
  43. import QtQuick.Extras.Private 1.0
  44. import QtQuick.Extras.Private.CppUtils 1.0
  45. /*!
  46. \qmltype ToggleButtonStyle
  47. \inqmlmodule QtQuick.Controls.Styles
  48. \since 5.5
  49. \ingroup controlsstyling
  50. \brief Provides custom styling for ToggleButton.
  51. You can create a custom toggle button by replacing the same delegates that
  52. \l {ButtonStyle} provides.
  53. */
  54. CircularButtonStyle {
  55. id: circularButtonStyle
  56. /*!
  57. The \l ToggleButton that this style is attached to.
  58. */
  59. readonly property ToggleButton control: __control
  60. /*!
  61. The gradient that is displayed on the inactive state indicator. The
  62. inactive state indicator will be the checked gradient when the button
  63. is unchecked, and the unchecked gradient when the button is checked.
  64. \sa checkedGradient, uncheckedGradient
  65. */
  66. property Gradient inactiveGradient: Gradient {
  67. GradientStop {
  68. position: 0
  69. color: commonStyleHelper.inactiveColor
  70. }
  71. GradientStop {
  72. position: 1
  73. color: commonStyleHelper.inactiveColorShine
  74. }
  75. }
  76. /*!
  77. The gradient that is displayed on the checked state indicator.
  78. \sa uncheckedGradient, inactiveGradient
  79. */
  80. property Gradient checkedGradient: Gradient {
  81. GradientStop {
  82. position: 0
  83. color: commonStyleHelper.onColor
  84. }
  85. GradientStop {
  86. position: 1
  87. color: commonStyleHelper.onColorShine
  88. }
  89. }
  90. /*!
  91. The gradient that is displayed on the unchecked state indicator.
  92. \sa checkedGradient, inactiveGradient
  93. */
  94. property Gradient uncheckedGradient: Gradient {
  95. GradientStop {
  96. position: 0
  97. color: commonStyleHelper.offColor
  98. }
  99. GradientStop {
  100. position: 1
  101. color: commonStyleHelper.offColorShine
  102. }
  103. }
  104. /*!
  105. The color that is used for the drop shadow below the checked state
  106. indicator.
  107. \sa uncheckedDropShadowColor
  108. */
  109. property color checkedDropShadowColor: commonStyleHelper.onColor
  110. /*!
  111. The color that is used for the drop shadow below the checked state
  112. indicator.
  113. \sa checkedDropShadowColor
  114. */
  115. property color uncheckedDropShadowColor: commonStyleHelper.offColor
  116. CommonStyleHelper {
  117. id: commonStyleHelper
  118. }
  119. background: Item {
  120. implicitWidth: __buttonHelper.implicitWidth
  121. implicitHeight: __buttonHelper.implicitHeight
  122. Connections {
  123. target: control
  124. function onPressedChanged() {
  125. backgroundCanvas.requestPaint();
  126. }
  127. function onCheckedChanged() {
  128. uncheckedCanvas.requestPaint();
  129. checkedCanvas.requestPaint();
  130. }
  131. }
  132. Connections {
  133. target: circularButtonStyle
  134. function onCheckedGradientChanged() { checkedCanvas.requestPaint() }
  135. function onCheckedDropShadowColorChanged() { checkedCanvas.requestPaint() }
  136. function onUncheckedGradientChanged() { uncheckedCanvas.requestPaint() }
  137. function onUncheckedDropShadowColorChanged() { uncheckedCanvas.requestPaint() }
  138. function onInactiveGradientChanged() {
  139. checkedCanvas.requestPaint();
  140. uncheckedCanvas.requestPaint();
  141. }
  142. }
  143. Connections {
  144. target: circularButtonStyle.checkedGradient
  145. function onUpdated() { checkedCanvas.requestPaint() }
  146. }
  147. Connections {
  148. target: circularButtonStyle.uncheckedGradient
  149. function onUpdated() { uncheckedCanvas.requestPaint() }
  150. }
  151. Connections {
  152. target: circularButtonStyle.inactiveGradient
  153. function onUpdated() {
  154. uncheckedCanvas.requestPaint();
  155. checkedCanvas.requestPaint();
  156. }
  157. }
  158. Canvas {
  159. id: backgroundCanvas
  160. anchors.fill: parent
  161. onPaint: {
  162. var ctx = getContext("2d");
  163. __buttonHelper.paintBackground(ctx);
  164. }
  165. }
  166. Canvas {
  167. id: uncheckedCanvas
  168. anchors.fill: parent
  169. anchors.margins: -(__buttonHelper.radius * 3)
  170. visible: control.checked
  171. readonly property real xCenter: width / 2
  172. readonly property real yCenter: height / 2
  173. onPaint: {
  174. var ctx = getContext("2d");
  175. ctx.reset();
  176. /* Draw unchecked indicator */
  177. ctx.beginPath();
  178. ctx.lineWidth = __buttonHelper.outerArcLineWidth - __buttonHelper.innerArcLineWidth;
  179. ctx.arc(xCenter, yCenter, __buttonHelper.outerArcRadius + __buttonHelper.innerArcLineWidth / 2,
  180. MathUtils.degToRad(180), MathUtils.degToRad(270), false);
  181. var gradient = ctx.createLinearGradient(xCenter, yCenter + __buttonHelper.radius,
  182. xCenter, yCenter - __buttonHelper.radius);
  183. var relevantGradient = control.checked ? inactiveGradient : uncheckedGradient;
  184. for (var i = 0; i < relevantGradient.stops.length; ++i) {
  185. gradient.addColorStop(relevantGradient.stops[i].position, relevantGradient.stops[i].color);
  186. }
  187. ctx.strokeStyle = gradient;
  188. ctx.stroke();
  189. }
  190. }
  191. Canvas {
  192. id: checkedCanvas
  193. anchors.fill: parent
  194. anchors.margins: -(__buttonHelper.radius * 3)
  195. visible: !control.checked
  196. readonly property real xCenter: width / 2
  197. readonly property real yCenter: height / 2
  198. onPaint: {
  199. var ctx = getContext("2d");
  200. ctx.reset();
  201. /* Draw checked indicator */
  202. ctx.beginPath();
  203. ctx.lineWidth = __buttonHelper.outerArcLineWidth - __buttonHelper.innerArcLineWidth;
  204. ctx.arc(xCenter, yCenter, __buttonHelper.outerArcRadius + __buttonHelper.innerArcLineWidth / 2,
  205. MathUtils.degToRad(270), MathUtils.degToRad(0), false);
  206. var gradient = ctx.createLinearGradient(xCenter, yCenter + __buttonHelper.radius,
  207. xCenter, yCenter - __buttonHelper.radius);
  208. var relevantGradient = control.checked ? checkedGradient : inactiveGradient;
  209. for (var i = 0; i < relevantGradient.stops.length; ++i) {
  210. gradient.addColorStop(relevantGradient.stops[i].position, relevantGradient.stops[i].color);
  211. }
  212. ctx.strokeStyle = gradient;
  213. ctx.stroke();
  214. }
  215. }
  216. DropShadow {
  217. id: uncheckedDropShadow
  218. anchors.fill: uncheckedCanvas
  219. cached: true
  220. color: uncheckedDropShadowColor
  221. source: uncheckedCanvas
  222. visible: !control.checked
  223. }
  224. DropShadow {
  225. id: checkedDropShadow
  226. anchors.fill: checkedCanvas
  227. cached: true
  228. color: checkedDropShadowColor
  229. source: checkedCanvas
  230. visible: control.checked
  231. }
  232. }
  233. panel: Item {
  234. implicitWidth: backgroundLoader.implicitWidth
  235. implicitHeight: backgroundLoader.implicitHeight
  236. Loader {
  237. id: backgroundLoader
  238. anchors.fill: parent
  239. sourceComponent: background
  240. }
  241. Loader {
  242. id: labelLoader
  243. sourceComponent: label
  244. anchors.fill: parent
  245. anchors.leftMargin: padding.left
  246. anchors.topMargin: padding.top
  247. anchors.rightMargin: padding.right
  248. anchors.bottomMargin: padding.bottom
  249. }
  250. }
  251. }