screensaver/screensaverplugins/snsrbigclockscreensaverplugin/src/snsrbigclockcontainer.cpp
changeset 62 341166945d65
child 69 87476091b3f5
equal deleted inserted replaced
57:2e2dc3d30ca8 62:341166945d65
       
     1 /*
       
     2 * Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Base class container.
       
    15 *
       
    16 */
       
    17 
       
    18 #include "snsrbigclockcontainer.h"
       
    19 
       
    20 #include <QPainter>
       
    21 #include <QDebug>
       
    22 #include <QTime>
       
    23 #include <QGraphicsLinearLayout>
       
    24 
       
    25 #include <hblabel.h>
       
    26 #include <hbevent.h>
       
    27 #include <hbcolorscheme.h>
       
    28 
       
    29 #include <qsysteminfo.h>
       
    30 
       
    31 #include "snsrbigclockcontainer.h"
       
    32 #include "snsrindicatorwidget.h"
       
    33 #include "snsrindicatormodel.h"
       
    34 
       
    35 /*!
       
    36     \class SnsrBigClockContainer
       
    37     \ingroup group_snsrbigclockscreensaverplugin
       
    38     \brief Base class. Container used for drawing background and for preparing layout.
       
    39  */
       
    40 
       
    41 const QString snsrBackgroundColorRole("snsrbackground");
       
    42 const int gStep(5);
       
    43 
       
    44 QTM_USE_NAMESPACE
       
    45 
       
    46 /*!
       
    47     Constructs a new SnsrBigClockContainer.
       
    48  */
       
    49 SnsrBigClockContainer::SnsrBigClockContainer() :
       
    50     mBackgroundContainerLayout(0),
       
    51     mMainView(0),
       
    52     mMainContainer(0),
       
    53     mIndicatorModel(0),
       
    54     mIndicatorWidget(0),
       
    55     mCurrentOrientation(-1)
       
    56 {
       
    57     setBackgroundColor();
       
    58     mBackgroundContainerLayout = new QGraphicsLinearLayout(Qt::Vertical);
       
    59     setLayout(mBackgroundContainerLayout);
       
    60     qsrand(QTime::currentTime().msec());
       
    61 }
       
    62 
       
    63 /*!
       
    64     Destructs the class.
       
    65  */
       
    66 SnsrBigClockContainer::~SnsrBigClockContainer()
       
    67 {
       
    68     resetIndicatorConnections();
       
    69     
       
    70     // e.g. mIndicatorWidget gets deleted during these calls
       
    71     mDocumentLoader.reset();
       
    72     qDeleteAll(mDocumentObjects);
       
    73     mDocumentObjects.clear();
       
    74 
       
    75     //mMainContainer,mBackgroundContainerLayout - deleted by the parent
       
    76     mIndicatorModel=0; // not owned
       
    77 }
       
    78 
       
    79 /*!
       
    80     \fn virtual void update() = 0;
       
    81 
       
    82     Slot for members update in container e.g. when time or date changed.
       
    83  */
       
    84 
       
    85 /*!
       
    86     \fn virtual void changeLayout(Qt::Orientation orientation) = 0;
       
    87 
       
    88     Slot for members update in container when orientation changed.
       
    89  */
       
    90 
       
    91 /*!
       
    92     \fn virtual int updateIntervalInMilliseconds() = 0;
       
    93 
       
    94     Concrete inherited container classes must implement this to return
       
    95     the desired update interval for that clock mode.
       
    96  */
       
    97 
       
    98 /*!
       
    99     Set used indicator model and do necessary initializations to show currently
       
   100     active indicators.
       
   101  */
       
   102 void SnsrBigClockContainer::initIndicators(SnsrIndicatorModel &model)
       
   103 {
       
   104     mIndicatorModel = &model;
       
   105     if (mIndicatorWidget) {
       
   106         connect(mIndicatorModel, SIGNAL(indicatorsUpdated(QList<SnsrIndicatorInfo>)),
       
   107                 mIndicatorWidget, SLOT(showIndicators(QList<SnsrIndicatorInfo>)));
       
   108                 
       
   109         connect(mIndicatorModel, SIGNAL(allIndicatorsDeactivated()),
       
   110                 mIndicatorWidget, SLOT(removeAllIndicators()));
       
   111         
       
   112         mIndicatorModel->initializeIndicatorWidget();
       
   113     }
       
   114 }
       
   115 
       
   116 /*!
       
   117     \reimp
       
   118  */
       
   119 void SnsrBigClockContainer::changeEvent(QEvent *event)
       
   120 {
       
   121     if (event->type() == HbEvent::ThemeChanged) {
       
   122         setBackgroundColor();
       
   123     }
       
   124     return QGraphicsWidget::changeEvent(event);
       
   125 }
       
   126 
       
   127 /*!
       
   128     Returns random point for given range.
       
   129     \param rect Area within which the generated point will be.
       
   130  */
       
   131 QPointF SnsrBigClockContainer::randomPosition(const QRectF &rect)
       
   132 {
       
   133     int width( rect.width() );
       
   134     int height( rect.height() );
       
   135     if ( width > 0 && height > 0 ) {
       
   136         return rect.topLeft() + QPointF( qrand()%width, qrand()%height );
       
   137     }
       
   138     else {
       
   139         return QPointF();
       
   140     }
       
   141 
       
   142 }
       
   143 
       
   144 /*!
       
   145     Returns new position between curRect position and destPos position.
       
   146     \param curPos Current position.
       
   147     \param destPos Destination position. When current position is near this
       
   148                    position or outside of the container, a new value is generated.
       
   149     \param containerRect The container within which the destination position will always
       
   150                          be after a call.
       
   151  */
       
   152 QPointF SnsrBigClockContainer::nextRandomPosition(const QPointF &curPos, QPointF &destPos, const QRectF &containerRect)
       
   153 {
       
   154     const int delta(gStep+2);
       
   155     const int minCntDimension(3*delta);
       
   156 
       
   157     // The random movement logic can work only if the container has enough space to move the
       
   158     // clock around. If the container is too small, just return the middle point of the container.
       
   159     if ( containerRect.width() < minCntDimension && containerRect.height() < minCntDimension ) {
       
   160         return containerRect.center();
       
   161     }
       
   162     
       
   163     int xDistance = abs( destPos.x() - curPos.x() );
       
   164     int yDistance = abs( destPos.y() - curPos.y() );
       
   165     
       
   166     // Generate new destination position when current widget position is close to 
       
   167     // destination random position or when current destination position is out of bounds.
       
   168     // It is possible that the new random position is very close to the current position,
       
   169     // in which case the random position is generated again.
       
   170     // It is paramount that container is large enough when next loop is entered
       
   171     // to prevent infinite looping.
       
   172     while ( (xDistance < delta && yDistance < delta)
       
   173             || !containerRect.contains(destPos) ) {
       
   174         destPos = randomPosition( containerRect );
       
   175         xDistance = abs( destPos.x() - curPos.x() );
       
   176         yDistance = abs( destPos.y() - curPos.y() );
       
   177     }
       
   178 
       
   179     // If, for some reason, the current position is out-of-bounds, then there's no
       
   180     // point to slowly move towards the destination. In that case, move immediately
       
   181     // to destination point.
       
   182     if ( !containerRect.contains(curPos) ) {
       
   183         return destPos;
       
   184     }
       
   185     // Otherwise, this is normal case and we will calculate a point which is just
       
   186     // a bit closer to the destination.
       
   187     
       
   188     // Version 1:
       
   189     //  o-----o---------------------------o
       
   190     //  p1    p2                          p3
       
   191     //
       
   192     // Version 2:
       
   193     //  o---------------------------o-----o
       
   194     //  p3                          p2    p1
       
   195     //
       
   196     // p1 - current widget position
       
   197     // p2 - next position to compute
       
   198     // p3 - destination random position
       
   199     QPointF p1(curPos);
       
   200     QPointF p2(0,0);
       
   201     QPointF p3(destPos);
       
   202 
       
   203     // Computes point p2 - new position between p1 and p3
       
   204 
       
   205     // Move the coordinate which is further away from the destination
       
   206     // and calculate the other coordinate from that so that the
       
   207     // result point p2 lies on the straigth line between p1 and p3.
       
   208     if ( yDistance > xDistance ) {
       
   209         if (p3.y() > p1.y()) {
       
   210             p2.setY(p1.y()+gStep);
       
   211         }
       
   212         else {
       
   213             p2.setY(p1.y()-gStep);
       
   214         }
       
   215         p2.setX((((p2.y()-p1.y())*(p3.x()-p1.x())) / (p3.y()-p1.y())) + p1.x()); // x2 = (((y2-y1)*(x3-x1)) / (y3-y1)) + x1
       
   216     }
       
   217     else {
       
   218         if (p3.x() > p1.x()) {
       
   219             p2.setX(p1.x()+gStep);
       
   220         }
       
   221         else {
       
   222             p2.setX(p1.x()-gStep);
       
   223         }
       
   224         p2.setY((((p3.y()-p1.y())*(p2.x()-p1.x())) / (p3.x()-p1.x())) + p1.y()); // y2 = (((y3-y1)*(x2-x1)) / (x3-x1)) + y1
       
   225     }
       
   226 
       
   227     // Return new position between points p1 and p3.
       
   228     return p2;
       
   229 }
       
   230 
       
   231 /*!
       
   232     Disconnect connections between indicator model and widget.
       
   233  */
       
   234 void SnsrBigClockContainer::resetIndicatorConnections()
       
   235 {
       
   236     disconnect(mIndicatorModel, SIGNAL(indicatorsUpdated(QList<SnsrIndicatorInfo>)),
       
   237                mIndicatorWidget, SLOT(showIndicators(QList<SnsrIndicatorInfo>)));
       
   238     
       
   239     disconnect(mIndicatorModel, SIGNAL(allIndicatorsDeactivated()),
       
   240                mIndicatorWidget, SLOT(removeAllIndicators()));
       
   241 }
       
   242 
       
   243 /*!
       
   244     Set background color.
       
   245  */
       
   246 void SnsrBigClockContainer::setBackgroundColor()
       
   247 {
       
   248     QColor backgroundColor = HbColorScheme::color(snsrBackgroundColorRole);
       
   249     if (backgroundColor.isValid()) {
       
   250         mBackgroundColor = backgroundColor;
       
   251     }
       
   252     else {
       
   253         mBackgroundColor = Qt::black;
       
   254     }
       
   255 }
       
   256 
       
   257 /*!
       
   258     Paints the contents of an item in local coordinates.
       
   259  */
       
   260 #ifdef COVERAGE_MEASUREMENT
       
   261 #pragma CTC SKIP
       
   262 #endif //COVERAGE_MEASUREMENT
       
   263 void SnsrBigClockContainer::paint(
       
   264         QPainter *painter,
       
   265         const QStyleOptionGraphicsItem *option,
       
   266         QWidget *widget
       
   267         )
       
   268 {
       
   269     Q_UNUSED(option)
       
   270     Q_UNUSED(widget)
       
   271 
       
   272     painter->fillRect(rect(), mBackgroundColor);
       
   273 }
       
   274 #ifdef COVERAGE_MEASUREMENT
       
   275 #pragma CTC ENDSKIP
       
   276 #endif //COVERAGE_MEASUREMENT
       
   277