Qt: Add CollapsibleWidget

This commit is contained in:
Connor McLaughlin 2021-05-16 03:23:26 +10:00
parent f5bec87f79
commit 148a706771
5 changed files with 93 additions and 3 deletions

View file

@ -24,6 +24,8 @@ set(SRCS
cheatcodeeditordialog.cpp cheatcodeeditordialog.cpp
cheatcodeeditordialog.h cheatcodeeditordialog.h
cheatcodeeditordialog.ui cheatcodeeditordialog.ui
collapsiblewidget.cpp
collapsiblewidget.h
consolesettingswidget.cpp consolesettingswidget.cpp
consolesettingswidget.h consolesettingswidget.h
consolesettingswidget.ui consolesettingswidget.ui

View file

@ -0,0 +1,56 @@
#include <QtCore/QPropertyAnimation>
#include "collapsiblewidget.h"
CollapsibleWidget::CollapsibleWidget(const QString& title, const int animationDuration, QWidget* parent)
: QWidget(parent), animationDuration(animationDuration)
{
toggleButton.setStyleSheet("QToolButton { border: none; }");
toggleButton.setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
toggleButton.setArrowType(Qt::ArrowType::RightArrow);
toggleButton.setText(title);
toggleButton.setCheckable(true);
toggleButton.setChecked(false);
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"));
// don't waste space
mainLayout.setContentsMargins(0, 0, 0, 0);
mainLayout.addWidget(&toggleButton);
mainLayout.addWidget(&contentArea);
setLayout(&mainLayout);
QObject::connect(&toggleButton, &QToolButton::clicked, [this](const bool checked) {
toggleButton.setArrowType(checked ? Qt::ArrowType::DownArrow : Qt::ArrowType::RightArrow);
toggleAnimation.setDirection(checked ? QAbstractAnimation::Forward : QAbstractAnimation::Backward);
toggleAnimation.start();
});
}
void CollapsibleWidget::setContentLayout(QLayout* contentLayout)
{
delete contentArea.layout();
contentArea.setLayout(contentLayout);
const auto collapsedHeight = sizeHint().height() - contentArea.maximumHeight();
auto contentHeight = contentLayout->sizeHint().height();
for (int i = 0; i < toggleAnimation.animationCount() - 1; ++i)
{
QPropertyAnimation* spoilerAnimation = static_cast<QPropertyAnimation*>(toggleAnimation.animationAt(i));
spoilerAnimation->setDuration(animationDuration);
spoilerAnimation->setStartValue(collapsedHeight);
spoilerAnimation->setEndValue(collapsedHeight + contentHeight);
}
QPropertyAnimation* contentAnimation =
static_cast<QPropertyAnimation*>(toggleAnimation.animationAt(toggleAnimation.animationCount() - 1));
contentAnimation->setDuration(animationDuration);
contentAnimation->setStartValue(0);
contentAnimation->setEndValue(contentHeight);
}

View file

@ -0,0 +1,27 @@
// https://stackoverflow.com/questions/32476006/how-to-make-an-expandable-collapsable-section-widget-in-qt
#pragma once
#include <QtCore/QParallelAnimationGroup>
#include <QtWidgets/QScrollArea>
#include <QtWidgets/QToolButton>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>
class CollapsibleWidget : public QWidget
{
Q_OBJECT
private:
QVBoxLayout mainLayout;
QToolButton toggleButton;
QParallelAnimationGroup toggleAnimation;
QScrollArea contentArea;
int animationDuration{300};
public:
explicit CollapsibleWidget(const QString& title = "", const int animationDuration = 300, QWidget* parent = 0);
QScrollArea* getScrollArea() { return &contentArea; }
void setContentLayout(QLayout* contentLayout);
};

View file

@ -60,6 +60,7 @@
<ClCompile Include="biossettingswidget.cpp" /> <ClCompile Include="biossettingswidget.cpp" />
<ClCompile Include="cheatmanagerdialog.cpp" /> <ClCompile Include="cheatmanagerdialog.cpp" />
<ClCompile Include="cheatcodeeditordialog.cpp" /> <ClCompile Include="cheatcodeeditordialog.cpp" />
<ClCompile Include="collapsiblewidget.cpp" />
<ClCompile Include="consolesettingswidget.cpp" /> <ClCompile Include="consolesettingswidget.cpp" />
<ClCompile Include="emulationsettingswidget.cpp" /> <ClCompile Include="emulationsettingswidget.cpp" />
<ClCompile Include="debuggermodels.cpp" /> <ClCompile Include="debuggermodels.cpp" />
@ -118,6 +119,7 @@
<QtMoc Include="debuggerwindow.h" /> <QtMoc Include="debuggerwindow.h" />
<QtMoc Include="achievementsettingswidget.h" /> <QtMoc Include="achievementsettingswidget.h" />
<QtMoc Include="achievementlogindialog.h" /> <QtMoc Include="achievementlogindialog.h" />
<QtMoc Include="collapsiblewidget.h" />
<ClInclude Include="inputbindingmonitor.h" /> <ClInclude Include="inputbindingmonitor.h" />
<QtMoc Include="memoryviewwidget.h" /> <QtMoc Include="memoryviewwidget.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
@ -228,6 +230,7 @@
<ClCompile Include="$(IntDir)moc_biossettingswidget.cpp" /> <ClCompile Include="$(IntDir)moc_biossettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_cheatmanagerdialog.cpp" /> <ClCompile Include="$(IntDir)moc_cheatmanagerdialog.cpp" />
<ClCompile Include="$(IntDir)moc_cheatcodeeditordialog.cpp" /> <ClCompile Include="$(IntDir)moc_cheatcodeeditordialog.cpp" />
<ClCompile Include="$(IntDir)moc_collapsiblewidget.cpp" />
<ClCompile Include="$(IntDir)moc_consolesettingswidget.cpp" /> <ClCompile Include="$(IntDir)moc_consolesettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_controllersettingswidget.cpp" /> <ClCompile Include="$(IntDir)moc_controllersettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_emulationsettingswidget.cpp" /> <ClCompile Include="$(IntDir)moc_emulationsettingswidget.cpp" />
@ -287,7 +290,7 @@
<QtTs Include="translations\duckstation-qt_de.ts"> <QtTs Include="translations\duckstation-qt_de.ts">
<FileType>Document</FileType> <FileType>Document</FileType>
</QtTs> </QtTs>
<QtTs Include="translations\duckstation-qt_en.ts"> <QtTs Include="translations\duckstation-qt_en.ts">
<FileType>Document</FileType> <FileType>Document</FileType>
</QtTs> </QtTs>
<QtTs Include="translations\duckstation-qt_es.ts"> <QtTs Include="translations\duckstation-qt_es.ts">

View file

@ -79,14 +79,16 @@
<ClCompile Include="$(IntDir)moc_emulationsettingswidget.cpp" /> <ClCompile Include="$(IntDir)moc_emulationsettingswidget.cpp" />
<ClCompile Include="achievementsettingswidget.cpp" /> <ClCompile Include="achievementsettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_achievementsettingswidget.cpp" /> <ClCompile Include="$(IntDir)moc_achievementsettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_achievementslogindialog.cpp" />
<ClCompile Include="achievementlogindialog.cpp" /> <ClCompile Include="achievementlogindialog.cpp" />
<ClCompile Include="$(IntDir)moc_achievementlogindialog.cpp" />
<ClCompile Include="collapsiblewidget.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="qtutils.h" /> <ClInclude Include="qtutils.h" />
<ClInclude Include="settingwidgetbinder.h" /> <ClInclude Include="settingwidgetbinder.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="inputbindingmonitor.h" /> <ClInclude Include="inputbindingmonitor.h" />
<ClInclude Include="collapsiblewidget.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="resources"> <Filter Include="resources">
@ -181,7 +183,7 @@
<QtTs Include="translations\duckstation-qt_de.ts"> <QtTs Include="translations\duckstation-qt_de.ts">
<Filter>translations</Filter> <Filter>translations</Filter>
</QtTs> </QtTs>
<QtTs Include="translations\duckstation-qt_en.ts"> <QtTs Include="translations\duckstation-qt_en.ts">
<Filter>translations</Filter> <Filter>translations</Filter>
</QtTs> </QtTs>
<QtTs Include="translations\duckstation-qt_es.ts"> <QtTs Include="translations\duckstation-qt_es.ts">