SwitchButton.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "SwitchButton.h"
  2. #include "Common/StyleSheet.h"
  3. #include <QTimer>
  4. #include <QStyle>
  5. #include <QPainter>
  6. Indicator::Indicator(QWidget *parent)
  7. : QToolButton(parent),
  8. m_sliderOnColor(QColor(Qt::white)),
  9. m_sliderOffColor(QColor(Qt::black)),
  10. m_sliderDisabledColor(QColor(155, 154, 153)),
  11. m_timer(new QTimer(this))
  12. {
  13. setCheckable(true);
  14. QToolButton::setChecked(false);
  15. resize(37, 16);
  16. m_padding = height() / 4;
  17. m_sliderX = m_padding;
  18. m_sliderRadius = (height() - 2 * m_padding) / 2;
  19. m_sliderEndX = width() - 2 * m_sliderRadius;
  20. m_sliderStep = width() / 50.0;
  21. connect(m_timer, &QTimer::timeout, this, &Indicator::updateSliderPos);
  22. }
  23. void Indicator::setChecked(bool checked)
  24. {
  25. if (checked == this->isChecked()) {
  26. return;
  27. }
  28. QToolButton::setChecked(checked);
  29. m_sliderRadius = (this->height() - 2 * m_padding) / 2;
  30. m_sliderEndX = checked ? (this->width() - 2 * m_sliderRadius - m_padding) : m_padding;
  31. m_timer->start(5);
  32. }
  33. QColor Indicator::getSliderOnColor() const
  34. {
  35. return m_sliderOnColor;
  36. }
  37. void Indicator::setSliderOnColor(const QColor &sliderOnColor)
  38. {
  39. m_sliderOnColor = sliderOnColor;
  40. update();
  41. }
  42. QColor Indicator::getSliderOffColor() const
  43. {
  44. return m_sliderOffColor;
  45. }
  46. void Indicator::setSliderOffColor(const QColor &sliderOffColor)
  47. {
  48. m_sliderOffColor = sliderOffColor;
  49. update();
  50. }
  51. QColor Indicator::getSliderDisabledColor() const
  52. {
  53. return m_sliderDisabledColor;
  54. }
  55. void Indicator::setSliderDisabledColor(const QColor &sliderDisabledColor)
  56. {
  57. m_sliderDisabledColor = sliderDisabledColor;
  58. update();
  59. }
  60. /// update slider position
  61. void Indicator::updateSliderPos()
  62. {
  63. if (isChecked()) {
  64. if (m_sliderX + m_sliderStep < m_sliderEndX) {
  65. m_sliderX += m_sliderStep;
  66. } else {
  67. m_sliderX = m_sliderEndX;
  68. m_timer->stop();
  69. }
  70. } else {
  71. if (m_sliderX - m_sliderStep > m_sliderEndX) {
  72. m_sliderX -= m_sliderStep;
  73. } else {
  74. m_sliderX = m_padding;
  75. m_timer->stop();
  76. }
  77. }
  78. this->style()->polish(this);
  79. }
  80. /// toggle checked state when mouse release
  81. void Indicator::mouseReleaseEvent(QMouseEvent *event)
  82. {
  83. QToolButton::mouseReleaseEvent(event);
  84. m_sliderEndX = isChecked() ? (this->width() - 2 * m_sliderRadius - m_padding) : m_padding;
  85. m_timer->start(5);
  86. emit checkedChanged(isChecked());
  87. }
  88. /// paint indicator
  89. void Indicator::paintEvent(QPaintEvent *event)
  90. {
  91. // the background and border are specified by qss
  92. QToolButton::paintEvent(event);
  93. QPainter painter(this);
  94. painter.setRenderHints(QPainter::Antialiasing);
  95. painter.setPen(Qt::NoPen);
  96. QColor color;
  97. if (isEnabled()) {
  98. color = isChecked() ? m_sliderOnColor : m_sliderOffColor;
  99. } else {
  100. color = m_sliderDisabledColor;
  101. }
  102. painter.setBrush(color);
  103. painter.drawEllipse(int(m_sliderX), m_padding, m_sliderRadius * 2, m_sliderRadius * 2);
  104. }
  105. void Indicator::resizeEvent(QResizeEvent * /*event*/)
  106. {
  107. m_padding = this->height() / 4;
  108. m_sliderRadius = (height() - 2 * m_padding) / 2;
  109. m_sliderStep = width() / 50.0;
  110. m_sliderEndX = isChecked() ? (this->width() - 2 * m_sliderRadius - m_padding) : m_padding;
  111. update();
  112. }
  113. SwitchButton::SwitchButton(const QString &text, QWidget *parent, IndicatorPosition indicatorPos)
  114. : QWidget(parent),
  115. m_text(text),
  116. m_spacing(12),
  117. m_indicatorPos(indicatorPos),
  118. m_hBox(new QHBoxLayout(this)),
  119. m_indicator(new Indicator(this)),
  120. m_label(new QLabel(text, this))
  121. {
  122. initWidget();
  123. }
  124. bool SwitchButton::isChecked() const
  125. {
  126. return m_indicator->isChecked();
  127. }
  128. void SwitchButton::setChecked(bool checked)
  129. {
  130. this->adjustSize();
  131. m_indicator->setChecked(checked);
  132. }
  133. void SwitchButton::toggleChecked()
  134. {
  135. m_indicator->setChecked(!m_indicator->isChecked());
  136. }
  137. QString SwitchButton::text() const
  138. {
  139. return m_text;
  140. }
  141. void SwitchButton::setText(const QString &text)
  142. {
  143. m_text = text;
  144. m_label->setText(text);
  145. this->adjustSize();
  146. }
  147. int SwitchButton::getSpacing() const
  148. {
  149. return m_spacing;
  150. }
  151. void SwitchButton::setSpacing(int spacing)
  152. {
  153. m_spacing = spacing;
  154. m_hBox->setSpacing(spacing);
  155. update();
  156. }
  157. void SwitchButton::initWidget()
  158. {
  159. setAttribute(Qt::WA_StyledBackground);
  160. m_hBox->setSpacing(m_spacing);
  161. m_hBox->setContentsMargins(0, 0, 0, 0);
  162. if (m_indicatorPos == IndicatorPosition::LEFT) {
  163. m_hBox->addWidget(m_indicator);
  164. m_hBox->addWidget(m_label);
  165. m_hBox->setAlignment(Qt::AlignLeft);
  166. } else {
  167. m_hBox->addWidget(m_label, 0, Qt::AlignRight);
  168. m_hBox->addWidget(m_indicator, 0, Qt::AlignRight);
  169. m_hBox->setAlignment(Qt::AlignRight);
  170. }
  171. // set default style sheet
  172. FluentStyleSheet::apply("SWITCH_BUTTON", this);
  173. connect(m_indicator, &Indicator::checkedChanged, this, &SwitchButton::checkedChanged);
  174. }