Skip to content

Commit

Permalink
Merge pull request MichaelVoelkel#7 from MichaelVoelkel/dynamic_section
Browse files Browse the repository at this point in the history
offer updateHeights in case of changed content
  • Loading branch information
MichaelVoelkel authored Jan 8, 2022
2 parents 1ee0f00 + ee0d7a0 commit f03a8e7
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 86 deletions.
152 changes: 86 additions & 66 deletions Section.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,75 +21,95 @@
#include <QPropertyAnimation>

#include "Section.h"

Section::Section(const QString & title, const int animationDuration, QWidget* parent)
: QWidget(parent), animationDuration(animationDuration)
{
toggleButton = new QToolButton(this);
headerLine = new QFrame(this);
toggleAnimation = new QParallelAnimationGroup(this);
contentArea = new QScrollArea(this);
mainLayout = new QGridLayout(this);

toggleButton->setStyleSheet("QToolButton {border: none;}");
toggleButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
toggleButton->setArrowType(Qt::ArrowType::RightArrow);
toggleButton->setText(title);
toggleButton->setCheckable(true);
toggleButton->setChecked(false);

headerLine->setFrameShape(QFrame::HLine);
headerLine->setFrameShadow(QFrame::Sunken);
headerLine->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);

contentArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

// start out collapsed
contentArea->setMaximumHeight(0);
contentArea->setMinimumHeight(0);

// let the entire widget grow and shrink with its content
toggleAnimation->addAnimation(new QPropertyAnimation(this, "minimumHeight"));
toggleAnimation->addAnimation(new QPropertyAnimation(this, "maximumHeight"));
toggleAnimation->addAnimation(new QPropertyAnimation(contentArea, "maximumHeight"));

mainLayout->setVerticalSpacing(0);
mainLayout->setContentsMargins(0, 0, 0, 0);

int row = 0;
mainLayout->addWidget(toggleButton, row, 0, 1, 1, Qt::AlignLeft);
mainLayout->addWidget(headerLine, row++, 2, 1, 1);
mainLayout->addWidget(contentArea, row, 0, 1, 3);
setLayout(mainLayout);

connect(toggleButton, &QToolButton::toggled, this, &Section::toggle);
}


void Section::toggle(bool collapsed) {
toggleButton->setArrowType(collapsed ? Qt::ArrowType::DownArrow : Qt::ArrowType::RightArrow);
toggleAnimation->setDirection(collapsed ? QAbstractAnimation::Forward : QAbstractAnimation::Backward);
toggleAnimation->start();
}


void Section::setContentLayout(QLayout & contentLayout)
#include <QDebug>
namespace ui
{
delete contentArea->layout();
contentArea->setLayout(&contentLayout);
const auto collapsedHeight = sizeHint().height() - contentArea->maximumHeight();
auto contentHeight = contentLayout.sizeHint().height();
Section::Section(const QString& title, const int animationDuration, QWidget* parent)
: QWidget(parent), animationDuration(animationDuration)
{
toggleButton = new QToolButton(this);
headerLine = new QFrame(this);
toggleAnimation = new QParallelAnimationGroup(this);
contentArea = new QScrollArea(this);
mainLayout = new QGridLayout(this);

toggleButton->setStyleSheet("QToolButton {border: none;}");
toggleButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
toggleButton->setArrowType(Qt::ArrowType::RightArrow);
toggleButton->setText(title);
toggleButton->setCheckable(true);
toggleButton->setChecked(false);

headerLine->setFrameShape(QFrame::HLine);
headerLine->setFrameShadow(QFrame::Sunken);
headerLine->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);

contentArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

// start out collapsed
contentArea->setMaximumHeight(0);
contentArea->setMinimumHeight(0);

// let the entire widget grow and shrink with its content
toggleAnimation->addAnimation(new QPropertyAnimation(this, "maximumHeight"));
toggleAnimation->addAnimation(new QPropertyAnimation(this, "minimumHeight"));
toggleAnimation->addAnimation(new QPropertyAnimation(contentArea, "maximumHeight"));

mainLayout->setVerticalSpacing(0);
mainLayout->setContentsMargins(0, 0, 0, 0);

int row = 0;
mainLayout->addWidget(toggleButton, row, 0, 1, 1, Qt::AlignLeft);
mainLayout->addWidget(headerLine, row++, 2, 1, 1);
mainLayout->addWidget(contentArea, row, 0, 1, 3);
setLayout(mainLayout);

connect(toggleButton, &QToolButton::toggled, this, &Section::toggle);
}

for (int i = 0; i < toggleAnimation->animationCount() - 1; ++i)
void Section::toggle(bool expanded)
{
QPropertyAnimation* SectionAnimation = static_cast<QPropertyAnimation *>(toggleAnimation->animationAt(i));
SectionAnimation->setDuration(animationDuration);
SectionAnimation->setStartValue(collapsedHeight);
SectionAnimation->setEndValue(collapsedHeight + contentHeight);
toggleButton->setArrowType(expanded ? Qt::ArrowType::DownArrow : Qt::ArrowType::RightArrow);
toggleAnimation->setDirection(expanded ? QAbstractAnimation::Forward : QAbstractAnimation::Backward);
toggleAnimation->start();

this->isExpanded = expanded;

qDebug() << "MV: toggle: isExpanded " << isExpanded;
}

QPropertyAnimation* contentAnimation = static_cast<QPropertyAnimation *>(toggleAnimation->animationAt(toggleAnimation->animationCount() - 1));
contentAnimation->setDuration(animationDuration);
contentAnimation->setStartValue(0);
contentAnimation->setEndValue(contentHeight);
void Section::setContentLayout(QLayout& contentLayout)
{
delete contentArea->layout();
contentArea->setLayout(&contentLayout);
collapsedHeight = sizeHint().height() - contentArea->maximumHeight();

updateHeights();
}

void Section::setTitle(QString title)
{
toggleButton->setText(std::move(title));
}

void Section::updateHeights()
{
int contentHeight = contentArea->layout()->sizeHint().height();

for (int i = 0; i < toggleAnimation->animationCount() - 1; ++i)
{
QPropertyAnimation* SectionAnimation = static_cast<QPropertyAnimation *>(toggleAnimation->animationAt(i));
SectionAnimation->setDuration(animationDuration);
SectionAnimation->setStartValue(collapsedHeight);
SectionAnimation->setEndValue(collapsedHeight + contentHeight);
}

QPropertyAnimation* contentAnimation = static_cast<QPropertyAnimation *>(toggleAnimation->animationAt(toggleAnimation->animationCount() - 1));
contentAnimation->setDuration(animationDuration);
contentAnimation->setStartValue(0);
contentAnimation->setEndValue(contentHeight);

toggleAnimation->setDirection(isExpanded ? QAbstractAnimation::Forward : QAbstractAnimation::Backward);
toggleAnimation->start();
}
}
53 changes: 33 additions & 20 deletions Section.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,40 @@
#include <QToolButton>
#include <QWidget>

class Section : public QWidget {
Q_OBJECT
private:
namespace ui
{
class Section : public QWidget
{
Q_OBJECT

private:
QGridLayout* mainLayout;
QToolButton* toggleButton;
QFrame* headerLine;
QParallelAnimationGroup* toggleAnimation;
QScrollArea* contentArea;
int animationDuration;
int collapsedHeight;
bool isExpanded = false;

public slots:
void toggle(bool collapsed);

QGridLayout* mainLayout;
QToolButton* toggleButton;
QFrame* headerLine;
QParallelAnimationGroup* toggleAnimation;
QScrollArea* contentArea;
int animationDuration;
public:
static const int DEFAULT_DURATION = 0;

// initialize section
explicit Section(const QString& title = "", const int animationDuration = DEFAULT_DURATION, QWidget* parent = 0);


public slots:

void toggle(bool collapsed);


public:
explicit Section(const QString & title = "", const int animationDuration = 100, QWidget* parent = 0);

void setContentLayout(QLayout & contentLayout);
};
// set layout of content
void setContentLayout(QLayout& contentLayout);

// set title
void setTitle(QString title);

// update animations and their heights
void updateHeights();
};
}

#endif // SECTION_H

0 comments on commit f03a8e7

Please sign in to comment.