Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

canvascard.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 
00021 #include "canvascard.h"
00022 
00023 #include <opie2/oresource.h>
00024 
00025 #include <qgfx_qws.h> // Needed to get the device's width
00026 
00027 #include <math.h>
00028 
00029 #if defined( QT_QWS_CASSIOPEIA )
00030 #define SLOW_HARDWARE
00031 #endif
00032 
00033 // Seems to be fast enough to me even without Transformations in the library
00034 //#if defined( QT_NO_TRANSFORMATIONS ) && defined( QT_QWS_IPAQ )
00035 //#define SLOW_HARDWARE
00036 //#endif
00037 
00038 
00039 QBitmap *Create180RotatedBitmap(QBitmap *srcBitmap)
00040 {
00041 #ifdef QT_NO_TRANSFORMATIONS
00042     int w = srcBitmap->width();
00043     int h = srcBitmap->height();
00044     QBitmap *dstBitmap = new QBitmap( w, h );
00045     // ### this is very poorly implemented and probably could be much faster
00046     for (int i = 0; i < w; i++)
00047         for (int j = 0; j < h; j++)
00048             bitBlt( dstBitmap, i, j, srcBitmap, w - i - 1, h - j - 1, 1, 1 );
00049     return dstBitmap;
00050 #else
00051     QWMatrix m;
00052     m.rotate( 180.0 );
00053     return new QBitmap( srcBitmap->xForm( m ) );
00054 #endif
00055 }
00056 
00057 
00058 QPixmap *CreateScaledPixmap(QPixmap *srcPixmap, double scaleX, double scaleY)
00059 {
00060 #ifdef QT_NO_TRANSFORMATIONS
00061     int w = srcPixmap->width();
00062     int h = srcPixmap->height();
00063     int newW = (int)(w * scaleX);
00064     int newH = (int)(h * scaleY);
00065     QPixmap *dstPixmap = new QPixmap( newW, newH );
00066     // ### this is very poorly implemented and probably could be much faster
00067     for (int i = 0; i < newW; i++) {
00068         int srcX = w * i / newW;
00069         if (newH == h) {
00070             // Optimise for scaleing in the X-axis only
00071             bitBlt( dstPixmap, i, 0, srcPixmap, srcX, 0, 1, h );
00072         } else {
00073             for (int j = 0; j < newH; j++) {
00074                 int srcY = h * j / newH;
00075                 bitBlt( dstPixmap, i, j, srcPixmap, srcX, srcY, 1, 1 );
00076             }
00077         }
00078     }
00079     return dstPixmap;
00080 #else
00081     QWMatrix s;
00082     s.scale( scaleX, scaleY );
00083     return new QPixmap( srcPixmap->xForm( s ) );
00084 #endif
00085 }
00086 
00087 
00088 // Initialise static member variables to NULL
00089 QPixmap *CanvasCard::cardsFaces = NULL;
00090 QPixmap *CanvasCard::cardsBacks = NULL;
00091 QBitmap *CanvasCard::cardsChars = NULL;
00092 QBitmap *CanvasCard::cardsSuits = NULL;
00093 QBitmap *CanvasCard::cardsCharsUpsideDown = NULL;
00094 QBitmap *CanvasCard::cardsSuitsUpsideDown = NULL;
00095 
00096 
00097 CanvasCard::CanvasCard( eValue v, eSuit s, bool f, QCanvas *canvas ) :
00098         Card(v, s, f), QCanvasRectangle( 0, 0, 1, 1, canvas ), cardBack(1), scaleX(1.0), scaleY(1.0)
00099 {
00100     if ( !cardsFaces ) {
00101         if ( qt_screen->deviceWidth() < 200 ) {
00102             cardsFaces = new QPixmap( Opie::Core::OResource::loadPixmap( "cards/card_face_small" ) );
00103             cardsBacks = new QPixmap( Opie::Core::OResource::loadPixmap( "cards/card_back0001_small" ) );
00104             cardsChars = new QBitmap();
00105         *cardsChars = Opie::Core::OResource::loadPixmap( "cards/card_chars_small" );
00106             cardsSuits = new QBitmap();
00107         *cardsSuits = Opie::Core::OResource::loadPixmap( "cards/card_suits_small" );
00108         } else {
00109             cardsFaces = new QPixmap( Opie::Core::OResource::loadPixmap( "cards/card_face" ) );
00110             cardsBacks = new QPixmap( Opie::Core::OResource::loadPixmap( "cards/card_back0001" ) );
00111             cardsChars = new QBitmap();
00112         *cardsChars = Opie::Core::OResource::loadPixmap( "cards/card_chars" );
00113             cardsSuits = new QBitmap();
00114         *cardsSuits = Opie::Core::OResource::loadPixmap( "cards/card_suits" );
00115         }
00116         cardsCharsUpsideDown = Create180RotatedBitmap( cardsChars );
00117         cardsSuitsUpsideDown = Create180RotatedBitmap( cardsSuits );
00118     }
00119     xOff = cardsFaces->width() / 2;
00120     yOff = cardsFaces->height() / 2;
00121     setSize( cardsFaces->width(), cardsFaces->height() );
00122     setPen( NoPen );
00123     flipping = FALSE;
00124 }
00125 
00126 
00127 void CanvasCard::setCardBack(int b)
00128 {
00129     if ( cardBack != b ) {
00130 
00131         cardBack = b;
00132 
00133         if ( cardsBacks )
00134             delete cardsBacks;
00135 
00136         if ( qt_screen->deviceWidth() < 200 ) {
00137             switch (cardBack) {
00138                 case 0:
00139                     cardsBacks = new QPixmap( Opie::Core::OResource::loadPixmap( "cards/card_back0001_small" ) ); break;
00140                 case 1:
00141                     cardsBacks = new QPixmap( Opie::Core::OResource::loadPixmap( "cards/card_back0002_small" ) ); break;
00142                 case 2:
00143                     cardsBacks = new QPixmap( Opie::Core::OResource::loadPixmap( "cards/card_back0003_small" ) ); break;
00144                 case 3:
00145                     cardsBacks = new QPixmap( Opie::Core::OResource::loadPixmap( "cards/card_back0004_small" ) ); break;
00146                 case 4:
00147                     cardsBacks = new QPixmap( Opie::Core::OResource::loadPixmap( "cards/card_back0005_small" ) ); break;
00148             }
00149         } else {
00150             switch (cardBack) {
00151                 case 0:
00152                     cardsBacks = new QPixmap( Opie::Core::OResource::loadPixmap( "cards/card_back0001" ) ); break;
00153                 case 1:
00154                     cardsBacks = new QPixmap( Opie::Core::OResource::loadPixmap( "cards/card_back0002" ) ); break;
00155                 case 2:
00156                     cardsBacks = new QPixmap( Opie::Core::OResource::loadPixmap( "cards/card_back0003" ) ); break;
00157                 case 3:
00158                     cardsBacks = new QPixmap( Opie::Core::OResource::loadPixmap( "cards/card_back0004" ) ); break;
00159                 case 4:
00160                     cardsBacks = new QPixmap( Opie::Core::OResource::loadPixmap( "cards/card_back0005" ) ); break;
00161             }
00162         }
00163 
00164         if ( !isFacing() )
00165             redraw();
00166     }
00167 }
00168 
00169 
00170 void CanvasCard::draw(QPainter &painter)
00171 {
00172     int ix = (int)x(), iy = (int)y();
00173 
00174     QPainter *p = &painter;
00175     QPixmap *unscaledCard = NULL;
00176 
00177     if ((scaleX <= 0.98) || (scaleY <= 0.98)) 
00178     {
00179         p = new QPainter();
00180         unscaledCard = new QPixmap( cardsFaces->width(), cardsFaces->height() );
00181         p->begin(unscaledCard);
00182         ix = 0;
00183         iy = 0;
00184     }
00185         
00186     if ( isFacing() ) {
00187         
00188         int w = cardsFaces->width(), h = cardsFaces->height();
00189 
00190         p->setBrush( QColor( 0xFF, 0xFF, 0xFF ) );
00191 
00192         if ( isRed() == TRUE )
00193             p->setPen( QColor( 0xFF, 0, 0 ) );
00194         else
00195             p->setPen( QColor( 0, 0, 0 ) );
00196 
00197         if ( qt_screen->deviceWidth() < 200 ) {
00198             p->drawPixmap( ix +      0, iy +     0, *cardsFaces );
00199             p->drawPixmap( ix +      3, iy +     3, *cardsChars, 5*(getValue()-1), 0, 5, 6 );
00200             p->drawPixmap( ix +     11, iy +     3, *cardsSuits, 5*(getSuit()-1), 0, 5, 6 );
00201             p->drawPixmap( ix +  w-3-5, iy + h-3-6, *cardsCharsUpsideDown, 5*(12-getValue()+1), 0, 5, 6 );
00202             p->drawPixmap( ix + w-11-5, iy + h-3-6, *cardsSuitsUpsideDown, 5*(3-getSuit()+1), 0, 5, 6 );
00203         } else {
00204             p->drawPixmap( ix +      0, iy +     0, *cardsFaces );
00205             p->drawPixmap( ix +      4, iy +     4, *cardsChars, 7*(getValue()-1), 0, 7, 7 );
00206             p->drawPixmap( ix +     12, iy +     4, *cardsSuits, 7*(getSuit()-1), 0, 7, 8 );
00207             p->drawPixmap( ix +  w-4-7, iy + h-4-7, *cardsCharsUpsideDown, 7*(12-getValue()+1), 0, 7, 7 );
00208             p->drawPixmap( ix + w-12-7, iy + h-5-7, *cardsSuitsUpsideDown, 7*(3-getSuit()+1), 0, 7, 8 );
00209         }
00210 
00211     } else {
00212         
00213         p->drawPixmap( ix, iy, *cardsBacks );
00214 
00215     }
00216 
00217     if (p != &painter)
00218     {
00219         p->end();
00220         QPixmap *scaledCard = CreateScaledPixmap( unscaledCard, scaleX, scaleY );
00221         int xoff = scaledCard->width() / 2;
00222         int yoff = scaledCard->height() / 2;
00223         painter.drawPixmap( (int)x() + xOff - xoff, (int)y() + yOff - yoff, *scaledCard );
00224         delete p;
00225         delete unscaledCard;
00226         delete scaledCard;
00227     }
00228 }
00229 
00230 
00231 static const double flipLift = 1.5;
00232 
00233 
00234 void CanvasCard::flipTo(int x2, int y2, int steps)
00235 {
00236     flipSteps = steps;
00237 
00238 #ifdef SLOW_HARDWARE
00239     move(x2,y2);
00240     Card::flipTo(x2,y2,steps);
00241 #else
00242     int x1 = (int)x();
00243     int y1 = (int)y();
00244     double dx = x2 - x1;
00245     double dy = y2 - y1;
00246 
00247     flipping = TRUE;
00248     destX = x2;
00249     destY = y2;
00250     animSteps = flipSteps;
00251     setVelocity(dx/animSteps, dy/animSteps-flipLift);
00252     setAnimated(TRUE);
00253 #endif
00254 }
00255 
00256 
00257 void CanvasCard::advance(int stage)
00258 {
00259     if ( stage==1 ) {
00260         if ( animSteps-- <= 0 ) {
00261             scaleX = 1.0;
00262             scaleY = 1.0;
00263             flipping = FALSE;
00264             setVelocity(0,0);
00265             setAnimated(FALSE);
00266             move(destX,destY); // exact
00267         } else {
00268             if ( flipping ) {
00269                 if ( animSteps > flipSteps / 2 ) {
00270                     // animSteps = flipSteps .. flipSteps/2 (flip up) -> 1..0
00271                     scaleX = ((double)animSteps/flipSteps-0.5)*2;
00272                 } else {
00273                     // animSteps = flipSteps/2 .. 0 (flip down) -> 0..1
00274                     scaleX = 1-((double)animSteps/flipSteps)*2;
00275                 }
00276                 if ( animSteps == flipSteps / 2-1 ) {
00277                     setYVelocity(yVelocity()+flipLift*2);
00278                     setFace( !isFacing() );
00279                 }
00280             }
00281         }
00282     }
00283     QCanvasRectangle::advance(stage);
00284 }
00285 
00286 
00287 void CanvasCard::animatedMove(int x2, int y2, int steps)
00288 {
00289     destX = x2;
00290     destY = y2;
00291 
00292     double x1 = x(), y1 = y(), dx = x2 - x1, dy = y2 - y1;
00293 
00294     // Ensure a good speed
00295     while ( fabs(dx/steps)+fabs(dy/steps) < 5.0 && steps > 4 )
00296         steps--;
00297 
00298     setAnimated(TRUE);
00299     setVelocity(dx/steps, dy/steps);
00300 
00301     animSteps = steps;
00302 }
00303 

Generated on Sat Nov 5 16:17:25 2005 for OPIE by  doxygen 1.4.2