qtmaterialtabs_internal.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #include "qtmaterialtabs_internal.h"
  2. #include <QPainter>
  3. #include <QPropertyAnimation>
  4. #include <QtWidgets/QLayout>
  5. #include <QtWidgets/QLayoutItem>
  6. #include <QEvent>
  7. #include "qtmaterialtabs.h"
  8. #include <QDebug>
  9. /*!
  10. * \class QtMaterialTabsInkBar
  11. * \internal
  12. */
  13. QtMaterialTabsInkBar::QtMaterialTabsInkBar(QtMaterialTabs *parent)
  14. : QtMaterialOverlayWidget(parent),
  15. m_tabs(parent),
  16. m_animation(new QPropertyAnimation(parent)),
  17. m_tween(0)
  18. {
  19. Q_ASSERT(parent);
  20. m_animation->setPropertyName("tweenValue");
  21. m_animation->setEasingCurve(QEasingCurve::OutCirc);
  22. m_animation->setTargetObject(this);
  23. m_animation->setDuration(700);
  24. m_tabs->installEventFilter(this);
  25. setAttribute(Qt::WA_TransparentForMouseEvents);
  26. setAttribute(Qt::WA_NoSystemBackground);
  27. }
  28. QtMaterialTabsInkBar::~QtMaterialTabsInkBar()
  29. {
  30. }
  31. void QtMaterialTabsInkBar::refreshGeometry()
  32. {
  33. QLayoutItem *item = m_tabs->layout()->itemAt(m_tabs->currentIndex());
  34. if (item)
  35. {
  36. const QRect r(item->geometry());
  37. const qreal s = 1-m_tween;
  38. if (QAbstractAnimation::Running != m_animation->state()) {
  39. m_geometry = QRect(r.left(), r.bottom()-1, r.width(), 2);
  40. } else {
  41. const qreal left = m_previousGeometry.left()*s + r.left()*m_tween;
  42. const qreal width = m_previousGeometry.width()*s + r.width()*m_tween;
  43. m_geometry = QRect(left, r.bottom()-1, width, 2);
  44. }
  45. m_tabs->update();
  46. }
  47. }
  48. void QtMaterialTabsInkBar::animate()
  49. {
  50. raise();
  51. m_previousGeometry = m_geometry;
  52. m_animation->stop();
  53. m_animation->setStartValue(0);
  54. m_animation->setEndValue(1);
  55. m_animation->start();
  56. }
  57. bool QtMaterialTabsInkBar::eventFilter(QObject *obj, QEvent *event)
  58. {
  59. switch (event->type())
  60. {
  61. case QEvent::Move:
  62. case QEvent::Resize:
  63. {
  64. refreshGeometry();
  65. break;
  66. }
  67. default:
  68. break;
  69. }
  70. return QtMaterialOverlayWidget::eventFilter(obj, event);
  71. }
  72. void QtMaterialTabsInkBar::paintEvent(QPaintEvent *event)
  73. {
  74. Q_UNUSED(event)
  75. QPainter painter(this);
  76. painter.setOpacity(1);
  77. painter.fillRect(m_geometry, m_tabs->inkColor());
  78. }
  79. /*!
  80. * \class QtMaterialTab
  81. * \internal
  82. */
  83. QtMaterialTab::QtMaterialTab(QtMaterialTabs *parent)
  84. : QtMaterialFlatButton(parent),
  85. m_tabs(parent),
  86. m_active(false)
  87. {
  88. Q_ASSERT(parent);
  89. setMinimumHeight(50);
  90. QFont f(font());
  91. f.setStyleName("Normal");
  92. setFont(f);
  93. setCornerRadius(0);
  94. setRole(Material::Primary);
  95. setBackgroundMode(Qt::OpaqueMode);
  96. setBaseOpacity(0.25);
  97. connect(this, SIGNAL(clicked(bool)), this, SLOT(activateTab()));
  98. }
  99. QtMaterialTab::~QtMaterialTab()
  100. {
  101. }
  102. QSize QtMaterialTab::sizeHint() const
  103. {
  104. if (icon().isNull()) {
  105. return QtMaterialFlatButton::sizeHint();
  106. } else {
  107. return QSize(40, iconSize().height()+46);
  108. }
  109. }
  110. void QtMaterialTab::activateTab()
  111. {
  112. m_tabs->setCurrentTab(this);
  113. }
  114. void QtMaterialTab::paintForeground(QPainter *painter)
  115. {
  116. painter->setPen(foregroundColor());
  117. if (!icon().isNull()) {
  118. painter->translate(0, 12);
  119. }
  120. QSize textSize(fontMetrics().size(Qt::TextSingleLine, text()));
  121. QSize base(size()-textSize);
  122. QRect textGeometry(QPoint(base.width(), base.height())/2, textSize);
  123. painter->drawText(textGeometry, Qt::AlignCenter, text());
  124. if (!icon().isNull())
  125. {
  126. const QSize &size = iconSize();
  127. QRect iconRect(QPoint((width()-size.width())/2, 0), size);
  128. QPixmap pixmap = icon().pixmap(iconSize());
  129. QPainter icon(&pixmap);
  130. icon.setCompositionMode(QPainter::CompositionMode_SourceIn);
  131. icon.fillRect(pixmap.rect(), painter->pen().color());
  132. painter->drawPixmap(iconRect, pixmap);
  133. }
  134. if (!m_active)
  135. {
  136. if (!icon().isNull()) {
  137. painter->translate(0, -12);
  138. }
  139. QBrush overlay;
  140. overlay.setStyle(Qt::SolidPattern);
  141. overlay.setColor(backgroundColor());
  142. painter->setOpacity(0.36);
  143. painter->fillRect(rect(), overlay);
  144. }
  145. }