diff options
author | Adriano Rezende <adriano.rezende@openbossa.org> | 2009-10-27 13:04:34 -0300 |
---|---|---|
committer | Adriano Rezende <adriano.rezende@openbossa.org> | 2009-10-29 18:25:06 -0300 |
commit | 3990e5973b67f9b688201d2823397523a51488df (patch) | |
tree | 4e765c5ab60c78654d7c14e74542c9979d7d528f /hyperui | |
parent | 81fd73d381feb34b23d9f70bcbe3d1bb3bbce875 (diff) |
HiperUi: Added draggable animation to unlock screen
The screen preview will scale up when in drag mode.
Diffstat (limited to 'hyperui')
-rw-r--r-- | hyperui/draggablepreview.cpp | 197 | ||||
-rw-r--r-- | hyperui/draggablepreview.h | 48 | ||||
-rw-r--r-- | hyperui/resource/640x360/hyperui.ini | 5 | ||||
-rw-r--r-- | hyperui/resource/864x480/hyperui.ini | 5 |
4 files changed, 139 insertions, 116 deletions
diff --git a/hyperui/draggablepreview.cpp b/hyperui/draggablepreview.cpp index c8d22fa..93f17dc 100644 --- a/hyperui/draggablepreview.cpp +++ b/hyperui/draggablepreview.cpp @@ -29,6 +29,9 @@ ** ****************************************************************************/ +#include <QState> +#include <QStateMachine> +#include <QSignalTransition> #include <QPropertyAnimation> #include <QParallelAnimationGroup> #include <QGraphicsSceneMouseEvent> @@ -37,33 +40,29 @@ #include "draggablepreview.h" +#define SCALED_POS(sw, sh, scale) \ + QPointF(qRound(sw * 0.5 - (sw * 0.5 + m_leftMargin) * scale), \ + qRound(sh - (sh + m_topMargin) * 0.5 * scale)) + + DraggablePreview::DraggablePreview(QGraphicsWidget *item, const QSize &screenSize, QGraphicsItem *parent) - : QGraphicsWidget(parent), m_screenSize(screenSize), - m_isMaximizeAnimation(false), m_item(item) + : QGraphicsWidget(parent), + m_item(item), + m_screenSize(screenSize), + m_border(Resource::intValue("draggable-preview/border")), + m_topMargin(Resource::intValue("draggable-preview/margin-top")), + m_leftMargin(Resource::intValue("draggable-preview/margin-left")), + m_maximizeRange(Resource::doubleValue("draggable-preview/maximize-range")), + m_minimumOffset(Resource::intValue("draggable-preview/minimum-offset")) { - readSettings(); - setupInterface(); - - m_animation = new QParallelAnimationGroup(this); - connect(m_animation, SIGNAL(finished()), SLOT(animationFinished())); -} + setFlag(QGraphicsItem::ItemHasNoContents); -void DraggablePreview::readSettings() -{ - m_border = Resource::intValue("draggable-preview/border"); - m_topMargin = Resource::intValue("draggable-preview/margin-top"); - m_leftMargin = Resource::intValue("draggable-preview/margin-left"); - m_restoreTime = Resource::intValue("draggable-preview/restore-time"); - m_maximizeTime = Resource::intValue("draggable-preview/maximize-time"); - m_minimumScale = Resource::doubleValue("draggable-preview/minimum-scale"); - m_maximizeThreshold = Resource::doubleValue("draggable-preview/maximize-threshold"); + setupInterface(); } void DraggablePreview::setupInterface() { - setFlag(QGraphicsItem::ItemHasNoContents); - // add background item QPixmap backgroundPixmap = Resource::pixmap("screen_unlock.png"); m_background = new QGraphicsPixmapItem(backgroundPixmap, this); @@ -80,110 +79,130 @@ void DraggablePreview::setupInterface() // resize to the background size resize(backgroundPixmap.size()); - // scale and position const int sw = m_screenSize.width(); const int sh = m_screenSize.height(); - const int scaledHeight = (sh + m_topMargin) * m_minimumScale * 0.5; - scale(m_minimumScale, m_minimumScale); - setPos(qRound(sw / 2.0 - (sw / 2.0 + m_leftMargin) * m_minimumScale), - qRound(sh - scaledHeight)); + qreal minimumScale = Resource::doubleValue("draggable-preview/minimum-scale"); + qreal draggableScale = Resource::doubleValue("draggable-preview/first-zoom-scale"); - m_minimumOffset = sh / 2 - scaledHeight; - m_maximumOffset = pos().y(); -} + m_draggablePos = SCALED_POS(sw, sh, draggableScale); + QPointF minimumPos(SCALED_POS(sw, sh, minimumScale)); + QPointF maximumPos(-m_leftMargin - m_border, -m_topMargin - m_border); -bool DraggablePreview::isAnimating() const -{ - return (m_animation->state() == QAbstractAnimation::Running); -} + m_maximumOffset = minimumPos.y(); -void DraggablePreview::animateRestore() -{ - m_animation->clearAnimations(); + QStateMachine *machine = new QStateMachine(this); - m_isMaximizeAnimation = false; + m_minimizedState = new QState(); + m_minimizedState->assignProperty(this, "pos", minimumPos); + m_minimizedState->assignProperty(this, "scale", minimumScale); - QPointF finalPos(pos().x(), m_maximumOffset); - m_animation->addAnimation(createMoveAnimation(finalPos, m_restoreTime)); - m_animation->start(); -} + m_draggableState = new QState(); + m_draggableState->assignProperty(this, "pos", m_draggablePos); + m_draggableState->assignProperty(this, "scale", draggableScale); -void DraggablePreview::animateMaximize() -{ - m_animation->clearAnimations(); + m_maximizedState = new QState(); + m_maximizedState->assignProperty(this, "pos", maximumPos); + m_maximizedState->assignProperty(this, "scale", 1.0); - m_isMaximizeAnimation = true; + int restoreTime = Resource::intValue("draggable-preview/restore-time"); + int maximizeTime = Resource::intValue("draggable-preview/maximize-time"); + int firstZoomTime = Resource::intValue("draggable-preview/first-zoom-time"); - qreal finalScale = 1.0 / m_minimumScale; - QPointF finalPos(-m_leftMargin - m_border, -m_topMargin - m_border); - m_animation->addAnimation(createMoveAnimation(finalPos, m_maximizeTime)); - m_animation->addAnimation(createScaleAnimation(finalScale, m_maximizeTime)); - m_animation->start(); -} + QSignalTransition *transition; -QAbstractAnimation *DraggablePreview::createScaleAnimation(qreal scale, int time) -{ - QPropertyAnimation *animation = new QPropertyAnimation(this, "scale"); - animation->setDuration(time); - animation->setEasingCurve(QEasingCurve::OutQuad); - animation->setStartValue(1.0); - animation->setEndValue(scale); - return animation; + // create minimized > draggable state transition + transition = m_minimizedState->addTransition(this, SIGNAL(draggableStarted()), + m_draggableState); + transition->addAnimation(createAnimation(firstZoomTime)); + + // create draggable > minimized state transition + transition = m_draggableState->addTransition(this, SIGNAL(minimizeStarted()), + m_minimizedState); + transition->addAnimation(createAnimation(restoreTime)); + + // create draggable > maximized state transition + transition = m_draggableState->addTransition(this, SIGNAL(maximizeStarted()), + m_maximizedState); + transition->addAnimation(createAnimation(maximizeTime, + SLOT(onMaximizeFinished()))); + + // this is used just to update the final value when still animating + transition = m_draggableState->addTransition(this, SIGNAL(draggableUpdate()), + m_draggableState); + transition->addAnimation(createAnimation(0)); + + // add states + machine->addState(m_minimizedState); + machine->addState(m_draggableState); + machine->addState(m_maximizedState); + + setPos(minimumPos); + setScale(minimumScale); + + machine->setInitialState(m_minimizedState); + machine->start(); } -QAbstractAnimation *DraggablePreview::createMoveAnimation(const QPointF &to, int time) +QAbstractAnimation *DraggablePreview::createAnimation(int time, const char *slot) { - QPropertyAnimation *animation = new QPropertyAnimation(this, "pos"); - animation->setDuration(time); - animation->setEasingCurve(QEasingCurve::OutQuad); - animation->setStartValue(pos()); - animation->setEndValue(to); - return animation; + QParallelAnimationGroup *result = new QParallelAnimationGroup(); + + QPropertyAnimation *posAnimation = new QPropertyAnimation(this, "pos"); + posAnimation->setDuration(time); + + QPropertyAnimation *scaleAnimation = new QPropertyAnimation(this, "scale"); + scaleAnimation->setDuration(time); + + result->addAnimation(posAnimation); + result->addAnimation(scaleAnimation); + + if (slot) + connect(result, SIGNAL(finished()), slot); + + return result; } -void DraggablePreview::animationFinished() +void DraggablePreview::onMaximizeFinished() { - if (m_isMaximizeAnimation) { - // hide background - m_background->hide(); - // move menu to front to not block events - m_item->setFlag(QGraphicsItem::ItemStacksBehindParent, false); + // hide background + m_background->hide(); - emit maximizeFinished(); + // move menu to front to not block events + m_item->setFlag(QGraphicsItem::ItemStacksBehindParent, false); - // detach from parent to avoid inherit transformations - m_item->setParentItem(0); - m_item->setPos(0, 0); - } + emit maximizeFinished(); + + // detach from parent to avoid inherit transformations + m_item->setParentItem(0); + m_item->setPos(0, 0); } void DraggablePreview::mousePressEvent(QGraphicsSceneMouseEvent *e) { - if (isAnimating()) - return; - m_lastPos = e->scenePos(); + m_draggableState->assignProperty(this, "pos", m_draggablePos); + emit draggableStarted(); } void DraggablePreview::mouseMoveEvent(QGraphicsSceneMouseEvent *e) { - if (isAnimating()) - return; + const int offset = qRound(pos().y() + e->scenePos().y() - m_lastPos.y()); + m_lastPos = e->scenePos(); - const int offset = qRound(pos().y() + e->scenePos().y() - m_lastPos.y()); + const int fy = qBound(m_minimumOffset, offset, m_maximumOffset); - m_lastPos = e->scenePos(); - setPos(pos().x(), qBound(m_minimumOffset, offset, m_maximumOffset)); + if (fy < m_draggablePos.y()) { + m_draggableState->assignProperty(this, "pos", + QPointF(m_draggablePos.x(), fy)); + emit draggableUpdate(); + } } void DraggablePreview::mouseReleaseEvent(QGraphicsSceneMouseEvent *) { - if (isAnimating()) - return; - - if (pos().y() < m_minimumOffset + m_maximizeThreshold) - animateMaximize(); + if (pos().y() < m_minimumOffset + m_maximizeRange) + emit maximizeStarted(); else - animateRestore(); + emit minimizeStarted(); } diff --git a/hyperui/draggablepreview.h b/hyperui/draggablepreview.h index 69e46e9..656f556 100644 --- a/hyperui/draggablepreview.h +++ b/hyperui/draggablepreview.h @@ -35,8 +35,8 @@ #include <QGraphicsWidget> QT_BEGIN_NAMESPACE +class QState; class QAbstractAnimation; -class QParallelAnimationGroup; QT_END_NAMESPACE @@ -48,45 +48,43 @@ public: DraggablePreview(QGraphicsWidget *item, const QSize &screenSize, QGraphicsItem *parent = 0); - bool isAnimating() const; - signals: + void draggableUpdate(); + void draggableStarted(); + void minimizeStarted(); + void maximizeStarted(); void maximizeFinished(); -private slots: - void animationFinished(); - -private: - void readSettings(); - void setupInterface(); - - void animateRestore(); - void animateMaximize(); - +protected: void mousePressEvent(QGraphicsSceneMouseEvent *e); void mouseMoveEvent(QGraphicsSceneMouseEvent *e); void mouseReleaseEvent(QGraphicsSceneMouseEvent *e); - QAbstractAnimation *createScaleAnimation(qreal scale, int time); - QAbstractAnimation *createMoveAnimation(const QPointF &to, int time); +private slots: + void onMaximizeFinished(); - QPointF m_lastPos; +private: + void setupInterface(); + QAbstractAnimation *createAnimation(int time, const char *slot = 0); + + QGraphicsWidget *m_item; QSize m_screenSize; - int m_minimumOffset; - int m_maximumOffset; int m_border; int m_topMargin; int m_leftMargin; - int m_restoreTime; - int m_maximizeTime; - qreal m_minimumScale; - int m_maximizeThreshold; - bool m_isMaximizeAnimation; + int m_maximizeRange; + + QPointF m_lastPos; + QPointF m_draggablePos; + int m_minimumOffset; + int m_maximumOffset; - QGraphicsWidget *m_item; QGraphicsPixmapItem *m_background; - QParallelAnimationGroup *m_animation; + + QState *m_minimizedState; + QState *m_draggableState; + QState *m_maximizedState; }; diff --git a/hyperui/resource/640x360/hyperui.ini b/hyperui/resource/640x360/hyperui.ini index b83e181..9d11953 100644 --- a/hyperui/resource/640x360/hyperui.ini +++ b/hyperui/resource/640x360/hyperui.ini @@ -41,8 +41,11 @@ margin-top=5 margin-left=58 restore-time=300 maximize-time=300 +first-zoom-time=200 minimum-scale=0.44 -maximize-threshold=50 +first-zoom-scale=0.5 +minimum-offset=150 +maximize-range=100 [dialer-widget] margin=4 diff --git a/hyperui/resource/864x480/hyperui.ini b/hyperui/resource/864x480/hyperui.ini index a3c96cf..9994d22 100644 --- a/hyperui/resource/864x480/hyperui.ini +++ b/hyperui/resource/864x480/hyperui.ini @@ -41,8 +41,11 @@ margin-top=7 margin-left=77 restore-time=300 maximize-time=300 +first-zoom-time=200 minimum-scale=0.44 -maximize-threshold=50 +first-zoom-scale=0.5 +minimum-offset=200 +maximize-range=160 [dialer-widget] margin=5 |