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