diff options
author | Ken Moore <ken@ixsystems.com> | 2017-07-20 12:40:16 -0400 |
---|---|---|
committer | Ken Moore <ken@ixsystems.com> | 2017-07-20 12:40:16 -0400 |
commit | 23b870f04c46e8fa6d4ca2b14eb6d9ea2285a4c0 (patch) | |
tree | 2c8a5443b880b7261838d264e3db386bfc7a5fd3 | |
parent | Get the compositing working much smoother now. (diff) | |
download | lumina-23b870f04c46e8fa6d4ca2b14eb6d9ea2285a4c0.tar.gz lumina-23b870f04c46e8fa6d4ca2b14eb6d9ea2285a4c0.tar.bz2 lumina-23b870f04c46e8fa6d4ca2b14eb6d9ea2285a4c0.zip |
Add a window animation framework, with 7 visibility animations for starters.
-rw-r--r-- | src-qt5/core/libLumina/NativeEmbedWidget.cpp | 9 | ||||
-rw-r--r-- | src-qt5/core/libLumina/NativeWindow.cpp | 4 | ||||
-rw-r--r-- | src-qt5/core/libLumina/RootSubWindow-animations.cpp | 94 | ||||
-rw-r--r-- | src-qt5/core/libLumina/RootSubWindow.cpp | 45 | ||||
-rw-r--r-- | src-qt5/core/libLumina/RootSubWindow.h | 7 | ||||
-rw-r--r-- | src-qt5/core/libLumina/RootWindow.pri | 4 |
6 files changed, 127 insertions, 36 deletions
diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.cpp b/src-qt5/core/libLumina/NativeEmbedWidget.cpp index 34501f2a..e3c19e9f 100644 --- a/src-qt5/core/libLumina/NativeEmbedWidget.cpp +++ b/src-qt5/core/libLumina/NativeEmbedWidget.cpp @@ -163,11 +163,11 @@ void NativeEmbedWidget::resyncWindow(){ } void NativeEmbedWidget::repaintWindow(){ - qDebug() << "Update Window Image"; + //qDebug() << "Update Window Image"; QImage tmp = windowImage( QRect(QPoint(0,0), this->size()) ); if(!tmp.isNull()){ winImage = tmp; - }else{ qDebug() << "Got Null Image!!"; } + }//else{ qDebug() << "Got Null Image!!"; } this->update(); } // ============== @@ -192,10 +192,11 @@ void NativeEmbedWidget::hideEvent(QHideEvent *ev){ void NativeEmbedWidget::paintEvent(QPaintEvent *ev){ if(this->size()!=winSize){ return; } //do not paint here - waiting to re-sync the sizes - if(WIN==0){ QWidget::paintEvent(ev); return; } + else if(WIN==0){ QWidget::paintEvent(ev); return; } + else if(this->size() != winImage.size()){ return; } //Need to paint the image from the window onto the widget as an overlay QRect geom = ev->rect(); //atomic updates - geom.adjust(-1,-1,1,1); //add an additional pixel in each direction to be painted + geom.adjust(-10,-10,10,10); //add an additional few pixels in each direction to be painted geom = geom.intersected(QRect(0,0,this->width(), this->height())); //ensure intersection with actual window if(!winImage.isNull()){ if( !QRect(QPoint(0,0),winImage.size()).contains(geom) ){ QTimer::singleShot(0,this, SLOT(repaintWindow()) );return; } diff --git a/src-qt5/core/libLumina/NativeWindow.cpp b/src-qt5/core/libLumina/NativeWindow.cpp index 94d39cb7..48d0380b 100644 --- a/src-qt5/core/libLumina/NativeWindow.cpp +++ b/src-qt5/core/libLumina/NativeWindow.cpp @@ -89,11 +89,11 @@ QRect NativeWindow::geometry(){ QRect geom( hash.value(NativeWindow::GlobalPos).toPoint(), hash.value(NativeWindow::Size).toSize() ); //Now adjust the window geom by the frame margins QList<int> frame = hash.value(NativeWindow::FrameExtents).value< QList<int> >(); //Left,Right,Top,Bottom - qDebug() << "Calculate Geometry:" << geom << frame; + //qDebug() << "Calculate Geometry:" << geom << frame; if(frame.length()==4){ geom = geom.adjusted( -frame[0], -frame[2], frame[1], frame[3] ); } - qDebug() << " - Total:" << geom; + //qDebug() << " - Total:" << geom; return geom; } // ==== PUBLIC SLOTS === diff --git a/src-qt5/core/libLumina/RootSubWindow-animations.cpp b/src-qt5/core/libLumina/RootSubWindow-animations.cpp new file mode 100644 index 00000000..e3deed3a --- /dev/null +++ b/src-qt5/core/libLumina/RootSubWindow-animations.cpp @@ -0,0 +1,94 @@ +//=========================================== +// Lumina Desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "RootSubWindow.h" +#include <QDebug> + +QStringList RootSubWindow::validAnimations(NativeWindow::Property prop){ + QStringList valid; + if(prop == NativeWindow::Visible){ + valid << "zoom" << "wipe-center-vertical" << "wipe-center-horizontal" << "shade-top" << "shade-right" << "shade-left" << "shade-bottom"; + } + return valid; +} + +void RootSubWindow::loadAnimation(QString name, NativeWindow::Property prop, QVariant nval){ + animResetProp.clear(); + //Special case - random animation each time + if(name=="random"){ + QStringList valid = validAnimations(prop); + name = valid.at(qrand()%valid.length()); + } + //Now setup the animation + if(prop == NativeWindow::Visible){ + //NOTE: Assigns values for "invisible->visible" animation: will reverse it afterwards as needed + anim->setPropertyName("geometry"); + QRect geom = this->geometry(); + if(name == "zoom"){ + //Zoom to/from the center point + anim->setStartValue( QRect(geom.center(), QSize(0,0)) ); + anim->setEndValue(geom); + }else if(name == "wipe-center-vertical"){ + anim->setStartValue( QRect( geom.center().x(), geom.y(), 0, geom.height()) ); + anim->setEndValue( geom ); + }else if(name == "wipe-center-horizontal"){ + anim->setStartValue( QRect( geom.x(), geom.center().y(), geom.width(), 0) ); + anim->setEndValue( geom ); + }else if(name == "shade-top"){ + anim->setStartValue( QRect( geom.x(), geom.y(), geom.width(), 0) ); + anim->setEndValue( geom ); + }else if(name == "shade-bottom"){ + anim->setStartValue( QRect( geom.x(), geom.y()+geom.height(), geom.width(), 0) ); + anim->setEndValue( geom ); + }else if(name == "shade-left"){ + anim->setStartValue( QRect( geom.x(), geom.y(), 0, geom.height()) ); + anim->setEndValue( geom ); + }else if(name == "shade-right"){ + anim->setStartValue( QRect( geom.x()+geom.width(), geom.y(), 0, geom.height()) ); + anim->setEndValue( geom ); + }else{ + //Invalid/None animation + if(nval.toBool()){ this->show(); } + else{ this->hide(); } + return; + } + if(nval.toBool()){ + this->setGeometry( anim->startValue().toRect() ); //ensure the window is the initial geom before it becomes visible + }else{ + QVariant tmp = anim->startValue(); + anim->setStartValue(anim->endValue()); + anim->setEndValue(tmp); + animResetProp = anim->startValue(); + QTimer::singleShot(anim->duration(), this, SLOT(hide()) ); + } + anim->start(); + this->show(); + } //end of Visibility animation +} + +void RootSubWindow::animFinished(){ + if(closing){ this->close(); return;} + else if(anim->propertyName()=="geometry"){ + if(!animResetProp.isNull()){ + /*qDebug() << "Animation Finished, Reset Geometry:" << animResetProp.toRect(); + qDebug() << " - Starting Value:" << anim->startValue().toRect(); + qDebug() << " - Ending Value:" << anim->endValue().toRect();*/ + this->setGeometry( animResetProp.toRect() ); + //Also ensure that the proper geometry is saved to the window structure + QRect curg = this->geometry(); + QRect wing = WIN->geometry(); + qDebug() << " - After Animation Reset:" << curg << wing; + if(curg!=wing){ + QRect clientg = clientGlobalGeom(); + qDebug() << "Sub Window geometry:" << clientg; + WIN->setProperties(QList< NativeWindow::Property>() << NativeWindow::Size << NativeWindow::GlobalPos, + QList<QVariant>() << clientg.size() << clientg.topLeft() ); + WinWidget->resyncWindow(); //also let the window know about the current geometry + } + } + } + animResetProp = QVariant(); //clear the variable +} diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 9ef6464e..55b6bd2e 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -246,6 +246,14 @@ void RootSubWindow::LoadProperties( QList< NativeWindow::Property> list){ propertiesChanged(list, vals); } +QRect RootSubWindow::clientGlobalGeom(){ + QRect tot = this->geometry(); + QList<int> frame = WIN->property(NativeWindow::FrameExtents).value< QList<int> >(); + //Now adjust this to take out the frame + tot.adjust(frame[0], frame[2], -frame[1], -frame[3]); + return tot; +} + // === PUBLIC SLOTS === void RootSubWindow::clientClosed(){ //qDebug() << "Client Closed"; @@ -312,7 +320,8 @@ void RootSubWindow::propertiesChanged(QList<NativeWindow::Property> props, QList switch(props[i]){ case NativeWindow::Visible: //qDebug() << "Got Visibility Change:" << vals[i] << this->geometry() << WIN->geometry(); - if(vals[i].toBool()){ + loadAnimation( "random", NativeWindow::Visible, vals[i]); + /*if(vals[i].toBool()){ if(lastGeom.isNull()){ animResetProp = this->geometry(); } else{ animResetProp = lastGeom; } anim->setPropertyName("geometry"); @@ -329,7 +338,7 @@ void RootSubWindow::propertiesChanged(QList<NativeWindow::Property> props, QList anim->setEndValue( QRect(this->geometry().center(), QSize(0,0) ) ); anim->start(); QTimer::singleShot(anim->duration(), this, SLOT(hide()) ); - } + }*/ break; case NativeWindow::Title: titleLabel->setText(vals[i].toString()); @@ -340,11 +349,6 @@ void RootSubWindow::propertiesChanged(QList<NativeWindow::Property> props, QList else{ otherB->setIcon(vals[i].value<QIcon>()); } break; case NativeWindow::GlobalPos: - //qDebug() << "Got Global Pos:" << this->pos() << WinWidget->mapToGlobal(QPoint(0,0)) << WIN->geometry().topLeft() << vals[i].toPoint(); - if(activeState == RootSubWindow::Normal){ - this->move( WIN->geometry().topLeft() ); - } - break; case NativeWindow::Size: //qDebug() << " - SIZE CHANGE"; if(WIN->property(NativeWindow::FrameExtents).isNull() && (i<props.indexOf(NativeWindow::FrameExtents)) ){ @@ -353,11 +357,8 @@ void RootSubWindow::propertiesChanged(QList<NativeWindow::Property> props, QList vals << vals.takeAt(i); i--; }else if(anim->state() != QPropertyAnimation::Running ){ - if(vals[i].toSize() != WinWidget->size() && activeState==Normal){ - //qDebug() << "Got Widget Size Change:" << vals[i].toSize() << WinWidget->size(); - WinWidget->resize(vals[i].toSize()); - this->resize( WIN->geometry().size() ); - //qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); + if(vals[i].toSize() != WinWidget->size() && activeState==Normal && vals[i]==WIN->property(NativeWindow::Size)){ + this->setGeometry(WIN->geometry()); } } break; @@ -388,20 +389,6 @@ void RootSubWindow::propertiesChanged(QList<NativeWindow::Property> props, QList } } -void RootSubWindow::animFinished(){ - if(closing){ this->close(); return;} - else if(anim->propertyName()=="geometry"){ - if(!animResetProp.isNull()){ - /*qDebug() << "Animation Finished, Reset Geometry:" << animResetProp; - qDebug() << " - Starting Value:" << anim->startValue(); - qDebug() << " - Ending Value:" << anim->endValue(); - qDebug() << " - Current Value:" << this->geometry();*/ - this->setGeometry( animResetProp.toRect() ); - } - } - animResetProp = QVariant(); //clear the variable -} - // === PROTECTED === void RootSubWindow::mousePressEvent(QMouseEvent *ev){ activate(); @@ -498,7 +485,9 @@ void RootSubWindow::mouseMoveEvent(QMouseEvent *ev){ default: break; } - this->setGeometry(geom); + //if( (geom.width()%2==0 && geom.height()%2==0) || activeState==Move){ + this->setGeometry(geom); + //} } QFrame::mouseMoveEvent(ev); } @@ -529,8 +518,6 @@ void RootSubWindow::moveEvent(QMoveEvent *ev){ QFrame::moveEvent(ev); if(!closing && anim->state()!=QAbstractAnimation::Running){ moveTimer->start(); - //WinWidget->resyncWindow(); - //WIN->requestProperty(NativeWindow::GlobalPos, ev->pos() ); } } diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/RootSubWindow.h index de6aba89..079a6201 100644 --- a/src-qt5/core/libLumina/RootSubWindow.h +++ b/src-qt5/core/libLumina/RootSubWindow.h @@ -39,6 +39,7 @@ private: //Functions for getting/setting state ModState getStateAtPoint(QPoint pt, bool setoffset = false); //generally used for mouse location detection void setMouseCursor(ModState, bool override = false); //Update the mouse cursor based on state + //Native window embed objects NativeWindow *WIN; NativeEmbedWidget *WinWidget; @@ -60,10 +61,14 @@ private: void LoadProperties( QList< NativeWindow::Property> list); + static QStringList validAnimations(NativeWindow::Property); + public slots: void clientClosed(); void LoadAllProperties(); + QRect clientGlobalGeom(); + //Button Actions - public so they can be tied to key shortcuts and stuff as well void toggleMinimize(); void toggleMaximize(); @@ -77,6 +82,8 @@ public slots: private slots: void propertiesChanged(QList<NativeWindow::Property>, QList<QVariant>); + + void loadAnimation(QString name, NativeWindow::Property, QVariant nval); //new val void animFinished(); protected: diff --git a/src-qt5/core/libLumina/RootWindow.pri b/src-qt5/core/libLumina/RootWindow.pri index e4d5f00b..b83240e5 100644 --- a/src-qt5/core/libLumina/RootWindow.pri +++ b/src-qt5/core/libLumina/RootWindow.pri @@ -1,7 +1,8 @@ # Files SOURCES *= $${PWD}/RootWindow.cpp \ - $${PWD}/RootSubWindow.cpp + $${PWD}/RootSubWindow.cpp \ + $${PWD}/RootSubWindow-animations.cpp HEADERS *= $${PWD}/RootWindow.h \ $${PWD}/RootSubWindow.h @@ -12,3 +13,4 @@ INCLUDEPATH *= ${PWD} include(LUtils.pri) include(NativeWindow.pri) include(LIconCache.pri) +include(DesktopSettings.pri) |