qtmaterialtoggle_internal.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. #include "qtmaterialtoggle_internal.h"
  2. #include <QPainter>
  3. #include <QEvent>
  4. #include <QtWidgets/QGraphicsDropShadowEffect>
  5. #include "qtmaterialtoggle.h"
  6. #include "lib/qtmaterialripple.h"
  7. /*!
  8. * \class QtMaterialToggleRippleOverlay
  9. * \internal
  10. */
  11. QtMaterialToggleRippleOverlay::QtMaterialToggleRippleOverlay(
  12. QtMaterialToggleThumb *thumb,
  13. QtMaterialToggleTrack *track,
  14. QtMaterialToggle *parent)
  15. : QtMaterialRippleOverlay(parent->parentWidget()),
  16. m_toggle(parent),
  17. m_thumb(thumb),
  18. m_track(track)
  19. {
  20. connect(parent, SIGNAL(toggled(bool)), this, SLOT(addToggleRipple()));
  21. thumb->installEventFilter(this);
  22. }
  23. QtMaterialToggleRippleOverlay::~QtMaterialToggleRippleOverlay()
  24. {
  25. }
  26. void QtMaterialToggleRippleOverlay::addToggleRipple()
  27. {
  28. if (!m_toggle->isEnabled()) {
  29. return;
  30. }
  31. int t, w;
  32. if (Qt::Horizontal == m_toggle->orientation()) {
  33. t = m_toggle->height()/2;
  34. w = m_thumb->height()/2+10;
  35. } else {
  36. t = m_toggle->width()/2;
  37. w = m_thumb->width()/2+10;
  38. }
  39. QtMaterialRipple *ripple = new QtMaterialRipple(QPoint(10+t, 20+t));
  40. ripple->setColor(m_track->trackColor());
  41. ripple->setRadiusEndValue(w);
  42. ripple->setOpacityStartValue(0.8);
  43. addRipple(ripple);
  44. }
  45. bool QtMaterialToggleRippleOverlay::eventFilter(QObject *obj, QEvent *event)
  46. {
  47. if (QEvent::Paint == event->type()) {
  48. setGeometry(overlayGeometry());
  49. QList<QtMaterialRipple *>::const_iterator i;
  50. QList<QtMaterialRipple *> items = ripples();
  51. QColor color = m_track->trackColor();
  52. for (i = items.begin(); i != items.end(); ++i) {
  53. (*i)->setColor(color);
  54. }
  55. }
  56. return QtMaterialRippleOverlay::eventFilter(obj, event);
  57. }
  58. QRect QtMaterialToggleRippleOverlay::overlayGeometry() const
  59. {
  60. const qreal offset = m_thumb->offset();
  61. if (Qt::Horizontal == m_toggle->orientation()) {
  62. return m_toggle->geometry().adjusted(-10+offset, -20, 10+offset, 20);
  63. } else {
  64. return m_toggle->geometry().adjusted(-10, -20+offset, 10, 20+offset);
  65. }
  66. }
  67. /*!
  68. * \class QtMaterialToggleThumb
  69. * \internal
  70. */
  71. QtMaterialToggleThumb::QtMaterialToggleThumb(QtMaterialToggle *parent)
  72. : QWidget(parent),
  73. m_toggle(parent),
  74. m_shift(0),
  75. m_offset(0)
  76. {
  77. Q_ASSERT(parent);
  78. QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect;
  79. effect->setBlurRadius(6);
  80. effect->setColor(QColor(0, 0, 0, 80));
  81. effect->setOffset(QPointF(0, 1));
  82. setGraphicsEffect(effect);
  83. parent->installEventFilter(this);
  84. }
  85. QtMaterialToggleThumb::~QtMaterialToggleThumb()
  86. {
  87. }
  88. void QtMaterialToggleThumb::setShift(qreal shift)
  89. {
  90. if (m_shift == shift) {
  91. return;
  92. }
  93. m_shift = shift;
  94. updateOffset();
  95. }
  96. bool QtMaterialToggleThumb::eventFilter(QObject *obj, QEvent *event)
  97. {
  98. const QEvent::Type type = event->type();
  99. if (QEvent::Resize == type || QEvent::Move == type)
  100. {
  101. setGeometry(m_toggle->rect().adjusted(8, 8, -8, -8));
  102. updateOffset();
  103. }
  104. return QWidget::eventFilter(obj, event);
  105. }
  106. void QtMaterialToggleThumb::paintEvent(QPaintEvent *event)
  107. {
  108. Q_UNUSED(event)
  109. QPainter painter(this);
  110. painter.setRenderHint(QPainter::Antialiasing);
  111. QBrush brush;
  112. brush.setStyle(Qt::SolidPattern);
  113. brush.setColor(m_toggle->isEnabled() ? m_thumbColor : Qt::white);
  114. painter.setBrush(brush);
  115. painter.setPen(Qt::NoPen);
  116. int s;
  117. QRectF r;
  118. if (Qt::Horizontal == m_toggle->orientation()) {
  119. s = height()-10;
  120. r = QRectF(5+m_offset, 5, s, s);
  121. } else {
  122. s = width()-10;
  123. r = QRectF(5, 5+m_offset, s, s);
  124. }
  125. painter.drawEllipse(r);
  126. if (!m_toggle->isEnabled()) {
  127. brush.setColor(m_toggle->disabledColor());
  128. painter.setBrush(brush);
  129. painter.drawEllipse(r);
  130. }
  131. }
  132. void QtMaterialToggleThumb::updateOffset()
  133. {
  134. const QSize s(Qt::Horizontal == m_toggle->orientation()
  135. ? size() : size().transposed());
  136. m_offset = m_shift*static_cast<qreal>(s.width()-s.height());
  137. update();
  138. }
  139. /*!
  140. * \class QtMaterialToggleTrack
  141. * \internal
  142. */
  143. QtMaterialToggleTrack::QtMaterialToggleTrack(QtMaterialToggle *parent)
  144. : QWidget(parent),
  145. m_toggle(parent)
  146. {
  147. Q_ASSERT(parent);
  148. parent->installEventFilter(this);
  149. }
  150. QtMaterialToggleTrack::~QtMaterialToggleTrack()
  151. {
  152. }
  153. void QtMaterialToggleTrack::setTrackColor(const QColor &color)
  154. {
  155. m_trackColor = color;
  156. update();
  157. }
  158. bool QtMaterialToggleTrack::eventFilter(QObject *obj, QEvent *event)
  159. {
  160. const QEvent::Type type = event->type();
  161. if (QEvent::Resize == type || QEvent::Move == type) {
  162. setGeometry(m_toggle->rect());
  163. }
  164. return QWidget::eventFilter(obj, event);
  165. }
  166. void QtMaterialToggleTrack::paintEvent(QPaintEvent *event)
  167. {
  168. Q_UNUSED(event)
  169. QPainter painter(this);
  170. painter.setRenderHint(QPainter::Antialiasing);
  171. QBrush brush;
  172. if (m_toggle->isEnabled()) {
  173. brush.setColor(m_trackColor);
  174. painter.setOpacity(0.8);
  175. } else {
  176. brush.setColor(m_toggle->disabledColor());
  177. painter.setOpacity(0.6);
  178. }
  179. brush.setStyle(Qt::SolidPattern);
  180. painter.setBrush(brush);
  181. painter.setPen(Qt::NoPen);
  182. if (Qt::Horizontal == m_toggle->orientation()) {
  183. const int h = height()/2;
  184. const QRect r(0, h/2, width(), h);
  185. painter.drawRoundedRect(r.adjusted(14, 4, -14, -4), h/2-4, h/2-4);
  186. } else {
  187. const int w = width()/2;
  188. const QRect r(w/2, 0, w, height());
  189. painter.drawRoundedRect(r.adjusted(4, 14, -4, -14), w/2-4, w/2-4);
  190. }
  191. }