demos/qtdemo/demoitem.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the demonstration applications of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "demoitem.h"
       
    43 #include "menumanager.h"
       
    44 #include "guide.h"
       
    45 #include "colors.h"
       
    46 
       
    47 QHash<QString, SharedImage *> DemoItem::sharedImageHash;
       
    48 QMatrix DemoItem::matrix;
       
    49 
       
    50 DemoItem::DemoItem(QGraphicsScene *scene, QGraphicsItem *parent) : QGraphicsItem(parent, scene)
       
    51 {
       
    52     this->opacity = 1.0;
       
    53     this->locked = false;
       
    54     this->prepared = false;
       
    55     this->neverVisible = false;
       
    56     this->noSubPixeling = false;
       
    57     this->currentAnimation = 0;
       
    58     this->currGuide = 0;
       
    59     this->guideFrame = 0;
       
    60     this->sharedImage = new SharedImage();
       
    61     ++this->sharedImage->refCount;
       
    62 }
       
    63 
       
    64 DemoItem::~DemoItem()
       
    65 {
       
    66     if(--this->sharedImage->refCount == 0){
       
    67         if (!this->hashKey.isEmpty())
       
    68             DemoItem::sharedImageHash.remove(this->hashKey);
       
    69         delete this->sharedImage;
       
    70     }
       
    71 }
       
    72 
       
    73 void DemoItem::setNeverVisible(bool never)
       
    74 {
       
    75     Q_UNUSED(never);
       
    76 /*
       
    77     this->neverVisible = never;
       
    78     if (never){
       
    79         this->setVisible(false);
       
    80         QList<QGraphicsItem *> c = children();
       
    81         for (int i=0; i<c.size(); i++){
       
    82             DemoItem *d = dynamic_cast<DemoItem *>(c[i]); // Don't use dynamic cast because it needs RTTI support.
       
    83             if (d)
       
    84                 d->setNeverVisible(true);
       
    85             else{
       
    86                 c[i]->setVisible(false);
       
    87             }
       
    88         }
       
    89     }
       
    90 */
       
    91 }
       
    92 
       
    93 void DemoItem::setRecursiveVisible(bool visible){
       
    94     if (visible && this->neverVisible){
       
    95         this->setVisible(false);
       
    96         return;
       
    97     }
       
    98 
       
    99     this->setVisible(visible);
       
   100     QList<QGraphicsItem *> c = children();
       
   101     for (int i=0; i<c.size(); i++){
       
   102         // DemoItem *d = dynamic_cast<DemoItem *>(c[i]);
       
   103         // if (d)
       
   104         //     d->setRecursiveVisible(visible);
       
   105         // else{
       
   106             c[i]->setVisible(visible);
       
   107         // }
       
   108     }
       
   109 }
       
   110 
       
   111 void DemoItem::useGuide(Guide *guide, float startFrame)
       
   112 {
       
   113     this->startFrame = startFrame;
       
   114     this->guideFrame = startFrame;
       
   115     while (this->guideFrame > guide->startLength + guide->length()){
       
   116         if (guide->nextGuide == guide->firstGuide)
       
   117             break;
       
   118 
       
   119         guide = guide->nextGuide;
       
   120     }
       
   121     this->currGuide = guide;
       
   122 }
       
   123 
       
   124 void DemoItem::guideAdvance(float distance)
       
   125 {
       
   126     this->guideFrame += distance;
       
   127     while (this->guideFrame > this->currGuide->startLength + this->currGuide->length()){
       
   128         this->currGuide = this->currGuide->nextGuide;
       
   129         if (this->currGuide == this->currGuide->firstGuide)
       
   130             this->guideFrame -= this->currGuide->lengthAll();
       
   131     }
       
   132 }
       
   133 
       
   134 void DemoItem::guideMove(float moveSpeed)
       
   135 {
       
   136     this->currGuide->guide(this, moveSpeed);
       
   137 }
       
   138 
       
   139 void DemoItem::setPosUsingSheepDog(const QPointF &dest, const QRectF &sceneFence)
       
   140 {
       
   141     this->setPos(dest);
       
   142     if (sceneFence.isNull())
       
   143         return;
       
   144 
       
   145     // I agree. This is not the optimal way of doing it.
       
   146     // But don't want for use time on it now....
       
   147     float itemWidth = this->boundingRect().width();
       
   148     float itemHeight = this->boundingRect().height();
       
   149     float fenceRight = sceneFence.x() + sceneFence.width();
       
   150     float fenceBottom = sceneFence.y() + sceneFence.height();
       
   151 
       
   152     if (this->scenePos().x() < sceneFence.x()) this->moveBy(this->mapFromScene(QPointF(sceneFence.x(), 0)).x(), 0);
       
   153     if (this->scenePos().x() > fenceRight - itemWidth) this->moveBy(this->mapFromScene(QPointF(fenceRight - itemWidth, 0)).x(), 0);
       
   154     if (this->scenePos().y() < sceneFence.y()) this->moveBy(0, this->mapFromScene(QPointF(0, sceneFence.y())).y());
       
   155     if (this->scenePos().y() > fenceBottom - itemHeight) this->moveBy(0, this->mapFromScene(QPointF(0, fenceBottom - itemHeight)).y());
       
   156 }
       
   157 
       
   158 void DemoItem::setGuidedPos(const QPointF &pos)
       
   159 {
       
   160     this->guidedPos = pos;
       
   161 }
       
   162 
       
   163 QPointF DemoItem::getGuidedPos()
       
   164 {
       
   165     return this->guidedPos;
       
   166 }
       
   167 
       
   168 void DemoItem::switchGuide(Guide *guide)
       
   169 {
       
   170     this->currGuide = guide;
       
   171     this->guideFrame = 0;
       
   172 }
       
   173 
       
   174 bool DemoItem::inTransition()
       
   175 {
       
   176     if (this->currentAnimation)
       
   177         return this->currentAnimation->running();
       
   178     else
       
   179         return false;
       
   180 }
       
   181 
       
   182 void DemoItem::setMatrix(const QMatrix &matrix)
       
   183 {
       
   184     DemoItem::matrix = matrix;
       
   185 }
       
   186 
       
   187 void DemoItem::useSharedImage(const QString &hashKey)
       
   188 {
       
   189     this->hashKey = hashKey;
       
   190     if (!sharedImageHash.contains(hashKey))
       
   191         sharedImageHash.insert(hashKey, this->sharedImage);
       
   192     else {
       
   193         if(--this->sharedImage->refCount == 0)
       
   194             delete this->sharedImage;
       
   195         this->sharedImage = sharedImageHash.value(hashKey);
       
   196         ++this->sharedImage->refCount;
       
   197     }
       
   198 }
       
   199 
       
   200 bool DemoItem::validateImage()
       
   201 {
       
   202     if ((this->sharedImage->matrix != DemoItem::matrix && !Colors::noRescale) || !(this->sharedImage->image || this->sharedImage->pixmap)){
       
   203         // (Re)create image according to new matrix
       
   204         delete this->sharedImage->image;
       
   205         this->sharedImage->image = 0;
       
   206         delete this->sharedImage->pixmap;
       
   207         this->sharedImage->pixmap = 0;
       
   208         this->sharedImage->matrix = DemoItem::matrix;
       
   209 
       
   210         // Let subclass create and draw a new image according to the new matrix
       
   211         QImage *image = this->createImage(Colors::noRescale ? QMatrix() : DemoItem::matrix);
       
   212         if (image){
       
   213             if (Colors::showBoundingRect){
       
   214                 // draw red transparent rect
       
   215                 QPainter painter(image);
       
   216                 painter.fillRect(image->rect(), QColor(255, 0, 0, 50));
       
   217                 painter.end();
       
   218             }
       
   219 
       
   220             this->sharedImage->unscaledBoundingRect = this->sharedImage->matrix.inverted().mapRect(image->rect());
       
   221             if (Colors::usePixmaps){
       
   222                 if (image->isNull())
       
   223                     this->sharedImage->pixmap = new QPixmap(1, 1);
       
   224                 else
       
   225                     this->sharedImage->pixmap = new QPixmap(image->size());
       
   226                 this->sharedImage->pixmap->fill(QColor(0, 0, 0, 0));
       
   227                 QPainter painter(this->sharedImage->pixmap);
       
   228                 painter.drawImage(0, 0, *image);
       
   229                 delete image;
       
   230             } else {
       
   231                 this->sharedImage->image = image;
       
   232             }
       
   233             return true;
       
   234         } else
       
   235             return false;
       
   236     }
       
   237     return true;
       
   238 }
       
   239 
       
   240 QRectF DemoItem::boundingRect() const
       
   241 {
       
   242     const_cast<DemoItem *>(this)->validateImage();
       
   243     return this->sharedImage->unscaledBoundingRect;
       
   244 }
       
   245 
       
   246 void DemoItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
       
   247 {
       
   248     Q_UNUSED(option);
       
   249     Q_UNUSED(widget);
       
   250 
       
   251     if (this->validateImage()){
       
   252 
       
   253         bool wasSmoothPixmapTransform = painter->testRenderHint(QPainter::SmoothPixmapTransform);
       
   254         painter->setRenderHint(QPainter::SmoothPixmapTransform);
       
   255 
       
   256         if (Colors::noRescale){
       
   257             // Let the painter scale the image for us.
       
   258             // This may degrade both quality and performance
       
   259             if (this->sharedImage->image)
       
   260                 painter->drawImage(this->pos(), *this->sharedImage->image);
       
   261             else
       
   262                 painter->drawPixmap(this->pos(), *this->sharedImage->pixmap);
       
   263         }
       
   264         else {
       
   265             QMatrix m = painter->worldMatrix();
       
   266             painter->setWorldMatrix(QMatrix());
       
   267             float x = this->noSubPixeling ? qRound(m.dx()) : m.dx();
       
   268             float y = this->noSubPixeling ? qRound(m.dy()) : m.dy();
       
   269             if (this->sharedImage->image)
       
   270                 painter->drawImage(QPointF(x, y), *this->sharedImage->image);
       
   271             else
       
   272                 painter->drawPixmap(QPointF(x, y), *this->sharedImage->pixmap);
       
   273         }
       
   274 
       
   275         if (!wasSmoothPixmapTransform) {
       
   276             painter->setRenderHint(QPainter::SmoothPixmapTransform, false);
       
   277         }
       
   278 
       
   279     }
       
   280 }