qtmaterialcircularprogress.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #include "qtmaterialcircularprogress.h"
  2. #include "qtmaterialcircularprogress_p.h"
  3. #include <QPropertyAnimation>
  4. #include <QParallelAnimationGroup>
  5. #include <QPainter>
  6. #include <QPainterPath>
  7. #include "qtmaterialcircularprogress_internal.h"
  8. #include "lib/qtmaterialstyle.h"
  9. /*!
  10. * \class QtMaterialCircularProgressPrivate
  11. * \internal
  12. */
  13. QtMaterialCircularProgressPrivate::QtMaterialCircularProgressPrivate(QtMaterialCircularProgress *q)
  14. : q_ptr(q)
  15. {
  16. }
  17. QtMaterialCircularProgressPrivate::~QtMaterialCircularProgressPrivate()
  18. {
  19. }
  20. void QtMaterialCircularProgressPrivate::init()
  21. {
  22. Q_Q(QtMaterialCircularProgress);
  23. delegate = new QtMaterialCircularProgressDelegate(q);
  24. progressType = Material::IndeterminateProgress;
  25. penWidth = 6.25;
  26. size = 64;
  27. useThemeColors = true;
  28. q->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding,
  29. QSizePolicy::MinimumExpanding));
  30. QParallelAnimationGroup *group = new QParallelAnimationGroup(q);
  31. group->setLoopCount(-1);
  32. QPropertyAnimation *animation;
  33. animation = new QPropertyAnimation(q);
  34. animation->setPropertyName("dashLength");
  35. animation->setTargetObject(delegate);
  36. animation->setEasingCurve(QEasingCurve::InOutQuad);
  37. animation->setStartValue(0.1);
  38. animation->setKeyValueAt(0.15, 0.2);
  39. animation->setKeyValueAt(0.6, 20);
  40. animation->setKeyValueAt(0.7, 20);
  41. animation->setEndValue(20);
  42. animation->setDuration(2050);
  43. group->addAnimation(animation);
  44. animation = new QPropertyAnimation(q);
  45. animation->setPropertyName("dashOffset");
  46. animation->setTargetObject(delegate);
  47. animation->setEasingCurve(QEasingCurve::InOutSine);
  48. animation->setStartValue(0);
  49. animation->setKeyValueAt(0.15, 0);
  50. animation->setKeyValueAt(0.6, -7);
  51. animation->setKeyValueAt(0.7, -7);
  52. animation->setEndValue(-25);
  53. animation->setDuration(2050);
  54. group->addAnimation(animation);
  55. animation = new QPropertyAnimation(q);
  56. animation->setPropertyName("angle");
  57. animation->setTargetObject(delegate);
  58. animation->setStartValue(0);
  59. animation->setEndValue(719);
  60. animation->setDuration(2050);
  61. group->addAnimation(animation);
  62. group->start();
  63. }
  64. /*!
  65. * \class QtMaterialCircularProgress
  66. */
  67. QtMaterialCircularProgress::QtMaterialCircularProgress(QWidget *parent)
  68. : QProgressBar(parent),
  69. d_ptr(new QtMaterialCircularProgressPrivate(this))
  70. {
  71. d_func()->init();
  72. }
  73. QtMaterialCircularProgress::~QtMaterialCircularProgress()
  74. {
  75. }
  76. void QtMaterialCircularProgress::setProgressType(Material::ProgressType type)
  77. {
  78. Q_D(QtMaterialCircularProgress);
  79. d->progressType = type;
  80. update();
  81. }
  82. Material::ProgressType QtMaterialCircularProgress::progressType() const
  83. {
  84. Q_D(const QtMaterialCircularProgress);
  85. return d->progressType;
  86. }
  87. void QtMaterialCircularProgress::setUseThemeColors(bool value)
  88. {
  89. Q_D(QtMaterialCircularProgress);
  90. if (d->useThemeColors == value) {
  91. return;
  92. }
  93. d->useThemeColors = value;
  94. update();
  95. }
  96. bool QtMaterialCircularProgress::useThemeColors() const
  97. {
  98. Q_D(const QtMaterialCircularProgress);
  99. return d->useThemeColors;
  100. }
  101. void QtMaterialCircularProgress::setLineWidth(qreal width)
  102. {
  103. Q_D(QtMaterialCircularProgress);
  104. d->penWidth = width;
  105. update();
  106. updateGeometry();
  107. }
  108. qreal QtMaterialCircularProgress::lineWidth() const
  109. {
  110. Q_D(const QtMaterialCircularProgress);
  111. return d->penWidth;
  112. }
  113. void QtMaterialCircularProgress::setSize(int size)
  114. {
  115. Q_D(QtMaterialCircularProgress);
  116. d->size = size;
  117. update();
  118. updateGeometry();
  119. }
  120. int QtMaterialCircularProgress::size() const
  121. {
  122. Q_D(const QtMaterialCircularProgress);
  123. return d->size;
  124. }
  125. void QtMaterialCircularProgress::setColor(const QColor &color)
  126. {
  127. Q_D(QtMaterialCircularProgress);
  128. d->color = color;
  129. MATERIAL_DISABLE_THEME_COLORS
  130. update();
  131. }
  132. QColor QtMaterialCircularProgress::color() const
  133. {
  134. Q_D(const QtMaterialCircularProgress);
  135. if (d->useThemeColors || !d->color.isValid()) {
  136. return QtMaterialStyle::instance().themeColor("primary1");
  137. } else {
  138. return d->color;
  139. }
  140. }
  141. /*!
  142. * \reimp
  143. */
  144. QSize QtMaterialCircularProgress::sizeHint() const
  145. {
  146. Q_D(const QtMaterialCircularProgress);
  147. const qreal s = d->size+d->penWidth+8;
  148. return QSize(s, s);
  149. }
  150. /*!
  151. * \reimp
  152. */
  153. void QtMaterialCircularProgress::paintEvent(QPaintEvent *event)
  154. {
  155. Q_UNUSED(event)
  156. Q_D(QtMaterialCircularProgress);
  157. QPainter painter(this);
  158. painter.setRenderHint(QPainter::Antialiasing);
  159. if (!isEnabled())
  160. {
  161. QPen pen;
  162. pen.setCapStyle(Qt::RoundCap);
  163. pen.setWidthF(d->penWidth);
  164. pen.setColor(QtMaterialStyle::instance().themeColor("border"));
  165. painter.setPen(pen);
  166. painter.drawLine(rect().center()-QPointF(20, 20), rect().center()+QPointF(20, 20));
  167. painter.drawLine(rect().center()+QPointF(20, -20), rect().center()-QPointF(20, -20));
  168. return;
  169. }
  170. if (Material::IndeterminateProgress == d->progressType)
  171. {
  172. painter.translate(width()/2, height()/2);
  173. painter.rotate(d->delegate->angle());
  174. }
  175. QPen pen;
  176. pen.setCapStyle(Qt::RoundCap);
  177. pen.setWidthF(d->penWidth);
  178. pen.setColor(color());
  179. if (Material::IndeterminateProgress == d->progressType)
  180. {
  181. QVector<qreal> pattern;
  182. pattern << d->delegate->dashLength()*d->size/50 << 30*d->size/50;
  183. pen.setDashOffset(d->delegate->dashOffset()*d->size/50);
  184. pen.setDashPattern(pattern);
  185. painter.setPen(pen);
  186. painter.drawEllipse(QPoint(0, 0), d->size/2, d->size/2);
  187. }
  188. else
  189. {
  190. painter.setPen(pen);
  191. const qreal x = (width()-d->size)/2;
  192. const qreal y = (height()-d->size)/2;
  193. const qreal a = 360*(value()-minimum())/(maximum()-minimum());
  194. QPainterPath path;
  195. path.arcMoveTo(x, y, d->size, d->size, 0);
  196. path.arcTo(x, y, d->size, d->size, 0, a);
  197. painter.drawPath(path);
  198. }
  199. }