]> cloud.milkyroute.net Git - dolphin.git/blob - src/animatedheightwidget.cpp
GIT_SILENT Sync po/docbooks with svn
[dolphin.git] / src / animatedheightwidget.cpp
1 /*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2024 Felix Ernst <felixernst@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7
8 #include "animatedheightwidget.h"
9
10 #include <QGridLayout>
11 #include <QPropertyAnimation>
12 #include <QScrollArea>
13 #include <QScrollBar>
14 #include <QStyle>
15
16 AnimatedHeightWidget::AnimatedHeightWidget(QWidget *parent)
17 : QWidget{parent}
18 {
19 // Showing of this widget is normally animated. We hide it for now and make it small.
20 hide();
21 setMaximumHeight(0);
22
23 auto fillParentLayout = new QGridLayout(this);
24 fillParentLayout->setContentsMargins(0, 0, 0, 0);
25
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);
37
38 setMinimumWidth(0);
39 }
40
41 QSize AnimatedHeightWidget::sizeHint() const
42 {
43 return QSize{1, preferredHeight()};
44 // 1 as width because this widget should never be the reason the DolphinViewContainer is made wider.
45 }
46
47 void AnimatedHeightWidget::setVisible(bool visible, Animated animated)
48 {
49 setEnabled(visible);
50 if (m_heightAnimation) {
51 m_heightAnimation->stop(); // deletes because of QAbstractAnimation::DeleteWhenStopped.
52 }
53
54 if (animated == WithAnimation
55 && (style()->styleHint(QStyle::SH_Widget_Animation_Duration, nullptr, this) < 1 || GlobalConfig::animationDurationFactor() <= 0.0)) {
56 animated = WithoutAnimation;
57 }
58
59 if (animated == WithoutAnimation) {
60 setMaximumHeight(visible ? preferredHeight() : 0);
61 setVisible(visible);
62 return;
63 }
64
65 m_heightAnimation = new QPropertyAnimation(this, "maximumHeight");
66 m_heightAnimation->setDuration(2 * style()->styleHint(QStyle::SH_Widget_Animation_Duration, nullptr, this) * GlobalConfig::animationDurationFactor());
67
68 m_heightAnimation->setStartValue(height());
69 m_heightAnimation->setEasingCurve(QEasingCurve::OutCubic);
70 if (visible) {
71 show();
72 m_heightAnimation->setEndValue(preferredHeight());
73 } else {
74 m_heightAnimation->setEndValue(0);
75 connect(m_heightAnimation, &QAbstractAnimation::finished, this, &QWidget::hide);
76 }
77
78 m_heightAnimation->start(QAbstractAnimation::DeleteWhenStopped);
79 }
80
81 QWidget *AnimatedHeightWidget::prepareContentsContainer(QWidget *contentsContainer)
82 {
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;
90 }
91
92 bool AnimatedHeightWidget::isAnimationRunning() const
93 {
94 return m_heightAnimation && m_heightAnimation->state() == QAbstractAnimation::Running;
95 }