Slider.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #include "Slider.h"
  2. #include "Common/StyleSheet.h"
  3. #include <QMouseEvent>
  4. #include <QPainter>
  5. #include <QStyleOptionComplex>
  6. Slider::Slider(Qt::Orientation orientation, QWidget *parent) : QSlider(orientation, parent)
  7. {
  8. FluentStyleSheet::apply("SLIDER", this);
  9. }
  10. void Slider::mousePressEvent(QMouseEvent *event)
  11. {
  12. QSlider::mousePressEvent(event);
  13. int value = 0;
  14. if (orientation() == Qt::Horizontal) {
  15. value = event->pos().x() * maximum() / width();
  16. } else {
  17. value = (height() - event->pos().y()) * maximum() / height();
  18. }
  19. setValue(value);
  20. emit clicked(value);
  21. }
  22. HollowHandleStyle::HollowHandleStyle(const QMap<QString, QVariant> &cfg)
  23. {
  24. config.insert("groove.height", 3);
  25. config.insert("sub-page.color", QColor(255, 255, 255));
  26. config.insert("add-page.color", QColor(255, 255, 255, 64));
  27. config.insert("handle.color", QColor(255, 255, 255));
  28. config.insert("handle.ring-width", 4);
  29. config.insert("handle.hollow-radius", 6);
  30. config.insert("handle.margin", 4);
  31. QMapIterator<QString, QVariant> i(cfg);
  32. while (i.hasNext()) {
  33. i.next();
  34. config.insert(i.key(), i.value());
  35. }
  36. // get handle size
  37. int w = config["handle.margin"].toInt() + config["handle.ring-width"].toInt()
  38. + config["handle.hollow-radius"].toInt();
  39. config.insert("handle.size", QSize(2 * w, 2 * w));
  40. }
  41. void HollowHandleStyle::drawComplexControl(QStyle::ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
  42. const QWidget *widget) const
  43. {
  44. // draw sub control
  45. const QStyleOptionSlider *opts = static_cast<const QStyleOptionSlider *>(opt);
  46. if (!opts) {
  47. return QProxyStyle::drawComplexControl(cc, opt, p, widget);
  48. }
  49. if (cc != this->CC_Slider || (opts->orientation != Qt::Horizontal)) {
  50. return QProxyStyle::drawComplexControl(cc, opt, p, widget);
  51. }
  52. QRect grooveRect = subControlRect(cc, opt, SC_SliderGroove, widget);
  53. QRect handleRect = subControlRect(cc, opt, SC_SliderHandle, widget);
  54. p->setRenderHints(QPainter::Antialiasing);
  55. p->setPen(Qt::NoPen);
  56. // paint groove
  57. p->save();
  58. p->translate(grooveRect.topLeft());
  59. // paint the crossed part
  60. int w = handleRect.x() - grooveRect.x();
  61. int h = config["groove.height"].toInt();
  62. p->setBrush(config["sub-page.color"].value<QColor>());
  63. p->drawRect(0, 0, w, h);
  64. // paint the uncrossed part
  65. int x = w + config["handle.size"].toSize().width();
  66. p->setBrush(config["add-page.color"].value<QColor>());
  67. p->drawRect(x, 0, grooveRect.width() - w, h);
  68. p->restore();
  69. // paint handle
  70. int ringWidth = config["handle.ring-width"].toInt();
  71. int hollowRadius = config["handle.hollow-radius"].toInt();
  72. int radius = ringWidth + hollowRadius;
  73. QPainterPath path;
  74. path.moveTo(0, 0);
  75. QPoint center = handleRect.center() + QPoint(1, 1);
  76. path.addEllipse(center, radius, radius);
  77. path.addEllipse(center, hollowRadius, hollowRadius);
  78. QColor handleColor = config["handle.color"].value<QColor>();
  79. if (opt->activeSubControls != SC_SliderHandle) {
  80. handleColor.setAlpha(255);
  81. } else {
  82. handleColor.setAlpha(153);
  83. }
  84. p->setBrush(handleColor);
  85. p->drawPath(path);
  86. // press handle
  87. const QAbstractSlider *wslider = qobject_cast<const QAbstractSlider *>(widget);
  88. if (wslider && wslider->isSliderDown()) {
  89. handleColor.setAlpha(255);
  90. p->setBrush(handleColor);
  91. p->drawEllipse(handleRect);
  92. }
  93. }
  94. QRect HollowHandleStyle::subControlRect(QStyle::ComplexControl cc, const QStyleOptionComplex *opt,
  95. QStyle::SubControl sc, const QWidget *widget) const
  96. {
  97. // get the rectangular area occupied by the sub control
  98. const QStyleOptionSlider *opts = static_cast<const QStyleOptionSlider *>(opt);
  99. if (!opts) {
  100. return QProxyStyle::subControlRect(cc, opt, sc, widget);
  101. }
  102. if (cc != this->CC_Slider || (opts->orientation != Qt::Horizontal) || sc == SC_SliderTickmarks) {
  103. return QProxyStyle::subControlRect(cc, opt, sc, widget);
  104. }
  105. QRect rect = opt->rect;
  106. if (sc == SC_SliderGroove) {
  107. int h = config["groove.height"].toInt();
  108. QRectF grooveRect(0, (rect.height() - h) / 2.0, rect.width(), h);
  109. return grooveRect.toRect();
  110. } else if (sc == SC_SliderHandle) {
  111. QSize size = config["handle.size"].toSize();
  112. double x = sliderPositionFromValue(opts->minimum, opts->maximum, opts->sliderPosition, rect.width());
  113. // solve the situation that the handle runs out of slider
  114. x *= (rect.width() - size.width()) * 1.0 / rect.width();
  115. QRectF sliderRect(x, 0, size.width(), size.height());
  116. return sliderRect.toRect();
  117. }
  118. // 正常不会到这里
  119. return QProxyStyle::subControlRect(cc, opt, sc, widget);
  120. }