spoiler.cpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #include "StdInc.h"
  2. #include <QPropertyAnimation>
  3. #include "spoiler.h"
  4. Spoiler::Spoiler(const QString & title, const int animationDuration, QWidget *parent) : QWidget(parent), animationDuration(animationDuration)
  5. {
  6. toggleButton.setStyleSheet("QToolButton { border: none; }");
  7. toggleButton.setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
  8. toggleButton.setArrowType(Qt::ArrowType::RightArrow);
  9. toggleButton.setText(title);
  10. toggleButton.setCheckable(true);
  11. toggleButton.setChecked(false);
  12. headerLine.setFrameShape(QFrame::HLine);
  13. headerLine.setFrameShadow(QFrame::Sunken);
  14. headerLine.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
  15. contentArea.setStyleSheet("QScrollArea { background-color: white; border: none; }");
  16. contentArea.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
  17. // start out collapsed
  18. contentArea.setMaximumHeight(0);
  19. contentArea.setMinimumHeight(0);
  20. // let the entire widget grow and shrink with its content
  21. toggleAnimation.addAnimation(new QPropertyAnimation(this, "minimumHeight"));
  22. toggleAnimation.addAnimation(new QPropertyAnimation(this, "maximumHeight"));
  23. toggleAnimation.addAnimation(new QPropertyAnimation(&contentArea, "maximumHeight"));
  24. // don't waste space
  25. mainLayout.setVerticalSpacing(0);
  26. mainLayout.setContentsMargins(0, 0, 0, 0);
  27. int row = 0;
  28. mainLayout.addWidget(&toggleButton, row, 0, 1, 1, Qt::AlignLeft);
  29. mainLayout.addWidget(&headerLine, row++, 2, 1, 1);
  30. mainLayout.addWidget(&contentArea, row, 0, 1, 3);
  31. setLayout(&mainLayout);
  32. QObject::connect(&toggleButton, &QToolButton::clicked, [this](const bool checked) {
  33. toggleButton.setArrowType(checked ? Qt::ArrowType::DownArrow : Qt::ArrowType::RightArrow);
  34. toggleAnimation.setDirection(checked ? QAbstractAnimation::Forward : QAbstractAnimation::Backward);
  35. toggleAnimation.start();
  36. });
  37. }
  38. void Spoiler::setContentLayout(QLayout & contentLayout)
  39. {
  40. delete contentArea.layout();
  41. contentArea.setLayout(&contentLayout);
  42. const auto collapsedHeight = sizeHint().height() - contentArea.maximumHeight();
  43. auto contentHeight = contentLayout.sizeHint().height();
  44. for (int i = 0; i < toggleAnimation.animationCount() - 1; ++i) {
  45. QPropertyAnimation * spoilerAnimation = static_cast<QPropertyAnimation *>(toggleAnimation.animationAt(i));
  46. spoilerAnimation->setDuration(animationDuration);
  47. spoilerAnimation->setStartValue(collapsedHeight);
  48. spoilerAnimation->setEndValue(collapsedHeight + contentHeight);
  49. }
  50. QPropertyAnimation * contentAnimation = static_cast<QPropertyAnimation *>(toggleAnimation.animationAt(toggleAnimation.animationCount() - 1));
  51. contentAnimation->setDuration(animationDuration);
  52. contentAnimation->setStartValue(0);
  53. contentAnimation->setEndValue(contentHeight);
  54. }