--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/screensaver/snsrplugins/snsrbigclockscreensaverplugin/src/snsrbigclockcontainer.cpp Wed Oct 06 16:06:24 2010 +0300
@@ -0,0 +1,422 @@
+/*
+* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Base class container.
+*
+*/
+
+#include "snsrbigclockcontainer.h"
+
+#include <QPainter>
+#include <QDebug>
+#include <QTime>
+#include <QGraphicsLinearLayout>
+
+#include <HbEvent>
+#include <HbColorScheme>
+#include <HbMainWindow>
+#include <HbEffect>
+
+#ifdef Q_OS_SYMBIAN
+#include <xqsettingsmanager.h>
+#include <screensaverdomaincrkeys.h>
+#endif //Q_OS_SYMBIAN
+
+#include "snsrbigclockcontainer.h"
+#include "snsrindicatorwidget.h"
+#include "snsrindicatormodel.h"
+#include "snsrcolors.h"
+
+/*!
+ \class SnsrBigClockContainer
+ \ingroup group_snsrbigclockscreensaverplugin
+ \brief Base class. Container used for drawing background and for preparing layout.
+ */
+
+
+
+const int gStep(5);
+
+
+/*!
+ Constructs a new SnsrBigClockContainer.
+ */
+SnsrBigClockContainer::SnsrBigClockContainer() :
+ mBackgroundContainerLayout(0),
+ mMainView(0),
+ mMainContainer(0),
+ mIndicatorModel(0),
+ mIndicatorWidget(0),
+ mCurrentOrientation(-1)
+{
+ setBackgroundColor();
+ mBackgroundContainerLayout = new QGraphicsLinearLayout(Qt::Vertical, this);
+ setLayout(mBackgroundContainerLayout);
+ qsrand(QTime::currentTime().msec());
+ connect( mainWindow(), SIGNAL(aboutToChangeOrientation()), SLOT(fadeOutView()) );
+}
+
+/*!
+ Destructs the class.
+ */
+SnsrBigClockContainer::~SnsrBigClockContainer()
+{
+ // e.g. mIndicatorWidget gets deleted during this call
+ resetWidgets();
+
+ //mBackgroundContainerLayout - deleted by the parent
+ mIndicatorModel = 0; // not owned
+}
+
+/*!
+ \fn virtual void update() = 0;
+
+ Slot for members update in container e.g. when time or date changed.
+ */
+
+/*!
+ Changes screensaver layout based on orientation changes.
+ \param orientation Current orientation.
+ */
+void SnsrBigClockContainer::changeLayout(Qt::Orientation orientation)
+{
+ SCREENSAVER_TEST_FUNC_ENTRY("SnsrBigClockContainer::changeLayout")
+
+ if (mCurrentOrientation != orientation) {
+ mCurrentOrientation = orientation;
+
+ // delete any old widgets
+ if ( mBackgroundContainerLayout->count() ) {
+ mBackgroundContainerLayout->removeAt(0);
+ }
+ resetWidgets();
+
+ // reload widgets from docml
+ loadWidgets();
+
+ // register orientation effects for the newly loaded main view
+ HbEffect::add( mMainView, "notificationdialog_appear", "appear" );
+ HbEffect::add( mMainView, "notificationdialog_disappear", "disappear" );
+ }
+ mBackgroundContainerLayout->setGeometry( mainWindow()->layoutRect() );
+ update();
+
+ // Run the fade-in effect, except if this container is a low-power one.
+ // In low-power mode, animations don't look good because of reduced
+ // color-depth and refresh rate.
+ if ( displayPowerMode() == Screensaver::ScreenModeFullPower ) {
+ HbEffect::start( mMainView, "appear" );
+ }
+
+ SCREENSAVER_TEST_FUNC_EXIT("SnsrBigClockContainer::changeLayout")
+}
+
+/*!
+ Set used indicator model that is owned by the screensaver class.
+ Model's life cycle must be the same as screensaver's so that indicators'
+ status data can be kept in memory and one can receive updates.
+ This method should be called when the current container is set.
+ */
+void SnsrBigClockContainer::setIndicatorModel(SnsrIndicatorModel &model)
+{
+ mIndicatorModel = &model;
+}
+
+/*!
+ @copydoc Screensaver::currentPowerMode()
+ */
+Screensaver::ScreenPowerMode SnsrBigClockContainer::displayPowerMode()
+{
+ // The default implementation returns full power mode. Inherited classes
+ // must override this if low power or display off mode are required.
+ return Screensaver::ScreenModeFullPower;
+}
+
+/*!
+ @copydoc Screensaver::getActiveScreenRows()
+ */
+void SnsrBigClockContainer::getActiveScreenRows(int *firstActiveRow, int *lastActiveRow)
+{
+ // This default implementation return the whole area of the
+ // container. Inherited low power mode containers can and should
+ // return smaller area which just barely encloses all the content.
+ if ( mMainContainer ) {
+ QRect mainRect = mMainContainer->rect().toRect();
+ if ( mCurrentOrientation == Qt::Vertical ) {
+ *firstActiveRow = mainRect.top();
+ *lastActiveRow = mainRect.bottom();
+ }
+ else {
+ *firstActiveRow = mainRect.left();
+ *lastActiveRow = mainRect.right();
+ }
+ }
+}
+
+/*!
+ Tell if this container wants to lock the screen orientation.
+ Default implementation in not locked but inherited classes may
+ override this.
+ */
+bool SnsrBigClockContainer::isOrientationLocked()
+{
+ return false;
+}
+
+/*!
+ \fn virtual int updateIntervalInMilliseconds() = 0;
+
+ Concrete inherited container classes must implement this to return
+ the desired update interval for that clock mode.
+ */
+
+/*!
+ \fn virtual int loadWidgets() = 0;
+
+ Concrete inherited container classes must implement this to instantiate
+ all the widgets shown in the container. The base class calls this
+ method when screen layuot is changed. The old widgets are already
+ deleted by the base class before this is called. Also changing the visible
+ container is treated as a layout change, and results in call to this method.
+ Thus, inherited containers don't have to load their widgets yet in their
+ constructors.
+ */
+
+/*!
+ \reimp
+ */
+void SnsrBigClockContainer::changeEvent(QEvent *event)
+{
+ if (event->type() == HbEvent::ThemeChanged) {
+ setBackgroundColor();
+ }
+ return QGraphicsWidget::changeEvent(event);
+}
+
+/*!
+ Returns random point for given range.
+ \param rect Area within which the generated point will be.
+ */
+QPointF SnsrBigClockContainer::randomPosition(const QRectF &rect)
+{
+ int width( rect.width() );
+ int height( rect.height() );
+ if ( width > 0 && height > 0 ) {
+ return rect.topLeft() + QPointF( qrand()%width, qrand()%height );
+ }
+ else {
+ return QPointF();
+ }
+
+}
+
+/*!
+ Returns new position between curRect position and destPos position.
+ \param curPos Current position.
+ \param destPos Destination position. When current position is near this
+ position or outside of the container, a new value is generated.
+ \param containerRect The container within which the destination position will always
+ be after a call.
+ */
+QPointF SnsrBigClockContainer::nextRandomPosition(const QPointF &curPos, QPointF &destPos, const QRectF &containerRect)
+{
+ const int delta(gStep+2);
+ const int minCntDimension(3*delta);
+
+ // The random movement logic can work only if the container has enough space to move the
+ // clock around. If the container is too small, just return the middle point of the container.
+ if ( containerRect.width() < minCntDimension && containerRect.height() < minCntDimension ) {
+ return containerRect.center();
+ }
+
+ int xDistance = abs( destPos.x() - curPos.x() );
+ int yDistance = abs( destPos.y() - curPos.y() );
+
+ // Generate new destination position when current widget position is close to
+ // destination random position or when current destination position is out of bounds.
+ // It is possible that the new random position is very close to the current position,
+ // in which case the random position is generated again.
+ // It is paramount that container is large enough when next loop is entered
+ // to prevent infinite looping.
+ while ( (xDistance < delta && yDistance < delta)
+ || !containerRect.contains(destPos) ) {
+ destPos = randomPosition( containerRect );
+ xDistance = abs( destPos.x() - curPos.x() );
+ yDistance = abs( destPos.y() - curPos.y() );
+ }
+
+ // If, for some reason, the current position is out-of-bounds, then there's no
+ // point to slowly move towards the destination. In that case, move immediately
+ // to destination point.
+ if ( !containerRect.contains(curPos) ) {
+ return destPos;
+ }
+ // Otherwise, this is normal case and we will calculate a point which is just
+ // a bit closer to the destination.
+
+ // Version 1:
+ // o-----o---------------------------o
+ // p1 p2 p3
+ //
+ // Version 2:
+ // o---------------------------o-----o
+ // p3 p2 p1
+ //
+ // p1 - current widget position
+ // p2 - next position to compute
+ // p3 - destination random position
+ QPointF p1(curPos);
+ QPointF p2(0,0);
+ QPointF p3(destPos);
+
+ // Computes point p2 - new position between p1 and p3
+
+ // Move the coordinate which is further away from the destination
+ // and calculate the other coordinate from that so that the
+ // result point p2 lies on the straigth line between p1 and p3.
+ if ( yDistance > xDistance ) {
+ if (p3.y() > p1.y()) {
+ p2.setY(p1.y()+gStep);
+ }
+ else {
+ p2.setY(p1.y()-gStep);
+ }
+ p2.setX((((p2.y()-p1.y())*(p3.x()-p1.x())) / (p3.y()-p1.y())) + p1.x()); // x2 = (((y2-y1)*(x3-x1)) / (y3-y1)) + x1
+ }
+ else {
+ if (p3.x() > p1.x()) {
+ p2.setX(p1.x()+gStep);
+ }
+ else {
+ p2.setX(p1.x()-gStep);
+ }
+ p2.setY((((p3.y()-p1.y())*(p2.x()-p1.x())) / (p3.x()-p1.x())) + p1.y()); // y2 = (((y3-y1)*(x2-x1)) / (x3-x1)) + y1
+ }
+
+ // Return new position between points p1 and p3.
+ return p2;
+}
+
+/*!
+ Do necessary initializations to show currently active indicators.
+ Should be called after the indicator widget is created.
+ */
+void SnsrBigClockContainer::connectIndicatorWidgetToModel()
+{
+ Q_ASSERT(mIndicatorModel && mIndicatorWidget);
+
+ connect(mIndicatorModel, SIGNAL(indicatorsUpdated(QList<SnsrIndicatorInfo>)),
+ mIndicatorWidget, SLOT(showIndicators(QList<SnsrIndicatorInfo>)));
+
+ connect(mIndicatorModel, SIGNAL(allIndicatorsDeactivated()),
+ mIndicatorWidget, SLOT(removeAllIndicators()));
+
+ mIndicatorModel->initializeIndicatorWidget();
+}
+
+/*!
+ Disconnect connections between indicator model and widget.
+ Should be called before deleting the indicator widget.
+ */
+void SnsrBigClockContainer::resetIndicatorConnections()
+{
+ if (mIndicatorWidget && mIndicatorModel) {
+ disconnect(mIndicatorModel, SIGNAL(indicatorsUpdated(QList<SnsrIndicatorInfo>)),
+ mIndicatorWidget, SLOT(showIndicators(QList<SnsrIndicatorInfo>)));
+
+ disconnect(mIndicatorModel, SIGNAL(allIndicatorsDeactivated()),
+ mIndicatorWidget, SLOT(removeAllIndicators()));
+ }
+}
+
+/*!
+ Destroy all the contained widgets
+ */
+void SnsrBigClockContainer::resetWidgets()
+{
+ // deregister effects
+ if ( mMainView ) {
+ HbEffect::remove( mMainView );
+ }
+
+ mDocumentLoader.reset();
+ qDeleteAll(mDocumentObjects);
+ mDocumentObjects.clear();
+}
+
+/*!
+ Set background color.
+ */
+void SnsrBigClockContainer::setBackgroundColor()
+{
+ mBackgroundColor = SnsrColors::BackgroundColor;
+}
+
+
+/*
+ * Returns true if swipe widget is used,
+ * false if swipe is not used.
+ */
+bool SnsrBigClockContainer::swipeToUnlockSupported()
+{
+#ifdef Q_OS_SYMBIAN
+ XQSettingsManager::Error error;
+ int swipeWidget = 0;
+ XQCentralRepositorySettingsKey settingsKey(
+ KCRUidScreensaverSettings.iUid, KScreensaverSwipeToOpen );
+ XQSettingsManager settingsManager;
+ swipeWidget = settingsManager.readItemValue(settingsKey, XQSettingsManager::TypeInt).toInt();
+ error = settingsManager.error();
+ if (error == XQSettingsManager::NoError && swipeWidget == 1) {
+ return true;
+ }
+ else {
+ return false;
+ }
+#else
+ return true;
+#endif //Q_OS_SYMBIAN
+}
+
+/*!
+ Paints the contents of an item in local coordinates.
+ */
+#ifdef COVERAGE_MEASUREMENT
+#pragma CTC SKIP
+#endif //COVERAGE_MEASUREMENT
+void SnsrBigClockContainer::paint(
+ QPainter *painter,
+ const QStyleOptionGraphicsItem *option,
+ QWidget *widget
+ )
+{
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
+
+ painter->fillRect(rect(), mBackgroundColor);
+}
+#ifdef COVERAGE_MEASUREMENT
+#pragma CTC ENDSKIP
+#endif //COVERAGE_MEASUREMENT
+
+/*!
+ Run the fade-out transition effect.
+ */
+void SnsrBigClockContainer::fadeOutView()
+{
+ // there's no point in animating the fade-out in the low-power mode
+ if ( mMainView && displayPowerMode() == Screensaver::ScreenModeFullPower ) {
+ HbEffect::start( mMainView, "disappear" );
+ }
+}
+