examples/sfexamples/vibrapool/src/VibraPoolAppView.cpp

00001 // 
00002 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
00003 // All rights reserved.
00004 // This component and the accompanying materials are made available
00005 // under the terms of the License "Eclipse Public License v1.0"
00006 // which accompanies this distribution, and is available
00007 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
00008 // 
00009 // Initial Contributors:
00010 // Nokia Corporation - initial contribution.
00011 // 
00012 // Contributors:
00013 // 
00014 // Description:  Application view implementation
00015 // 
00016 // 
00017 
00018 
00019 // INCLUDE FILES
00020 #include <coemain.h>
00021 #include "VibraPoolAppView.h"
00022 #include <e32math.h>
00023 
00024 // Definitions related to the animation of the ball
00025 #define BALL_DIAMETER 25
00026 #define THRESHOLD  15
00027 #define TABLE_BORDER 30
00028 #define STEP 3
00029 
00030 
00031 // ============================ MEMBER FUNCTIONS ===============================
00032 
00033 // -----------------------------------------------------------------------------
00034 // CVibraPoolAppView::NewL()
00035 // Two-phased constructor.
00036 // -----------------------------------------------------------------------------
00037 //
00038 CVibraPoolAppView* CVibraPoolAppView::NewL( const TRect& aRect )
00039         {
00040         CVibraPoolAppView* self = CVibraPoolAppView::NewLC( aRect );
00041         CleanupStack::Pop( self );
00042         return self;
00043         }
00044 
00045 // -----------------------------------------------------------------------------
00046 // CVibraPoolAppView::NewLC()
00047 // Two-phased constructor.
00048 // -----------------------------------------------------------------------------
00049 //
00050 CVibraPoolAppView* CVibraPoolAppView::NewLC( const TRect& aRect )
00051         {
00052         CVibraPoolAppView* self = new ( ELeave ) CVibraPoolAppView;
00053         CleanupStack::PushL( self );
00054         self->ConstructL( aRect );
00055         return self; 
00056         }
00057 
00058 // -----------------------------------------------------------------------------
00059 // CVibraPoolAppView::ConstructL()
00060 // Symbian 2nd phase constructor can leave.
00061 // -----------------------------------------------------------------------------
00062 //
00063 void CVibraPoolAppView::ConstructL( const TRect& aRect )
00064         {
00065         // Create a window for this application view
00066         CreateWindowL();
00067         // Set the windows size
00068         SetRect( aRect );
00069         // Activate the window, which makes it ready to be drawn
00070         ActivateL();
00071 
00072         //========================================
00073         // Constructing our vibration control
00074         //========================================
00075         //
00076     iVibra = CHWRMVibra::NewL(); // No callbacks
00077     // Initial ball location on screen (set randomly).
00078     // Tee idea here is to limit the range of random numbers generated to the
00079     // valid area of the pool table where the ball may bouce (taking into consideration
00080     // the width of the wooden borders of the table and the diameter of the ball).
00081     iBallLoc.iX = Math::Random()%(aRect.Width()-(TABLE_BORDER*2)-(BALL_DIAMETER)-(THRESHOLD*2))+(THRESHOLD+TABLE_BORDER);
00082     iBallLoc.iY = Math::Random()%(aRect.Height()-(TABLE_BORDER*2)-(BALL_DIAMETER)-(THRESHOLD*2))+(THRESHOLD+TABLE_BORDER);
00083     // Number of pixels to step each time the ball moves
00084     iMoveX = iMoveY = STEP;
00085     // The ball is drawn because it did not fall in a hole
00086         iDrawBall = ETrue;
00087         // Construct and start our asynchronous object responsible of moving the ball. 
00088         iMove = CMoveBall::NewL(*this);
00089     iMove->StartMovingBall();
00090         }
00091 
00092 // -----------------------------------------------------------------------------
00093 // CVibraPoolAppView::CVibraPoolAppView()
00094 // C++ default constructor can NOT contain any code, that might leave.
00095 // -----------------------------------------------------------------------------
00096 //
00097 CVibraPoolAppView::CVibraPoolAppView()
00098         {
00099         // No implementation required
00100         }
00101 
00102 
00103 // -----------------------------------------------------------------------------
00104 // CVibraPoolAppView::~CVibraPoolAppView()
00105 // Destructor.
00106 // -----------------------------------------------------------------------------
00107 //
00108 CVibraPoolAppView::~CVibraPoolAppView()
00109         {
00110     delete iVibra;
00111     delete iMove;
00112     }
00113 
00114 
00115 // -----------------------------------------------------------------------------
00116 // CVibraPoolAppView::Draw()
00117 // Draws the display.
00118 // -----------------------------------------------------------------------------
00119 //
00120 void CVibraPoolAppView::Draw( const TRect& /*aRect*/ ) const
00121         {
00122         // Get the standard graphics context
00123         CWindowGc& gc = SystemGc();
00124         // Gets the control's extent
00125         TRect drawRect( Rect());
00126         // Clears the screen
00127         gc.Clear( drawRect );
00128 
00129         // Drawing the table
00130         //
00131         gc.SetPenStyle(CGraphicsContext::ENullPen);
00132         gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
00133         gc.SetBrushColor(TRgb(128,80,50));      // Dark brown
00134         gc.DrawRect(drawRect);
00135         gc.SetBrushColor(KRgbDarkGreen);
00136         gc.DrawRect(TRect(10,10, drawRect.Width()-10,drawRect.Height()-10));
00137         gc.SetBrushColor(KRgbGreen);
00138         gc.DrawRect(TRect(TABLE_BORDER,TABLE_BORDER, drawRect.Width()-TABLE_BORDER,drawRect.Height()-TABLE_BORDER));
00139 
00140         // Drawing the holes (the positions are set empirically)
00141         //
00142         gc.SetBrushColor(KRgbBlack);
00143                 // Upper left
00144         gc.DrawEllipse(TRect(15, 15, 50, 50));
00145                 // Upper right
00146         gc.DrawEllipse(TRect(drawRect.Width()-50, 15, drawRect.Width()-15, 50));
00147                 // Lower left
00148         gc.DrawEllipse(TRect(15, drawRect.Height()-50, 50, drawRect.Height()-15));
00149                 // Upper left
00150         gc.DrawEllipse(TRect(drawRect.Width()-50, drawRect.Height()-50, drawRect.Width()-15, drawRect.Height()-15));
00151                 
00152         // Drawing the ball
00153         //
00154         if(iDrawBall)
00155                 {               
00156                 gc.SetBrushColor(KRgbRed);
00157                 // The ball is drawn in its new location everytime CMoveBall updates it
00158                 gc.DrawEllipse(TRect(iBallLoc.iX, iBallLoc.iY, iBallLoc.iX+25, iBallLoc.iY+25));
00159                 }
00160         }
00161 
00162 // -----------------------------------------------------------------------------
00163 // CVibraPoolAppView::SizeChanged()
00164 // Called by framework when the view size is changed.
00165 // -----------------------------------------------------------------------------
00166 //
00167 void CVibraPoolAppView::SizeChanged()
00168         {  
00169         DrawNow();
00170         }
00171 
00172 
00173 //======================== VIBRAPOOL SPECIFIC FUNCTIONS ========================
00174 
00175 // -----------------------------------------------------------------------------
00176 // CVibraPoolAppView::HolesDetection()
00177 // Called by application to detect if the ball fell in a hole or not
00178 // -----------------------------------------------------------------------------
00179 //
00180 TBool CVibraPoolAppView::HolesDetection()
00181         {
00182         TRect r = Rect();
00183         // TABLE_BORDER represents the value of THRESHOLD+(TABLE_BORDER/2) which is the distance between
00184         // the position of the ball and the center of the hole. If it is less than 6 then the ball falls.
00185         // Otherwise, it continues rolling.
00186                 // check if ball falls in upper left hole
00187         if( iBallLoc.iX - TABLE_BORDER <= 6 && iBallLoc.iY - TABLE_BORDER <= 6 || 
00188                 // check if ball falls in upper right hole
00189                 (Rect().Width()-TABLE_BORDER) - iBallLoc.iX <= (6+BALL_DIAMETER) && iBallLoc.iY - TABLE_BORDER <= 6 ||
00190                 // check if ball falls in lower left hole
00191                 iBallLoc.iX - TABLE_BORDER <= 6 && (Rect().Height()-TABLE_BORDER) - iBallLoc.iY <= (6+BALL_DIAMETER)  ||
00192                 // check if ball falls in upper right hole
00193                 (Rect().Width()-TABLE_BORDER) - iBallLoc.iX <= (6+BALL_DIAMETER) && (Rect().Height()-TABLE_BORDER) - iBallLoc.iY <= (6+BALL_DIAMETER) )         
00194                 {
00195                 iMove->StopMoveBall();
00196                 // When the ball falls in the hole do not draw it
00197                 iDrawBall = EFalse;     
00198                 return ETrue;
00199                 }
00200         return EFalse;
00201         }
00202 
00203 // -----------------------------------------------------------------------------
00204 // CVibraPoolAppView::WallsDetection()
00205 // Called by application to detect if the ball hits a wall
00206 // -----------------------------------------------------------------------------
00207 //
00208 void CVibraPoolAppView::WallsDetection()
00209         {
00210         // Check if the ball will hit the right table border
00211         if(iBallLoc.iX+iMoveX >= (Rect().Width()-(TABLE_BORDER+BALL_DIAMETER-STEP)) )
00212                 {
00213                 // Change the direction of the movement to move to the left
00214                 iMoveX = -STEP; 
00215                 // If vibration is "on" in the device profile settings
00216                 if(iVibra->VibraSettings()==CHWRMVibra::EVibraModeON)
00217                         {                       
00218                         iVibra->StartVibraL(100, 20);
00219                         }
00220                 }
00221         // Check if the ball will hit the left table border
00222         else if(iBallLoc.iX-iMoveX <= TABLE_BORDER )
00223                 {
00224                 // Change the direction of the movement to move to the right
00225                 iMoveX = STEP;
00226                 if(iVibra->VibraSettings()==CHWRMVibra::EVibraModeON)
00227                         {                       
00228                         iVibra->StartVibraL(100, 20);
00229                         }
00230                 }
00231 
00232         // Increment the horizontal stepping
00233         iBallLoc.iX += iMoveX;
00234         
00235         // Check if the ball will hit the lower table border
00236         if(iBallLoc.iY+iMoveY >= (Rect().Height()-(TABLE_BORDER+BALL_DIAMETER-STEP)) )
00237                 {
00238                 // Change the direction of the movement to move up
00239                 iMoveY = -STEP;         
00240                 if(iVibra->VibraSettings()==CHWRMVibra::EVibraModeON)
00241                         {                       
00242                         iVibra->StartVibraL(100, 20);
00243                         }
00244                 }
00245         // Check if the ball will hit the upper table border
00246         else if(iBallLoc.iY-iMoveY <= TABLE_BORDER )
00247                 {
00248                 // Change the direction of the movement to move down
00249                 iMoveY  = STEP;
00250                 if(iVibra->VibraSettings()==CHWRMVibra::EVibraModeON)
00251                         {                       
00252                         iVibra->StartVibraL(100, 20);
00253                         }
00254                 }
00255 
00256         // Increment the vertical stepping
00257         iBallLoc.iY += iMoveY;  
00258         
00259         // After ball location is updated check if the ball is to fall in a hole 
00260         if( HolesDetection() )
00261                 {
00262                 // If vibration is on in the profile settings
00263                 if(iVibra->VibraSettings()==CHWRMVibra::EVibraModeON)
00264                         {
00265                         // Vibrate in negative direction        
00266                         iVibra->StartVibraL(300, -100);
00267                         // Update the screen now
00268                         DrawNow();
00269                         // First interval of half a second
00270                         User::After(500000);            
00271                         // Vibrate in positive direction        
00272                         iVibra->StartVibraL(300, 100);
00273                         // Second interval of another half second
00274                         User::After(500000);            
00275                         iVibra->StartVibraL(1000, -100);                
00276                         }
00277                 }
00278         }
00279         
00280 // -----------------------------------------------------------------------------
00281 // CVibraPoolAppView::UpdateScreen()
00282 // This is the callback fundtion called from CMoveBall
00283 // -----------------------------------------------------------------------------
00284 //
00285 void CVibraPoolAppView::UpdateScreen()
00286         {
00287         WallsDetection();
00288         DrawNow();
00289         }
00290                 
00291 // -----------------------------------------------------------------------------
00292 // CVibraPoolAppView::ReStartGame()
00293 // Clears the location of the ball and the timer, then relocates and restarts 
00294 // the timer
00295 // -----------------------------------------------------------------------------
00296 //
00297 void CVibraPoolAppView::ReStartGame()
00298         {
00299         // Redisplay the ball after it fell in the hole
00300         iDrawBall = ETrue;
00301         iMove->StopMoveBall();
00302         iBallLoc.iX = Math::Random()%(Rect().Width()-(TABLE_BORDER*2)-(BALL_DIAMETER)-(THRESHOLD*2))+(THRESHOLD+TABLE_BORDER);
00303     iBallLoc.iY = Math::Random()%(Rect().Height()-(TABLE_BORDER*2)-(BALL_DIAMETER)-(THRESHOLD*2))+(THRESHOLD+TABLE_BORDER);
00304     iMove->StartMovingBall();
00305         }
00306 
00307 // -----------------------------------------------------------------------------
00308 // CVibraPoolAppView::StopGame()
00309 // THe functions checks in its implementation if its object is already running
00310 // before trying to stop it. This prevents the panic caused by trying to cancel
00311 // an asynchronous call which is not outstanding on the schedular
00312 // -----------------------------------------------------------------------------
00313 //
00314 void CVibraPoolAppView::StopGame()
00315         {
00316         iMove->StopMoveBall();
00317         }
00318 
00319 
00320 // End of File

Generated by  doxygen 1.6.2