00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <coemain.h>
00031 #include <gulutil.h>
00032 #include <e32keys.h>
00033 #include <aknviewappui.h>
00034
00035
00036 #include "OandXAppView.h"
00037 #include "OandXAppUi.h"
00038 #include "OandXController.h"
00039 #include "OandXEngine.h"
00040 #include <OandX.rsg>
00041 #include "OandX.pan"
00042 #include "OandX.hrh"
00043 #include "oandxdefs.h"
00044
00045 COandXGameView* COandXGameView::NewLC()
00046 {
00047 COandXGameView* self = new ( ELeave ) COandXGameView();
00048 CleanupStack::PushL( self );
00049 self->ConstructL();
00050 return self;
00051 }
00052
00053 COandXGameView::COandXGameView( )
00054 {
00055 }
00056
00057 void COandXGameView::ConstructL()
00058 {
00059 BaseConstructL( R_OANDX_GAME_VIEW );
00060 iContainer = COandXAppViewContainer::NewL(ClientRect());
00061 iContainer->SetMopParent( this );
00062 }
00063
00064 COandXGameView::~COandXGameView()
00065 {
00066 if (iGameViewStacked)
00067 {
00068 AppUi()->RemoveFromViewStack( *this, iContainer );
00069 }
00070 delete iContainer;
00071 }
00072
00073 TUid COandXGameView::Id() const
00074 {
00075 return KUidOandXView;
00076 }
00077
00078 void COandXGameView::HandleCommandL( TInt aCommand )
00079 {
00080 switch ( aCommand )
00081 {
00082
00083 case EAknSoftkeyBack:
00084 {
00085 AppUi()->HandleCommandL( EEikCmdExit );
00086 break;
00087 }
00088
00089 default:
00090 {
00091 AppUi()->HandleCommandL( aCommand );
00092 break;
00093 }
00094 }
00095 }
00096
00097 void COandXGameView::HandleViewRectChange()
00098 {
00099 if ( iContainer )
00100 {
00101 iContainer->SetRect(ClientRect());
00102 }
00103 }
00104
00105 void COandXGameView::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane)
00106 {
00107 if (aResourceId != R_OANDX_GAME_MENU)
00108 {
00109 return;
00110 }
00111 if (Controller().IsNewGame())
00112 {
00113 aMenuPane->DeleteMenuItem(EOandXNewGame);
00114 if (!Controller().IsCrossTurn())
00115 {
00116 aMenuPane->SetItemTextL(EOandXFirstPlayer,R_OANDX_X_MOVES_FIRST);
00117 }
00118 }
00119 else
00120 {
00121 aMenuPane->DeleteMenuItem(EOandXFirstPlayer);
00122 }
00123 }
00124
00125 void COandXGameView::DoActivateL(const TVwsViewId& ,
00126 TUid ,
00127 const TDesC8& )
00128 {
00129 __ASSERT_ALWAYS(!iGameViewStacked, Panic(EOandXControlAlreadyStacked));
00130 AppUi()->AddToStackL( *this, iContainer );
00131 iGameViewStacked = ETrue;
00132
00133 iContainer->MakeVisible(ETrue);
00134 iContainer->DrawNow();
00135 }
00136
00137 void COandXGameView::DoDeactivate()
00138 {
00139 __ASSERT_ALWAYS(iGameViewStacked, Panic(EOandXControlNotStacked));
00140 AppUi()->RemoveFromViewStack( *this, iContainer );
00141 iGameViewStacked = EFalse;
00142
00143 iContainer->MakeVisible(EFalse);
00144 }
00145
00146 COandXAppViewContainer* COandXGameView::Container()
00147 {
00148 return iContainer;
00149 }
00150
00151
00152
00153
00154 void COandXSymbolControl::DrawSymbol(CWindowGc& aGc, const TRect& aRect, TBool aDrawCross) const
00155 {
00156 TRect drawRect(aRect);
00157
00158
00159 drawRect.Shrink(aRect.Width()/6,aRect.Height()/6);
00160
00161
00162 TSize penSize(aRect.Width()/9,aRect.Height()/9);
00163 aGc.SetPenSize(penSize);
00164 aGc.SetPenStyle(CGraphicsContext::ESolidPen);
00165
00166 if (aDrawCross)
00167 {
00168 aGc.SetPenColor(KRgbGreen);
00169
00170
00171 drawRect.Shrink(penSize.iWidth/2,penSize.iHeight/2);
00172
00173 aGc.DrawLine(drawRect.iTl, drawRect.iBr);
00174 TInt temp;
00175 temp = drawRect.iTl.iX;
00176 drawRect.iTl.iX = drawRect.iBr.iX;
00177 drawRect.iBr.iX = temp;
00178 aGc.DrawLine(drawRect.iTl, drawRect.iBr);
00179 }
00180 else
00181 {
00182 aGc.SetPenColor(KRgbRed);
00183 aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
00184 aGc.DrawEllipse(drawRect);
00185 }
00186 };
00187
00188
00189
00190 COandXTile::COandXTile()
00191 {
00192 }
00193
00194 COandXTile::~COandXTile()
00195 {
00196 }
00197
00198 void COandXTile::ConstructL(RWindow& aWindow)
00199 {
00200 SetContainerWindowL(aWindow);
00201
00202 }
00203
00204 void COandXTile::Draw(const TRect& ) const
00205 {
00206 TTileState tileType;
00207 tileType = iCmdHandler->TileStatus(this);
00208
00209 CWindowGc& gc = SystemGc();
00210 TRect rect = Rect();
00211
00212 if (IsFocused())
00213 {
00214 gc.SetBrushColor(KRgbYellow);
00215 }
00216 gc.Clear(rect);
00217 if (tileType!=ETileBlank)
00218 {
00219 DrawSymbol(gc, rect, tileType==ETileCross);
00220 }
00221 }
00222
00223 void COandXTile::SetOwnerAndObserver(COandXAppViewContainer* aControl)
00224 {
00225 iCmdHandler = aControl;
00226 SetObserver(aControl);
00227 }
00228
00229 void COandXTile::TryHitL()
00230 {
00231 if (iCmdHandler->TryHitSquareL(this))
00232 {
00233 DrawDeferred();
00234 }
00235 }
00236
00237 TKeyResponse COandXTile::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
00238 {
00239 TKeyResponse keyResponse = EKeyWasNotConsumed;
00240 if (aType!=EEventKey)
00241 {
00242 return keyResponse;
00243 }
00244 switch (aKeyEvent.iCode)
00245 {
00246 case EKeyOK:
00247 TryHitL();
00248 keyResponse = EKeyWasConsumed;
00249 break;
00250 default:
00251 keyResponse = EKeyWasNotConsumed;
00252 break;
00253 }
00254 return keyResponse;
00255 }
00256
00257 TCoeInputCapabilities COandXTile::InputCapabilities() const
00258 {
00259 return TCoeInputCapabilities::ENavigation;
00260 }
00261
00262 void COandXTile::HandlePointerEventL(const TPointerEvent& aPointerEvent)
00263 {
00264 if (aPointerEvent.iType == TPointerEvent::EButton1Down)
00265 {
00266 TryHitL();
00267 }
00268 }
00269
00270 void COandXTile::FocusChanged(TDrawNow aDrawNow)
00271 {
00272 if (aDrawNow == EDrawNow)
00273 {
00274 DrawNow();
00275 }
00276 }
00277
00278
00279
00280
00281 COandXStatusWin* COandXStatusWin::NewL(RWindow& aWindow)
00282 {
00283 COandXStatusWin* self=new(ELeave) COandXStatusWin;
00284 CleanupStack::PushL(self);
00285 self->ConstructL(aWindow);
00286 CleanupStack::Pop();
00287 self->SetFocusing(EFalse);
00288 return self;
00289 }
00290
00291 COandXStatusWin::COandXStatusWin()
00292 {
00293 }
00294
00295 COandXStatusWin::~COandXStatusWin()
00296 {
00297 }
00298
00299 void COandXStatusWin::ConstructL(RWindow& aWindow)
00300 {
00301 SetContainerWindowL(aWindow);
00302
00303 }
00304
00305 void COandXStatusWin::Draw(const TRect& ) const
00306 {
00307 CWindowGc& gc = SystemGc();
00308 TRect boxRect = Rect();
00309 gc.Clear(boxRect);
00310 TInt boxHeight = boxRect.iBr.iY - boxRect.iTl.iY;
00311 boxRect.iTl.iX = boxRect.iBr.iX - boxHeight;
00312 DrawSymbol(gc, boxRect, Controller().IsCrossTurn());
00313 }
00314
00315
00316
00317
00318 #define KBorderWidth 10
00319 #define KLineWidth ((KTilesPerRow > KTilesPerCol ? KTilesPerRow : KTilesPerCol) > 4 ? 2 : 4)
00320
00321
00322 COandXAppViewContainer* COandXAppViewContainer::NewL(const TRect& aRect)
00323 {
00324 COandXAppViewContainer* self = new(ELeave) COandXAppViewContainer;
00325 CleanupStack::PushL(self);
00326 self->ConstructL(aRect);
00327 CleanupStack::Pop(self);
00328 return self;
00329 }
00330
00331 COandXAppViewContainer::COandXAppViewContainer()
00335 {
00336
00337 }
00338
00339 COandXAppViewContainer::~COandXAppViewContainer()
00340 {
00341 for (TInt i=0; i<KNumberOfTiles; i++)
00342 {
00343 delete iTiles[i];
00344 }
00345 iTiles.Close();
00346 delete iStatusWin;
00347 }
00348
00349 void COandXAppViewContainer::ConstructL(const TRect& aRect)
00350 {
00351
00352 CreateWindowL();
00353
00354 for (TInt i = 0; i < KNumberOfTiles; i++)
00355 {
00356 User::LeaveIfError(iTiles.Append(CreateTileL()));
00357 }
00358 ComponentControl(0)->SetFocus(ETrue);
00359 iStatusWin = COandXStatusWin::NewL(Window());
00360
00361
00362 SetRect(aRect);
00363
00364 ActivateL();
00365 }
00366
00367 COandXTile* COandXAppViewContainer::CreateTileL()
00368 {
00369 COandXTile* tile = new(ELeave) COandXTile;
00370 CleanupStack::PushL(tile);
00371 tile->ConstructL(Window());
00372 CleanupStack::Pop();
00373 tile->SetOwnerAndObserver(this);
00374 return tile;
00375 }
00376
00377 void COandXAppViewContainer::SizeChanged()
00378 {
00379 __ASSERT_DEBUG(iTiles[KNumberOfTiles-1], Panic(EOandXNoTiles));
00380
00381 TRect rect = Rect();
00382 rect.iTl.iY = rect.iBr.iY - KStatusWinHeight;
00383 iStatusWin->SetRect(rect);
00384 rect = Rect();
00385 rect.iBr.iY -= KStatusWinHeight;
00386 TSize controlSize = rect.Size();
00387 TSize tileSize;
00388 tileSize.iWidth=2*((controlSize.iWidth-2*KBorderWidth-(KTilesPerRow-1)*KLineWidth)/(2*KTilesPerRow));
00389 tileSize.iHeight=2*((controlSize.iHeight-2*KBorderWidth-(KTilesPerCol-1)*KLineWidth)/(2*KTilesPerCol));
00390 iTileSide = tileSize.iWidth < tileSize.iHeight ? tileSize.iWidth :tileSize.iHeight;
00391 TSize boardSize;
00392 boardSize.iWidth = KTilesPerRow*iTileSide + (KTilesPerRow-1)*KLineWidth;
00393 boardSize.iHeight = KTilesPerCol*iTileSide + (KTilesPerCol-1)*KLineWidth;
00394 iBoardRect.iTl.iX = (controlSize.iWidth - boardSize.iWidth)/2;
00395 iBoardRect.iTl.iY = (controlSize.iHeight - boardSize.iHeight)/2;
00396 iBoardRect.iBr.iX = iBoardRect.iTl.iX + boardSize.iWidth;
00397 iBoardRect.iBr.iY = iBoardRect.iTl.iY + boardSize.iHeight;
00398 iBorderRect = iBoardRect;
00399 iBorderRect.Grow(KBorderWidth,KBorderWidth);
00400
00401 for (TInt i=0; i<KNumberOfTiles; i++)
00402 {
00403 TInt row = i / KTilesPerRow;
00404 TInt col = i % KTilesPerRow;
00405 TRect tileRect;
00406 tileRect.iTl.iX = iBoardRect.iTl.iX + col * (iTileSide + KLineWidth);
00407 tileRect.iTl.iY = iBoardRect.iTl.iY + row * (iTileSide + KLineWidth);
00408 tileRect.iBr.iX = tileRect.iTl.iX + iTileSide;
00409 tileRect.iBr.iY = tileRect.iTl.iY + iTileSide;
00410 ComponentControl(i)->SetRect(tileRect);
00411 }
00412 }
00413
00414 void COandXAppViewContainer::ResetView()
00415 {
00416 MoveFocusTo(0);
00417 DrawNow();
00418 }
00419
00420
00421 void COandXAppViewContainer::Draw(const TRect& ) const
00422 {
00423 CWindowGc& gc = SystemGc();
00424 TRect rect = Rect();
00425
00426
00427 gc.SetPenStyle(CGraphicsContext::ENullPen);
00428 gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
00429 gc.SetBrushColor(KRgbWhite);
00430 DrawUtils::DrawBetweenRects(gc, rect, iBorderRect);
00431
00432
00433 gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
00434 gc.SetBrushColor(KRgbGray);
00435 DrawUtils::DrawBetweenRects(gc, iBorderRect, iBoardRect);
00436
00437
00438 gc.SetBrushColor(KRgbBlack);
00439 TRect line;
00440 line.iTl.iX = iBoardRect.iTl.iX + iTileSide;
00441 line.iTl.iY = iBoardRect.iTl.iY;
00442 line.iBr.iX = line.iTl.iX + KLineWidth;
00443 line.iBr.iY = iBoardRect.iBr.iY;
00444 gc.DrawRect(line);
00445
00446 for (TInt i = 0; i < KTilesPerRow - 2; i++)
00447 {
00448 line .iTl.iX += iTileSide + KLineWidth;
00449 line .iBr.iX += iTileSide + KLineWidth;
00450 gc.DrawRect(line);
00451 }
00452
00453 line.iTl.iX = iBoardRect.iTl.iX;
00454 line.iTl.iY = iBoardRect.iTl.iY + iTileSide;
00455 line.iBr.iX = iBoardRect.iBr.iX;
00456 line.iBr.iY = line.iTl.iY + KLineWidth;
00457 gc.DrawRect(line);
00458
00459 for (TInt i = 0; i < KTilesPerCol - 2; i++)
00460 {
00461 line .iTl.iY += iTileSide + KLineWidth;
00462 line .iBr.iY += iTileSide + KLineWidth;
00463 gc.DrawRect(line);
00464 }
00465 }
00466
00467
00468 TInt COandXAppViewContainer::CountComponentControls() const
00469 {
00470 return KNumberOfTiles +1;
00471 }
00472
00473 CCoeControl* COandXAppViewContainer::ComponentControl(TInt aIndex) const
00474 {
00475 if (aIndex==KNumberOfTiles)
00476 {
00477 return iStatusWin;
00478 }
00479 else
00480 {
00481 return const_cast<COandXTile*>(iTiles[aIndex]);
00482 }
00483 }
00484
00485 TKeyResponse COandXAppViewContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
00486 {
00487 TKeyResponse keyResponse = EKeyWasNotConsumed;
00488 if (aType!=EEventKey)
00489 {
00490 return keyResponse;
00491 }
00492 TInt index = IdOfFocusControl();
00493 switch (aKeyEvent.iCode)
00494 {
00495 case EKeyLeftArrow:
00496 if (index % KTilesPerRow)
00497 {
00498 MoveFocusTo(index-1);
00499 keyResponse = EKeyWasConsumed;
00500 }
00501 break;
00502 case EKeyRightArrow:
00503 if ((index % KTilesPerRow) < KTilesPerRow - 1)
00504 {
00505 MoveFocusTo(index+1);
00506 keyResponse = EKeyWasConsumed;
00507 }
00508 break;
00509 case EKeyUpArrow:
00510 if (index >= KTilesPerRow)
00511 {
00512 MoveFocusTo(index-KTilesPerRow);
00513 keyResponse = EKeyWasConsumed;
00514 }
00515 break;
00516 case EKeyDownArrow:
00517 if (index < KNumberOfTiles - KTilesPerRow)
00518 {
00519 MoveFocusTo(index+KTilesPerRow);
00520 keyResponse = EKeyWasConsumed;
00521 }
00522 break;
00523 default:
00524 keyResponse = ComponentControl(index)->OfferKeyEventL(aKeyEvent,aType);
00525 break;
00526 }
00527 return keyResponse;
00528 }
00529
00530 TInt COandXAppViewContainer::IdOfFocusControl()
00531 {
00532 TInt ret = -1;
00533 for (TInt i=0; i<KNumberOfTiles; i++)
00534 {
00535 if (ComponentControl(i)->IsFocused())
00536 {
00537 ret = i;
00538 break;
00539 }
00540 }
00541 __ASSERT_ALWAYS(ret>=0, Panic(EOandXNoTileWithFocus));
00542 return ret;
00543 }
00544
00545 void COandXAppViewContainer::SwitchFocus(TInt aFromIndex, CCoeControl* aToControl)
00546 {
00547 ComponentControl(aFromIndex)->SetFocus(EFalse, EDrawNow);
00548 aToControl->SetFocus(ETrue, EDrawNow);
00549 }
00550
00551 void COandXAppViewContainer::MoveFocusTo(const TInt index)
00552 {
00553 TInt oldIndex = IdOfFocusControl();
00554 if (index!= oldIndex)
00555 {
00556 SwitchFocus(oldIndex, ComponentControl(index));
00557 }
00558 }
00559
00560
00561 void COandXAppViewContainer::HandleControlEventL(CCoeControl* aControl, TCoeEvent aEventType)
00562 {
00563 switch (aEventType)
00564 {
00565 case EEventRequestFocus:
00566 SwitchFocus(IdOfFocusControl(), aControl);
00567 break;
00568 default:
00569 break;
00570 }
00571 }
00572
00573 TBool COandXAppViewContainer::TryHitSquareL(const COandXTile* aControl)
00574 {
00575 return Controller().HitSquareL(Index(aControl));
00576 }
00577
00578 TTileState COandXAppViewContainer::TileStatus(const COandXTile* aControl) const
00579 {
00580 return Engine().TileStatus(Index(aControl));
00581 }
00582
00583 void COandXAppViewContainer::ShowTurn()
00584 {
00585 iStatusWin->DrawDeferred();
00586 }