qtmaterialtoggle.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. #include "qtmaterialtoggle.h"
  2. #include "qtmaterialtoggle_p.h"
  3. #include <QtWidgets/QApplication>
  4. #include <QStateMachine>
  5. #include <QSignalTransition>
  6. #include <QPropertyAnimation>
  7. #include "qtmaterialtoggle_internal.h"
  8. #include "lib/qtmaterialstyle.h"
  9. /*!
  10. * \class QtMaterialTogglePrivate
  11. * \internal
  12. */
  13. QtMaterialTogglePrivate::QtMaterialTogglePrivate(QtMaterialToggle *q)
  14. : q_ptr(q)
  15. {
  16. }
  17. QtMaterialTogglePrivate::~QtMaterialTogglePrivate()
  18. {
  19. }
  20. void QtMaterialTogglePrivate::init()
  21. {
  22. Q_Q(QtMaterialToggle);
  23. track = new QtMaterialToggleTrack(q);
  24. thumb = new QtMaterialToggleThumb(q);
  25. rippleOverlay = new QtMaterialToggleRippleOverlay(thumb, track, q);
  26. stateMachine = new QStateMachine(q);
  27. offState = new QState;
  28. onState = new QState;
  29. orientation = Qt::Horizontal;
  30. useThemeColors = true;
  31. q->setCheckable(true);
  32. q->setChecked(false);
  33. q->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
  34. stateMachine->addState(offState);
  35. stateMachine->addState(onState);
  36. stateMachine->setInitialState(offState);
  37. offState->assignProperty(thumb, "shift", 0);
  38. onState->assignProperty(thumb, "shift", 1);
  39. QSignalTransition *transition;
  40. QPropertyAnimation *animation;
  41. //
  42. transition = new QSignalTransition(q, SIGNAL(toggled(bool)));
  43. transition->setTargetState(onState);
  44. offState->addTransition(transition);
  45. animation = new QPropertyAnimation(q);
  46. animation->setPropertyName("shift");
  47. animation->setTargetObject(thumb);
  48. animation->setDuration(200);
  49. animation->setEasingCurve(QEasingCurve::OutQuad);
  50. transition->addAnimation(animation);
  51. animation = new QPropertyAnimation(q);
  52. animation->setPropertyName("trackColor");
  53. animation->setTargetObject(track);
  54. animation->setDuration(150);
  55. transition->addAnimation(animation);
  56. animation = new QPropertyAnimation(q);
  57. animation->setPropertyName("thumbColor");
  58. animation->setTargetObject(thumb);
  59. animation->setDuration(150);
  60. transition->addAnimation(animation);
  61. //
  62. transition = new QSignalTransition(q, SIGNAL(toggled(bool)));
  63. transition->setTargetState(offState);
  64. onState->addTransition(transition);
  65. animation = new QPropertyAnimation(q);
  66. animation->setPropertyName("shift");
  67. animation->setTargetObject(thumb);
  68. animation->setDuration(200);
  69. animation->setEasingCurve(QEasingCurve::OutQuad);
  70. transition->addAnimation(animation);
  71. animation = new QPropertyAnimation(q);
  72. animation->setPropertyName("trackColor");
  73. animation->setTargetObject(track);
  74. animation->setDuration(150);
  75. transition->addAnimation(animation);
  76. animation = new QPropertyAnimation(q);
  77. animation->setPropertyName("thumbColor");
  78. animation->setTargetObject(thumb);
  79. animation->setDuration(150);
  80. transition->addAnimation(animation);
  81. //
  82. setupProperties();
  83. stateMachine->start();
  84. QCoreApplication::processEvents();
  85. }
  86. void QtMaterialTogglePrivate::setupProperties()
  87. {
  88. Q_Q(QtMaterialToggle);
  89. if (q->isEnabled()) {
  90. const qreal shift = thumb->shift();
  91. if (qFuzzyCompare(shift, 1)) {
  92. thumb->setThumbColor(q->activeColor());
  93. track->setTrackColor(q->activeColor().lighter(110));
  94. } else if (qFuzzyCompare(1+shift, 1)) {
  95. thumb->setThumbColor(q->inactiveColor());
  96. track->setTrackColor(q->trackColor());
  97. }
  98. }
  99. offState->assignProperty(track, "trackColor", q->trackColor().lighter(110));
  100. onState->assignProperty(track, "trackColor", q->activeColor().lighter(110));
  101. offState->assignProperty(thumb, "thumbColor", q->inactiveColor());
  102. onState->assignProperty(thumb, "thumbColor", q->activeColor());
  103. q->update();
  104. }
  105. /*!
  106. * \class QtMaterialToggle
  107. */
  108. QtMaterialToggle::QtMaterialToggle(QWidget *parent)
  109. : QAbstractButton(parent),
  110. d_ptr(new QtMaterialTogglePrivate(this))
  111. {
  112. d_func()->init();
  113. }
  114. QtMaterialToggle::~QtMaterialToggle()
  115. {
  116. }
  117. void QtMaterialToggle::setUseThemeColors(bool value)
  118. {
  119. Q_D(QtMaterialToggle);
  120. d->useThemeColors = value;
  121. d->setupProperties();
  122. }
  123. bool QtMaterialToggle::useThemeColors() const
  124. {
  125. Q_D(const QtMaterialToggle);
  126. return d->useThemeColors;
  127. }
  128. void QtMaterialToggle::setDisabledColor(const QColor &color)
  129. {
  130. Q_D(QtMaterialToggle);
  131. d->disabledColor = color;
  132. MATERIAL_DISABLE_THEME_COLORS
  133. d->setupProperties();
  134. }
  135. QColor QtMaterialToggle::disabledColor() const
  136. {
  137. Q_D(const QtMaterialToggle);
  138. if (d->useThemeColors || !d->disabledColor.isValid()) {
  139. return QtMaterialStyle::instance().themeColor("disabled");
  140. } else {
  141. return d->disabledColor;
  142. }
  143. }
  144. void QtMaterialToggle::setActiveColor(const QColor &color)
  145. {
  146. Q_D(QtMaterialToggle);
  147. d->activeColor = color;
  148. MATERIAL_DISABLE_THEME_COLORS
  149. d->setupProperties();
  150. }
  151. QColor QtMaterialToggle::activeColor() const
  152. {
  153. Q_D(const QtMaterialToggle);
  154. if (d->useThemeColors || !d->activeColor.isValid()) {
  155. return QtMaterialStyle::instance().themeColor("primary1");
  156. } else {
  157. return d->activeColor;
  158. }
  159. }
  160. void QtMaterialToggle::setInactiveColor(const QColor &color)
  161. {
  162. Q_D(QtMaterialToggle);
  163. d->inactiveColor = color;
  164. MATERIAL_DISABLE_THEME_COLORS
  165. d->setupProperties();
  166. }
  167. QColor QtMaterialToggle::inactiveColor() const
  168. {
  169. Q_D(const QtMaterialToggle);
  170. if (d->useThemeColors || !d->inactiveColor.isValid()) {
  171. return QtMaterialStyle::instance().themeColor("canvas");
  172. } else {
  173. return d->inactiveColor;
  174. }
  175. }
  176. void QtMaterialToggle::setTrackColor(const QColor &color)
  177. {
  178. Q_D(QtMaterialToggle);
  179. d->trackColor = color;
  180. MATERIAL_DISABLE_THEME_COLORS
  181. d->setupProperties();
  182. }
  183. QColor QtMaterialToggle::trackColor() const
  184. {
  185. Q_D(const QtMaterialToggle);
  186. if (d->useThemeColors || !d->trackColor.isValid()) {
  187. return QtMaterialStyle::instance().themeColor("accent3");
  188. } else {
  189. return d->trackColor;
  190. }
  191. }
  192. void QtMaterialToggle::setOrientation(Qt::Orientation orientation)
  193. {
  194. Q_D(QtMaterialToggle);
  195. if (d->orientation == orientation) {
  196. return;
  197. }
  198. d->orientation = orientation;
  199. updateGeometry();
  200. }
  201. Qt::Orientation QtMaterialToggle::orientation() const
  202. {
  203. Q_D(const QtMaterialToggle);
  204. return d->orientation;
  205. }
  206. QSize QtMaterialToggle::sizeHint() const
  207. {
  208. Q_D(const QtMaterialToggle);
  209. return Qt::Horizontal == d->orientation
  210. ? QSize(64, 48)
  211. : QSize(48, 64);
  212. }
  213. bool QtMaterialToggle::event(QEvent *event)
  214. {
  215. Q_D(QtMaterialToggle);
  216. switch (event->type())
  217. {
  218. case QEvent::ParentChange:
  219. {
  220. QWidget *widget;
  221. if ((widget = parentWidget())) {
  222. d->rippleOverlay->setParent(widget);
  223. }
  224. break;
  225. }
  226. default:
  227. break;
  228. }
  229. return QAbstractButton::event(event);
  230. }
  231. void QtMaterialToggle::paintEvent(QPaintEvent *event)
  232. {
  233. Q_UNUSED(event)
  234. }