ExpandGroupSettingCard.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. #include "ExpandGroupSettingCard.h"
  2. #include "QFluentWidgets.h"
  3. #include "SettingCard.h"
  4. #include "Layout/VBoxLayout.h"
  5. #include <QPainter>
  6. #include <QApplication>
  7. #include <QMouseEvent>
  8. ExpandButton::ExpandButton(QWidget *parent) : QAbstractButton(parent), isHover(false), isPressed(false), m_angle(0)
  9. {
  10. setFixedSize(30, 30);
  11. m_rotateAni = new QPropertyAnimation(this, "angle", this);
  12. }
  13. float ExpandButton::getAngle() const
  14. {
  15. return m_angle;
  16. }
  17. void ExpandButton::setAngle(float angle)
  18. {
  19. m_angle = angle;
  20. update();
  21. }
  22. void ExpandButton::setPressed(bool pressed)
  23. {
  24. isPressed = pressed;
  25. update();
  26. }
  27. void ExpandButton::setHover(bool hover)
  28. {
  29. isHover = hover;
  30. update();
  31. }
  32. void ExpandButton::mousePressEvent(QMouseEvent *event)
  33. {
  34. QAbstractButton::mousePressEvent(event);
  35. setPressed(true);
  36. }
  37. void ExpandButton::mouseReleaseEvent(QMouseEvent *event)
  38. {
  39. QAbstractButton::mouseReleaseEvent(event);
  40. setPressed(false);
  41. }
  42. void ExpandButton::enterEvent(QEvent * /*event*/)
  43. {
  44. setHover(true);
  45. }
  46. void ExpandButton::leaveEvent(QEvent * /*event*/)
  47. {
  48. setHover(false);
  49. }
  50. void ExpandButton::paintEvent(QPaintEvent * /*event*/)
  51. {
  52. QPainter painter(this);
  53. painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
  54. painter.setPen(Qt::NoPen);
  55. // draw background
  56. int r = QFWIns.isDarkTheme() ? 255 : 0;
  57. QColor color;
  58. if (isPressed) {
  59. color = QColor(r, r, r, 10);
  60. } else if (isHover) {
  61. color = QColor(r, r, r, 14);
  62. } else {
  63. color = Qt::transparent;
  64. }
  65. painter.setBrush(color);
  66. painter.drawRoundedRect(rect(), 4, 4);
  67. // draw icon
  68. painter.translate(width() / 2, height() / 2);
  69. painter.rotate(m_angle);
  70. QScopedPointer<FluentIcon> ficon(NEWFLICON(FluentIcon, ARROW_DOWN));
  71. ficon->render(&painter, QRectF(-5, -5, 9.6, 9.6).toRect());
  72. }
  73. void ExpandButton::onClicked()
  74. {
  75. if (m_angle < 180) {
  76. m_rotateAni->setEndValue(180);
  77. } else {
  78. m_rotateAni->setEndValue(0);
  79. }
  80. m_rotateAni->setDuration(200);
  81. m_rotateAni->start();
  82. }
  83. ExpandSettingCard::ExpandSettingCard(FluentIconBase *icon, const QString &title, const QString &content,
  84. QWidget *parent)
  85. : QFrame(parent), m_isExpand(false)
  86. {
  87. m_expandButton = new ExpandButton(this);
  88. m_view = new QFrame(this);
  89. m_card = new SettingCard(icon, title, content, this);
  90. viewLayout = new VBoxLayout(m_view);
  91. // expand animation
  92. m_aniGroup = new QParallelAnimationGroup(this);
  93. m_slideAni = new QPropertyAnimation(m_view, "pos", this);
  94. m_expandAni = new QPropertyAnimation(this, "geometry", this);
  95. initWidget();
  96. }
  97. /// add widget to tail
  98. void ExpandSettingCard::addWidget(QWidget *widget)
  99. {
  100. m_card->hBoxLayout->addWidget(widget, 0, Qt::AlignRight);
  101. m_card->hBoxLayout->addSpacing(19);
  102. m_card->hBoxLayout->addWidget(m_expandButton, 0, Qt::AlignRight);
  103. m_card->hBoxLayout->addSpacing(8);
  104. }
  105. /// set the expand status of card
  106. void ExpandSettingCard::setExpand(bool expand)
  107. {
  108. if (m_isExpand == expand) {
  109. return;
  110. }
  111. // update style sheet
  112. m_isExpand = expand;
  113. setProperty("isExpand", expand);
  114. setStyle(QApplication::style());
  115. // start expand animation
  116. int ch = m_card->height();
  117. int vh = m_view->height();
  118. if (expand) {
  119. m_expandAni->setStartValue(this->geometry());
  120. m_expandAni->setEndValue(QRect(this->pos(), QSize(this->width(), ch + vh)));
  121. m_slideAni->setStartValue(QPoint(0, ch - vh));
  122. m_slideAni->setEndValue(QPoint(0, ch));
  123. m_view->show();
  124. } else {
  125. m_expandAni->setStartValue(this->geometry());
  126. m_expandAni->setEndValue(QRect(this->pos(), m_card->size()));
  127. m_slideAni->setStartValue(QPoint(0, ch));
  128. m_slideAni->setEndValue(QPoint(0, ch - vh));
  129. }
  130. m_aniGroup->start();
  131. }
  132. void ExpandSettingCard::setValue(const QVariant &value)
  133. {
  134. Q_UNUSED(value)
  135. }
  136. void ExpandSettingCard::toggleExpand()
  137. {
  138. setExpand(!m_isExpand);
  139. }
  140. void ExpandSettingCard::resizeEvent(QResizeEvent * /*event*/)
  141. {
  142. m_card->resize(this->width(), m_card->height());
  143. m_view->resize(this->width(), m_view->height());
  144. }
  145. bool ExpandSettingCard::eventFilter(QObject *watched, QEvent *event)
  146. {
  147. if (watched == m_card) {
  148. if (event->type() == QEvent::Enter) {
  149. m_expandButton->setHover(true);
  150. } else if (event->type() == QEvent::Leave) {
  151. m_expandButton->setHover(false);
  152. } else if (event->type() == QEvent::MouseButtonPress) {
  153. QMouseEvent *me = static_cast<QMouseEvent *>(event);
  154. if (me->button() == Qt::LeftButton) {
  155. m_expandButton->setPressed(true);
  156. }
  157. } else if (event->type() == QEvent::MouseButtonRelease) {
  158. QMouseEvent *me = static_cast<QMouseEvent *>(event);
  159. if (me->button() == Qt::LeftButton) {
  160. m_expandButton->setPressed(false);
  161. m_expandButton->click();
  162. }
  163. }
  164. }
  165. return QFrame::eventFilter(watched, event);
  166. }
  167. void ExpandSettingCard::initWidget()
  168. {
  169. setMinimumHeight(m_card->height());
  170. m_view->hide();
  171. // initialize expand animation
  172. m_aniGroup->addAnimation(m_expandAni);
  173. m_aniGroup->addAnimation(m_slideAni);
  174. m_slideAni->setEasingCurve(QEasingCurve::OutQuad);
  175. m_expandAni->setEasingCurve(QEasingCurve::OutQuad);
  176. m_slideAni->setDuration(200);
  177. m_expandAni->setDuration(200);
  178. // initialize style sheet
  179. m_view->setObjectName("view");
  180. setProperty("isExpand", false);
  181. FluentStyleSheet::apply("EXPAND_SETTING_CARD", m_card);
  182. FluentStyleSheet::apply("EXPAND_SETTING_CARD", this);
  183. m_card->installEventFilter(this);
  184. connect(m_aniGroup, &QParallelAnimationGroup::finished, this, &ExpandSettingCard::onAniFinished);
  185. connect(m_expandButton, &ExpandButton::clicked, this, &ExpandSettingCard::toggleExpand);
  186. }
  187. void ExpandSettingCard::adjustViewSize()
  188. {
  189. int h = 0;
  190. for (auto w : viewLayout->widgets()) {
  191. h += w->height();
  192. }
  193. int spacing = (viewLayout->widgets().count() - 1) * viewLayout->spacing();
  194. QMargins margin = viewLayout->contentsMargins();
  195. h = h + margin.top() + margin.bottom() + spacing;
  196. m_view->resize(m_view->width(), h);
  197. if (m_view->isVisible()) {
  198. resize(this->width(), h + m_card->height());
  199. }
  200. }
  201. /// expand animation finished slot
  202. void ExpandSettingCard::onAniFinished()
  203. {
  204. if (!m_isExpand) {
  205. m_view->hide();
  206. }
  207. }
  208. QFrame *ExpandSettingCard::view() const
  209. {
  210. return m_view;
  211. }
  212. GroupSeparator::GroupSeparator(QWidget *parent) : QWidget(parent)
  213. {
  214. setFixedHeight(3);
  215. }
  216. void GroupSeparator::paintEvent(QPaintEvent * /*event*/)
  217. {
  218. QPainter painter(this);
  219. int c = QFWIns.isDarkTheme() ? 35 : 230;
  220. painter.setPen(QColor(c, c, c));
  221. painter.drawLine(0, 1, this->width(), 1);
  222. }
  223. ExpandGroupSettingCard::ExpandGroupSettingCard(FluentIconBase *icon, const QString &title, const QString &content,
  224. QWidget *parent)
  225. : ExpandSettingCard(icon, title, content, parent)
  226. {
  227. }
  228. void ExpandGroupSettingCard::addGroupWidget(QWidget *widget)
  229. {
  230. if (viewLayout->widgets().contains(widget)) {
  231. return;
  232. }
  233. // add separator
  234. if (viewLayout->count() >= 1) {
  235. viewLayout->addWidget(new GroupSeparator(this->view()));
  236. }
  237. widget->setParent(this->view());
  238. viewLayout->addWidget(widget);
  239. }