File indexing completed on 2024-04-28 04:18:53

0001 /*
0002 Gwenview: an image viewer
0003 Copyright 2007 Aurélien Gâteau <agateau@kde.org>
0004 
0005 This program is free software; you can redistribute it and/or
0006 modify it under the terms of the GNU General Public License
0007 as published by the Free Software Foundation; either version 2
0008 of the License, or (at your option) any later version.
0009 
0010 This program is distributed in the hope that it will be useful,
0011 but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 GNU General Public License for more details.
0014 
0015 You should have received a copy of the GNU General Public License
0016 along with this program; if not, write to the Free Software
0017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
0018 
0019 */
0020 // Self
0021 #include "slidecontainer.h"
0022 
0023 // KF
0024 
0025 // Qt
0026 #include <QEvent>
0027 #include <QPropertyAnimation>
0028 #include <QResizeEvent>
0029 
0030 namespace Gwenview
0031 {
0032 static const int SLIDE_DURATION = 250;
0033 
0034 SlideContainer::SlideContainer(QWidget *parent)
0035     : QFrame(parent)
0036     , mContent(nullptr)
0037 {
0038     mSlidingOut = false;
0039     setFixedHeight(0);
0040 }
0041 
0042 QWidget *SlideContainer::content() const
0043 {
0044     return mContent;
0045 }
0046 
0047 void SlideContainer::setContent(QWidget *content)
0048 {
0049     if (mContent) {
0050         mContent->setParent(nullptr);
0051         mContent->removeEventFilter(this);
0052     }
0053     mContent = content;
0054     if (mContent) {
0055         mContent->setParent(this);
0056         mContent->installEventFilter(this);
0057         mContent->hide();
0058     }
0059 }
0060 
0061 void SlideContainer::animTo(int newHeight)
0062 {
0063     delete mAnim.data();
0064     auto anim = new QPropertyAnimation(this, "slideHeight", this);
0065     anim->setDuration(SLIDE_DURATION);
0066     anim->setStartValue(slideHeight());
0067     anim->setEndValue(newHeight);
0068     anim->start(QAbstractAnimation::DeleteWhenStopped);
0069     connect(anim, &QPropertyAnimation::finished, this, &SlideContainer::slotAnimFinished);
0070     mAnim = anim;
0071 }
0072 
0073 void SlideContainer::slideIn()
0074 {
0075     mSlidingOut = false;
0076     mContent->show();
0077     mContent->adjustSize();
0078     delete mAnim.data();
0079     if (height() == mContent->height()) {
0080         return;
0081     }
0082     animTo(mContent->height());
0083 }
0084 
0085 void SlideContainer::slideOut()
0086 {
0087     if (height() == 0) {
0088         return;
0089     }
0090     mSlidingOut = true;
0091     animTo(0);
0092 }
0093 
0094 QSize SlideContainer::sizeHint() const
0095 {
0096     if (mContent) {
0097         return mContent->sizeHint();
0098     } else {
0099         return {};
0100     }
0101 }
0102 
0103 QSize SlideContainer::minimumSizeHint() const
0104 {
0105     if (mContent) {
0106         return mContent->minimumSizeHint();
0107     } else {
0108         return {};
0109     }
0110 }
0111 
0112 void SlideContainer::resizeEvent(QResizeEvent *event)
0113 {
0114     if (mContent) {
0115         if (event->oldSize().width() != width()) {
0116             adjustContentGeometry();
0117         }
0118     }
0119 }
0120 
0121 void SlideContainer::adjustContentGeometry()
0122 {
0123     if (mContent) {
0124         const int contentHeight = mContent->hasHeightForWidth() ? mContent->heightForWidth(width()) : mContent->height();
0125         mContent->setGeometry(0, height() - contentHeight, width(), contentHeight);
0126     }
0127 }
0128 
0129 bool SlideContainer::eventFilter(QObject *, QEvent *event)
0130 {
0131     switch (event->type()) {
0132     case QEvent::Resize:
0133         if (!mSlidingOut && height() != 0) {
0134             animTo(mContent->height());
0135         }
0136         break;
0137     case QEvent::LayoutRequest:
0138         mContent->adjustSize();
0139         break;
0140     default:
0141         break;
0142     }
0143     return false;
0144 }
0145 
0146 int SlideContainer::slideHeight() const
0147 {
0148     return isVisible() ? height() : 0;
0149 }
0150 
0151 void SlideContainer::setSlideHeight(int value)
0152 {
0153     setFixedHeight(value);
0154     adjustContentGeometry();
0155 }
0156 
0157 void SlideContainer::slotAnimFinished()
0158 {
0159     if (height() == 0) {
0160         mSlidingOut = false;
0161         Q_EMIT slidedOut();
0162     } else {
0163         Q_EMIT slidedIn();
0164     }
0165 }
0166 
0167 } // namespace
0168 
0169 #include "moc_slidecontainer.cpp"