⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oandxappview.cpp

📁 Symbian OS C++ for Mobile Phones v3 Example Code
💻 CPP
字号:
// Copyright (c) 2004 - 2006, Symbian Software Ltd. All rights reserved.

#include <coemain.h>
#include <gulutil.h>
#include <e32keys.h>


#include "OandXAppView.h"
#include "OandXAppUi.h"
#include "OandXController.h"
#include "OandXEngine.h"
#include "OandX.pan"
#include "oandxdefs.h"


// O and X symbol-drawing control member functions

void COandXSymbolControl::DrawSymbol(CWindowGc& aGc, const TRect& aRect, TBool aDrawCross) const
	{
	TRect drawRect(aRect);
	
	// Shrink by about 15%
	drawRect.Shrink(aRect.Width()/6,aRect.Height()/6); 
	
    // Pen size set to just over 10% of the overall shape's size
	TSize penSize(aRect.Width()/9,aRect.Height()/9);
	aGc.SetPenSize(penSize);
	aGc.SetPenStyle(CGraphicsContext::ESolidPen);
	
	if (aDrawCross)
		{
		aGc.SetPenColor(KRgbGreen);
		
		// Cosmetic reduction of cross size by half the line width
		drawRect.Shrink(penSize.iWidth/2,penSize.iHeight/2);
		
		aGc.DrawLine(drawRect.iTl, drawRect.iBr);
		TInt temp;
		temp = drawRect.iTl.iX;
		drawRect.iTl.iX = drawRect.iBr.iX;
		drawRect.iBr.iX = temp;
		aGc.DrawLine(drawRect.iTl, drawRect.iBr);
		}
	else // draw a circle
		{
		aGc.SetPenColor(KRgbRed);
		aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
		aGc.DrawEllipse(drawRect);
		}
	};

// 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
	{
	TTileState tileType;
	tileType = iCmdHandler->TileStatus(this);

	CWindowGc& gc = SystemGc();
	TRect rect = Rect();
	
	if (IsFocused())
		{
		gc.SetBrushColor(KRgbYellow);
		}
	gc.Clear(rect);
	if (tileType!=ETileBlank)
		{
		DrawSymbol(gc, rect, tileType==ETileCross);
		}
	}

void  COandXTile::SetOwnerAndObserver(COandXAppView* aControl)
	{
	iCmdHandler = aControl;
	SetObserver(aControl);
	}

void COandXTile::TryHitL()
	{
	if (iCmdHandler->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();
		}
	}


// Status window member functions

COandXStatusWin* COandXStatusWin::NewL(RWindow& aWindow)
	{
	COandXStatusWin* self=new(ELeave) COandXStatusWin;
	CleanupStack::PushL(self);
	self->ConstructL(aWindow);
	CleanupStack::Pop();
	self->SetFocusing(EFalse);
	return self;
	}

COandXStatusWin::COandXStatusWin()
	{
	}
	
COandXStatusWin::~COandXStatusWin()
	{
	}
	
void COandXStatusWin::ConstructL(RWindow& aWindow)
	{
	SetContainerWindowL(aWindow);
	// No call to ActivateL() as the window is activated by its container
	}

void COandXStatusWin::Draw(const TRect& /*aRect*/) const
	{
	CWindowGc& gc = SystemGc();
	TRect boxRect = Rect();
	gc.Clear(boxRect);
	TInt boxHeight = boxRect.iBr.iY - boxRect.iTl.iY;
	boxRect.iTl.iX = boxRect.iBr.iX - boxHeight;
	DrawSymbol(gc, boxRect, Controller().IsCrossTurn());
	}


// App View member functions

#define KBorderWidth 10
#define KLineWidth ((KTilesPerRow > KTilesPerCol ? KTilesPerRow : KTilesPerCol) > 4 ? 2 : 4)


COandXAppView* COandXAppView::NewL(const TRect& aRect)
	{
	COandXAppView* self = new(ELeave) COandXAppView;
	CleanupStack::PushL(self);
	self->ConstructL(aRect);
	CleanupStack::Pop(self);
	return self;
	}

COandXAppView::COandXAppView()
/**
	
 */
	{
	// empty.
	}

COandXAppView::~COandXAppView()
	{
	for (TInt i=0; i<KNumberOfTiles; i++)
		{
		delete iTiles[i];
		}
	iTiles.Close();
	delete iStatusWin;
	}

void COandXAppView::ConstructL(const TRect& aRect)
	{
	// Create a window for this application view
	CreateWindowL();

	for (TInt i = 0; i < KNumberOfTiles; i++)
		{
		User::LeaveIfError(iTiles.Append(CreateTileL()));
		}
	ComponentControl(0)->SetFocus(ETrue);
	iStatusWin = COandXStatusWin::NewL(Window());

	// Set the window's size
	SetRect(aRect); // needs to be after component 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

	TRect rect = Rect();
	rect.iTl.iY = rect.iBr.iY - KStatusWinHeight;
	iStatusWin->SetRect(rect);
	rect = Rect();
	rect.iBr.iY -= KStatusWinHeight;
	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<KNumberOfTiles; 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);
	// Draw the remaining (KTilesPerRow-2) vertical lines
	for (TInt 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 (TInt 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 +1;
	}

CCoeControl* COandXAppView::ComponentControl(TInt aIndex) const
	{
	if (aIndex==KNumberOfTiles)
		{
		return iStatusWin;
		}
	else
		{
		return const_cast<COandXTile*>(iTiles[aIndex]);
		}
	}

TKeyResponse COandXAppView::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
	{
	TKeyResponse keyResponse = EKeyWasNotConsumed;
	if (aType!=EEventKey)
		{
		return keyResponse;
		}
	TInt index = IdOfFocusControl();
	switch (aKeyEvent.iCode)
		{
	case EKeyLeftArrow: // check not in first column
		if (index % KTilesPerRow)
			{
			MoveFocusTo(index-1);
			keyResponse = EKeyWasConsumed;
			}
		break;
	case EKeyRightArrow: // check not in last column
		if ((index % KTilesPerRow) < KTilesPerRow - 1)
			{
			MoveFocusTo(index+1);
			keyResponse = EKeyWasConsumed;
			}
		break;
	case EKeyUpArrow: // check not on top row
		if (index >= KTilesPerRow)
			{
			MoveFocusTo(index-KTilesPerRow);
			keyResponse = EKeyWasConsumed;
			}
		break;
	case EKeyDownArrow: // check not in bottom row
		if (index < KNumberOfTiles - KTilesPerRow)
			{
			MoveFocusTo(index+KTilesPerRow);
			keyResponse = EKeyWasConsumed;
			}
		break;
	default:
		keyResponse = ComponentControl(index)->OfferKeyEventL(aKeyEvent,aType);
		break;
		}
	return keyResponse;
	}

TInt COandXAppView::IdOfFocusControl()
	{
	TInt ret = -1;
	for (TInt i=0; i<KNumberOfTiles; i++)
		{
		if (ComponentControl(i)->IsFocused())
			{
			ret = i;
			break;
			}
		}
	__ASSERT_ALWAYS(ret>=0, Panic(EOandXNoTileWithFocus));
	return ret;
	}
	
void COandXAppView::SwitchFocus(TInt aFromIndex, CCoeControl* aToControl)
	{
	ComponentControl(aFromIndex)->SetFocus(EFalse, EDrawNow);
	aToControl->SetFocus(ETrue, EDrawNow);
	}
	
void COandXAppView::MoveFocusTo(const TInt index)
	{
	TInt oldIndex = IdOfFocusControl();
	if (index!= oldIndex)
		{
		SwitchFocus(oldIndex, ComponentControl(index));
		}
	}


void COandXAppView::HandleControlEventL(CCoeControl* aControl, TCoeEvent aEventType)
	{
	switch (aEventType)
		{
	case EEventRequestFocus:
		SwitchFocus(IdOfFocusControl(), aControl);
		break;
	default:
		break;
		}
	}

TBool COandXAppView::TryHitSquareL(const COandXTile* aControl)
	{
	return Controller().HitSquareL(Index(aControl));
	}

TTileState COandXAppView::TileStatus(const COandXTile* aControl) const
	{
	return Engine().TileStatus(Index(aControl));
	}

void COandXAppView::ShowTurn()
	{
	iStatusWin->DrawDeferred();
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -