/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: openBossa - INdT (renato.chencarek@openbossa.org) ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** the openBossa stream from INdT (renato.chencarek@openbossa.org). ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include #include #include "dataresource.h" #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_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")) { setFlag(QGraphicsItem::ItemHasNoContents); setupInterface(); } void DraggablePreview::setupInterface() { // add background item QPixmap backgroundPixmap = Resource::pixmap("screen_unlock.png"); m_background = new QGraphicsPixmapItem(backgroundPixmap, this); m_background->setPos(0, 0); m_background->setFlag(QGraphicsItem::ItemStacksBehindParent); m_background->setShapeMode(QGraphicsPixmapItem::BoundingRectShape); // add embedded widget m_item->setParentItem(this); m_item->setFlag(QGraphicsItem::ItemStacksBehindParent); m_item->setPos(m_leftMargin + m_border, m_topMargin + m_border); m_item->resize(m_screenSize); // resize to the background size resize(backgroundPixmap.size()); const int sw = m_screenSize.width(); const int sh = m_screenSize.height(); qreal minimumScale = Resource::doubleValue("draggable-preview/minimum-scale"); qreal draggableScale = Resource::doubleValue("draggable-preview/first-zoom-scale"); m_draggablePos = SCALED_POS(sw, sh, draggableScale); QPointF minimumPos(SCALED_POS(sw, sh, minimumScale)); QPointF maximumPos(-m_leftMargin - m_border, -m_topMargin - m_border); m_maximumOffset = minimumPos.y(); QStateMachine *machine = new QStateMachine(this); m_minimizedState = new QState(); m_minimizedState->assignProperty(this, "pos", minimumPos); m_minimizedState->assignProperty(this, "scale", minimumScale); m_draggableState = new QState(); m_draggableState->assignProperty(this, "pos", m_draggablePos); m_draggableState->assignProperty(this, "scale", draggableScale); m_maximizedState = new QState(); m_maximizedState->assignProperty(this, "pos", maximumPos); m_maximizedState->assignProperty(this, "scale", 1.0); 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"); QSignalTransition *transition; // 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::createAnimation(int time, const char *slot) { QParallelAnimationGroup *result = new QParallelAnimationGroup(); QPropertyAnimation *posAnimation = new QPropertyAnimation(this, "pos"); posAnimation->setEasingCurve(QEasingCurve::InSine); posAnimation->setDuration(time); QPropertyAnimation *scaleAnimation = new QPropertyAnimation(this, "scale"); scaleAnimation->setEasingCurve(QEasingCurve::InSine); scaleAnimation->setDuration(time); result->addAnimation(posAnimation); result->addAnimation(scaleAnimation); if (slot) connect(result, SIGNAL(finished()), slot); return result; } void DraggablePreview::onMaximizeFinished() { // hide background m_background->hide(); // move menu to front to not block events m_item->setFlag(QGraphicsItem::ItemStacksBehindParent, false); emit maximizeFinished(); // detach from parent to avoid inherit transformations m_item->setParentItem(0); m_item->setPos(0, 0); } void DraggablePreview::mousePressEvent(QGraphicsSceneMouseEvent *e) { m_lastPos = e->scenePos(); m_draggableState->assignProperty(this, "pos", m_draggablePos); emit draggableStarted(); } void DraggablePreview::mouseMoveEvent(QGraphicsSceneMouseEvent *e) { const int offset = qRound(pos().y() + e->scenePos().y() - m_lastPos.y()); m_lastPos = e->scenePos(); const int fy = 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 (pos().y() < m_minimumOffset + m_maximizeRange) emit maximizeStarted(); else emit minimizeStarted(); }