File indexing completed on 2024-05-12 16:39:55
0001 /* This file is part of the KDE project 0002 Copyright (C) 2011 Jarosław Staniek <staniek@kde.org> 0003 0004 This program is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this program; see the file COPYING. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 * Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "KexiAnimatedLayout.h" 0021 #include "KexiAnimatedLayout_p.h" 0022 0023 #include <kexiutils/utils.h> 0024 0025 #include <QPainter> 0026 #include <QPaintEvent> 0027 #include <QDebug> 0028 0029 KexiAnimatedLayout::Private::Private(KexiAnimatedLayout * qq) 0030 : QWidget(), q(qq), animation(this, "pos") 0031 { 0032 hide(); 0033 setAttribute(Qt::WA_OpaquePaintEvent, true); 0034 animation.setEasingCurve(QEasingCurve::InOutQuart); 0035 animation.setDuration(500); 0036 connect(&animation, SIGNAL(finished()), this, SLOT(animationFinished())); 0037 } 0038 0039 void KexiAnimatedLayout::Private::animateTo(QWidget* destination) 0040 { 0041 QWidget *from = q->currentWidget(); 0042 Q_ASSERT(destination && from); 0043 destinationWidget = destination; 0044 if (from == destinationWidget) 0045 return; 0046 if (!(KexiUtils::graphicEffectsLevel() & KexiUtils::SimpleAnimationEffects)) 0047 { 0048 // animations not allowed: switch to destination widget immediately 0049 animationFinished(); 0050 return; 0051 } 0052 bool toRight = q->currentIndex() < q->indexOf(destinationWidget); 0053 hide(); 0054 setParent(from); 0055 QSize s(from->parentWidget()->size()); 0056 QPoint startPos(toRight ? QPoint(0, 0) : QPoint(s.width(), 0)); 0057 QPoint endPos(toRight ? QPoint(s.width(), 0) : QPoint(0, 0)); 0058 animation.setStartValue(-startPos); 0059 animation.setEndValue(-endPos); 0060 buffer = QPixmap(s.width() * 2, s.height()); 0061 buffer.fill(Qt::white); 0062 from->render(&buffer, startPos); 0063 //qDebug() << s << from->geometry() << destinationWidget->geometry(); 0064 destinationWidget->resize(from->size()); // needed because destination could 0065 // have been never displayed 0066 destinationWidget->render(&buffer, endPos); 0067 resize(buffer.size()); 0068 move(animation.startValue().toPoint().x(), animation.startValue().toPoint().y()); 0069 show(); 0070 animation.start(); 0071 } 0072 0073 void KexiAnimatedLayout::Private::paintEvent(QPaintEvent* event) 0074 { 0075 if (buffer.isNull()) 0076 return; 0077 QPainter p(this); 0078 p.drawPixmap(event->rect(), buffer, event->rect()); 0079 } 0080 0081 void KexiAnimatedLayout::Private::animationFinished() 0082 { 0083 if (destinationWidget) { 0084 static_cast<QStackedLayout*>(q)->setCurrentWidget(destinationWidget); 0085 } 0086 hide(); 0087 destinationWidget = 0; 0088 buffer = QPixmap(); 0089 } 0090 0091 // ---- 0092 0093 KexiAnimatedLayout::KexiAnimatedLayout(QWidget* parent) 0094 : QStackedLayout(parent) 0095 , d(new Private(this)) 0096 { 0097 } 0098 0099 KexiAnimatedLayout::~KexiAnimatedLayout() 0100 { 0101 delete d; 0102 } 0103 0104 void KexiAnimatedLayout::setCurrentWidget(QWidget* widget) 0105 { 0106 if (indexOf(widget) < 0) { 0107 return; 0108 } 0109 if (!currentWidget()) { 0110 QStackedLayout::setCurrentWidget(widget); 0111 return; 0112 } 0113 d->animateTo(widget); 0114 } 0115 0116 void KexiAnimatedLayout::setCurrentIndex(int index) 0117 { 0118 QWidget *w = widget(index); 0119 if (!w) 0120 return; 0121 0122 setCurrentWidget(w); 0123 }