2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2024 Felix Ernst <felixernst@kde.org>
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
8 #include "animatedheightwidget.h"
10 #include <QGridLayout>
11 #include <QPropertyAnimation>
12 #include <QScrollArea>
16 AnimatedHeightWidget::AnimatedHeightWidget(QWidget
*parent
)
19 // Showing of this widget is normally animated. We hide it for now and make it small.
23 auto fillParentLayout
= new QGridLayout(this);
24 fillParentLayout
->setContentsMargins(0, 0, 0, 0);
26 // Put the contents into a QScrollArea. This prevents increasing the view width
27 // in case there is not enough available width for the contents.
28 m_contentsContainerParent
= new QScrollArea(this);
29 fillParentLayout
->addWidget(m_contentsContainerParent
);
30 m_contentsContainerParent
->setFrameShape(QFrame::NoFrame
);
31 m_contentsContainerParent
->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff
);
32 m_contentsContainerParent
->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff
);
33 m_contentsContainerParent
->setWidgetResizable(true);
34 // Disables manual scrolling, for example with mouse scrollwheel.
35 m_contentsContainerParent
->verticalScrollBar()->setEnabled(false);
36 m_contentsContainerParent
->horizontalScrollBar()->setEnabled(false);
41 QSize
AnimatedHeightWidget::sizeHint() const
43 return QSize
{1, preferredHeight()};
44 // 1 as width because this widget should never be the reason the DolphinViewContainer is made wider.
47 void AnimatedHeightWidget::setVisible(bool visible
, Animated animated
)
50 if (m_heightAnimation
) {
51 m_heightAnimation
->stop(); // deletes because of QAbstractAnimation::DeleteWhenStopped.
54 if (animated
== WithAnimation
55 && (style()->styleHint(QStyle::SH_Widget_Animation_Duration
, nullptr, this) < 1 || GlobalConfig::animationDurationFactor() <= 0.0)) {
56 animated
= WithoutAnimation
;
59 if (animated
== WithoutAnimation
) {
60 setMaximumHeight(visible
? preferredHeight() : 0);
65 m_heightAnimation
= new QPropertyAnimation(this, "maximumHeight");
66 m_heightAnimation
->setDuration(2 * style()->styleHint(QStyle::SH_Widget_Animation_Duration
, nullptr, this) * GlobalConfig::animationDurationFactor());
68 m_heightAnimation
->setStartValue(height());
69 m_heightAnimation
->setEasingCurve(QEasingCurve::OutCubic
);
72 m_heightAnimation
->setEndValue(preferredHeight());
74 m_heightAnimation
->setEndValue(0);
75 connect(m_heightAnimation
, &QAbstractAnimation::finished
, this, &QWidget::hide
);
78 m_heightAnimation
->start(QAbstractAnimation::DeleteWhenStopped
);
81 QWidget
*AnimatedHeightWidget::prepareContentsContainer(QWidget
*contentsContainer
)
83 Q_ASSERT_X(!m_contentsContainerParent
->widget(),
84 "AnimatedHeightWidget::prepareContentsContainer",
85 "Another contentsContainer has already been prepared. There can only be one.");
86 contentsContainer
->setParent(m_contentsContainerParent
);
87 m_contentsContainerParent
->setWidget(contentsContainer
);
88 m_contentsContainerParent
->setFocusProxy(contentsContainer
);
89 return contentsContainer
;
92 bool AnimatedHeightWidget::isAnimationRunning() const
94 return m_heightAnimation
&& m_heightAnimation
->state() == QAbstractAnimation::Running
;