// Copyright (c) 2004, Symbian Software Ltd. All rights reserved.
#include <coemain.h>
#include <gulutil.h>
#include <e32keys.h>
#include "OandXAppView.h"
#include "OandXAppUi.h"
#include "OandX.pan"
#include "oandxdefs.h"
// Tile member functions
COandXTile::COandXTile()
{
}
COandXTile::~COandXTile()
{
}
void COandXTile::ConstructL(RWindow& aWindow)
{
SetContainerWindowL(aWindow);
// No call to ActivateL() as the window is activated by its container
}
void COandXTile::Draw(const TRect& /*aRect*/) const
{
TInt tileType;
tileType = iAppView->SquareStatus(this);
CWindowGc& gc = SystemGc();
TRect rect = Rect();
if (IsFocused())
{
gc.SetBrushColor(KRgbYellow);
}
gc.Clear(rect);
if (tileType!=ETileBlank)
{
TSize size;
size.SetSize(rect.iBr.iX- rect.iTl.iX, rect.iBr.iY - rect.iTl.iY);
rect.Shrink(size.iWidth/6,size.iHeight/6); // Shrink by about 15%
gc.SetPenStyle(CGraphicsContext::ESolidPen);
size.iWidth /=5; // Pen size set to just over 10% of the shape's size
size.iHeight /= 5;
gc.SetPenSize(size);
if (tileType == ETileNought)
{
gc.SetPenColor(KRgbRed);
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
gc.DrawEllipse(rect);
}
else // draw a cross
{
gc.SetPenColor(KRgbGreen);
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
rect.Shrink(size.iWidth/2,size.iHeight/2); // Cosmetic reduction of cross size by half the line width
gc.DrawLine(rect.iTl, rect.iBr);
TInt temp;
temp = rect.iTl.iX;
rect.iTl.iX = rect.iBr.iX;
rect.iBr.iX = temp;
gc.DrawLine(rect.iTl, rect.iBr);
}
}
}
void COandXTile::SetOwnerAndObserver(COandXAppView* aControl)
{
iAppView = aControl;
SetObserver(aControl);
}
void COandXTile::TryHitL()
{
if (iAppView->TryHitSquareL(this))
{
DrawDeferred();
}
}
TKeyResponse COandXTile::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
TKeyResponse keyResponse = EKeyWasNotConsumed;
if (aType!=EEventKey)
{
return keyResponse;
}
switch (aKeyEvent.iCode)
{
case EKeyOK:
TryHitL();
keyResponse = EKeyWasConsumed;
break;
default:
keyResponse = EKeyWasNotConsumed;
break;
}
return keyResponse;
}
TCoeInputCapabilities COandXTile::InputCapabilities() const
{
return TCoeInputCapabilities::ENavigation;
}
void COandXTile::HandlePointerEventL(const TPointerEvent& aPointerEvent)
{
if (aPointerEvent.iType == TPointerEvent::EButton1Down)
{
TryHitL();
}
}
void COandXTile::FocusChanged(TDrawNow aDrawNow)
{
if (aDrawNow == EDrawNow)
{
DrawNow();
}
}
// App View member functions
#define KBorderWidth 10
#define KLineWidth ((KTilesPerRow > KTilesPerCol ? KTilesPerRow : KTilesPerCol) > 4 ? 2 : 4)
COandXAppView::COandXAppView()
{
}
COandXAppView::~COandXAppView()
{
for (TInt i=0; i<CountComponentControls(); i++)
{
delete iTiles[i];
}
iTiles.Close();
}
void COandXAppView::ConstructL(const TRect& aRect, MOandXGameControl* aGameControl)
{
// Create a window for this application view
CreateWindowL();
iGameControl = aGameControl;
for (TInt i = 0; i < CountComponentControls(); i++)
{
User::LeaveIfError(iTiles.Append(CreateTileL()));
}
ComponentControl(0)->SetFocus(ETrue);
// Set the window's size
SetRect(aRect); // needs to be after tile creation - see SizeChanged()
// Activate the window, which makes it ready to be drawn
ActivateL();
}
COandXTile* COandXAppView::CreateTileL()
{
COandXTile * tile = new(ELeave) COandXTile;
CleanupStack::PushL(tile);
tile->ConstructL(Window());
CleanupStack::Pop(); // tile
tile->SetOwnerAndObserver(this);
return tile;
}
void COandXAppView::SizeChanged()
{
__ASSERT_DEBUG(iTiles[KNumberOfTiles-1], Panic(EOandXNoTiles)); // all component tiles must already exist
TSize controlSize = Rect().Size();
TSize tileSize;
tileSize.iWidth=2*((controlSize.iWidth-2*KBorderWidth-(KTilesPerRow-1)*KLineWidth)/(2*KTilesPerRow));
tileSize.iHeight=2*((controlSize.iHeight-2*KBorderWidth-(KTilesPerCol-1)*KLineWidth)/(2*KTilesPerCol));
iTileSide = tileSize.iWidth < tileSize.iHeight ? tileSize.iWidth :tileSize.iHeight;
TSize boardSize;
boardSize.iWidth = KTilesPerRow*iTileSide + (KTilesPerRow-1)*KLineWidth;
boardSize.iHeight = KTilesPerCol*iTileSide + (KTilesPerCol-1)*KLineWidth;
iBoardRect.iTl.iX = (controlSize.iWidth - boardSize.iWidth)/2;
iBoardRect.iTl.iY = (controlSize.iHeight - boardSize.iHeight)/2;
iBoardRect.iBr.iX = iBoardRect.iTl.iX + boardSize.iWidth;
iBoardRect.iBr.iY = iBoardRect.iTl.iY + boardSize.iHeight;
iBorderRect = iBoardRect;
iBorderRect.Grow(KBorderWidth,KBorderWidth);
for (TInt i=0; i<CountComponentControls(); i++)
{
TInt row = i / KTilesPerRow;
TInt col = i % KTilesPerRow;
TRect tileRect;
tileRect.iTl.iX = iBoardRect.iTl.iX + col * (iTileSide + KLineWidth);
tileRect.iTl.iY = iBoardRect.iTl.iY + row * (iTileSide + KLineWidth);
tileRect.iBr.iX = tileRect.iTl.iX + iTileSide;
tileRect.iBr.iY = tileRect.iTl.iY + iTileSide;
ComponentControl(i)->SetRect(tileRect);
}
}
void COandXAppView::ResetView()
{
MoveFocusTo(0);
DrawNow();
}
void COandXAppView::Draw(const TRect& /*aRect*/) const
{
CWindowGc& gc = SystemGc();
TRect rect = Rect();
// Draw outside the border
gc.SetPenStyle(CGraphicsContext::ENullPen);
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
gc.SetBrushColor(KRgbWhite);
DrawUtils::DrawBetweenRects(gc, rect, iBorderRect);
// Draw a border around the board
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
gc.SetBrushColor(KRgbGray);
DrawUtils::DrawBetweenRects(gc, iBorderRect, iBoardRect);
//Draw the first vertical line
gc.SetBrushColor(KRgbBlack);
TRect line;
line.iTl.iX = iBoardRect.iTl.iX + iTileSide;
line.iTl.iY = iBoardRect.iTl.iY;
line.iBr.iX = line.iTl.iX + KLineWidth;
line.iBr.iY = iBoardRect.iBr.iY;
gc.DrawRect(line);
TInt i;
// Draw the remaining (KTilesPerRow-2) vertical lines
for (i = 0; i < KTilesPerRow - 2; i++)
{
line .iTl.iX += iTileSide + KLineWidth;
line .iBr.iX += iTileSide + KLineWidth;
gc.DrawRect(line);
}
// Draw the first horizontal line
line.iTl.iX = iBoardRect.iTl.iX;
line.iTl.iY = iBoardRect.iTl.iY + iTileSide;
line.iBr.iX = iBoardRect.iBr.iX;
line.iBr.iY = line.iTl.iY + KLineWidth;
gc.DrawRect(line);
// Draw the remaining (KTilesPerCol -2) horizontal lines
for (i = 0; i < KTilesPerCol - 2; i++)
{
line .iTl.iY += iTileSide + KLineWidth;
line .iBr.iY += iTileSide + KLineWidth;
gc.DrawRect(line);
}
}
TInt COandXAppView::CountComponentControls() const
{
return KNumberOfTiles;
}
CCoeControl* COandXAppView::ComponentControl(TInt aIndex) const
{
return const_cast<COandXTile*>(iTiles[aIndex]);
}
TKeyResponse COandXAppView::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
TKeyResponse keyResponse = EKeyWasNotConsume