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