examples/sfexamples/oandx/src/oandxappview.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:
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 // O and X symbol-drawing control member functions
00031 
00032 void COandXSymbolControl::DrawSymbol(CWindowGc& aGc, const TRect& aRect, TBool aDrawCross) const
00033         {
00034         TRect drawRect(aRect);
00035         
00036         // Shrink by about 15%
00037         drawRect.Shrink(aRect.Width()/6,aRect.Height()/6); 
00038         
00039     // Pen size set to just over 10% of the overall shape's size
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                 // Cosmetic reduction of cross size by half the line width
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 // draw a circle
00059                 {
00060                 aGc.SetPenColor(KRgbRed);
00061                 aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
00062                 aGc.DrawEllipse(drawRect);
00063                 }
00064         };
00065 
00066 // Tile member functions
00067 
00068 COandXTile::COandXTile()
00069         {
00070         }
00071         
00072 COandXTile::~COandXTile()
00073         {
00074         }
00075 
00076 void COandXTile::ConstructL(RWindow& aWindow)
00077         {
00078         SetContainerWindowL(aWindow);
00079         // No call to ActivateL() as the window is activated by its container
00080         }
00081 
00082 void COandXTile::Draw(const TRect& /*aRect*/) 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 // Status window member functions
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         // No call to ActivateL() as the window is activated by its container
00181         }
00182 
00183 void COandXStatusWin::Draw(const TRect& /*aRect*/) 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 // App View member functions
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         // empty.
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         // Create a window for this application view
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         // Set the window's size
00240         SetRect(aRect); // needs to be after component creation - see SizeChanged()
00241         // Activate the window, which makes it ready to be drawn
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(); // tile
00251         tile->SetOwnerAndObserver(this);
00252         return tile;
00253         }
00254         
00255 void COandXAppView::SizeChanged()
00256         {
00257         __ASSERT_DEBUG(iTiles[KNumberOfTiles-1], Panic(EOandXNoTiles)); // all component tiles must already exist
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& /*aRect*/) const
00300         {
00301         CWindowGc& gc = SystemGc();
00302         TRect rect = Rect();
00303         
00304         // Draw outside the border
00305         gc.SetPenStyle(CGraphicsContext::ENullPen);
00306         gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
00307         gc.SetBrushColor(KRgbWhite);
00308         DrawUtils::DrawBetweenRects(gc, rect, iBorderRect);
00309         
00310         // Draw a border around the board
00311         gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
00312         gc.SetBrushColor(KRgbGray);
00313         DrawUtils::DrawBetweenRects(gc, iBorderRect, iBoardRect);
00314         
00315         //Draw the first vertical line
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         // Draw the remaining (KTilesPerRow-2) vertical lines
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         // Draw the first horizontal line
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         // Draw the remaining (KTilesPerCol -2) horizontal lines
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: // check not in first column
00374                 if (index % KTilesPerRow)
00375                         {
00376                         MoveFocusTo(index-1);
00377                         keyResponse = EKeyWasConsumed;
00378                         }
00379                 break;
00380         case EKeyRightArrow: // check not in last column
00381                 if ((index % KTilesPerRow) < KTilesPerRow - 1)
00382                         {
00383                         MoveFocusTo(index+1);
00384                         keyResponse = EKeyWasConsumed;
00385                         }
00386                 break;
00387         case EKeyUpArrow: // check not on top row
00388                 if (index >= KTilesPerRow)
00389                         {
00390                         MoveFocusTo(index-KTilesPerRow);
00391                         keyResponse = EKeyWasConsumed;
00392                         }
00393                 break;
00394         case EKeyDownArrow: // check not in bottom row
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         }

Generated by  doxygen 1.6.2