windowing/windowserver/tlib/TLDIALOG.CPP
author Faisal Memon <faisal.memon@nokia.com>
Fri, 14 May 2010 15:41:33 +0100
branchNewGraphicsArchitecture
changeset 64 5c983aa672ea
parent 0 5d03bc08d59c
permissions -rw-r--r--
Merge 1. Pull in cpp files in the performance enhanced Khronos RI OVG files which are newly added. I've ignored platform-specific cpp files for linux, macosx, and null operating systems because this local solution has its own platform glue (i.e. facility to target Bitmaps but no full windowing support). I've ignored sfEGLInterface.cpp because this is used as a bridge to go from EGL to Nokia's Platsim which offers an EGL service. That's not relevant to this implementation because this is ARM side code, not Intel side. I just left a comment to sfEGLInterface.cpp in case we need to pick up this later on. The current code compiles on winscw. Prior to this fix, the code works on winscw, and can launch the SVG tiger (tiger.exe). That takes about 20 seconds to render. I hope to always be able to show this icon on each commit, and the plan is for the render time to reduce with this series of submissions. On this commit, the tiger renders ok in 20 seconds.

// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// Base classes used for building window server test code
// 
//

#include <e32std.h>
#include <w32std.h>
#include <e32svr.h>
#include <e32def_private.h>
#include "TLIB.H"

const TInt ButtonGap=20;
const TInt ButtonBorderGap=10;
const TInt ButtonBorderMargin=3;
const TInt TextMargin=5;
const TInt KAutoDelaySeconds=60; 

NONSHARABLE_CLASS(CTAutoKey): public CActive
	{
public:
	static CTAutoKey* NewL(RWsSession& aWs);
	~CTAutoKey();
	void Activate(TInt aDelay);
	
	void RunL();
	void DoCancel();
	
private:
	CTAutoKey(RWsSession& aWs);
	void ConstructL();	
	
	RTimer iTimer;
	TInt iDelay;
	RWsSession& iWs;
	};

EXPORT_C CTDialog::CTDialog() : CTTitledWindow(), iNumButtons(1)
	{
	iButton[0].Copy(_L("Continue"));	// Default button
	}

EXPORT_C CTDialog::~CTDialog()
	{
	if (iIsActive)
		CActiveScheduler::Stop();
	delete iAutoKey;
	}

EXPORT_C void CTDialog::ConstructLD(CTWinBase &aParent,CWindowGc &aGc)
	{
	iOldFocus=aParent.Group()->CurWin();
	TRAPD(err,CTTitledWindow::ConstructL(aParent));
	if (err!=KErrNone)
		{
		delete this;
		User::Leave(err);
		}
	iActivated=ETrue;
	iWin.SetBackgroundColor(TRgb::Gray256(238));	// Light gray
	AssignGC(aGc);
	iWin.SetPointerCapture(ETrue);
	Group()->SetCurrentWindow(this, ETrue);
	iAutoKey=CTAutoKey::NewL(Client()->iWs);
	}

EXPORT_C void CTDialog::RelinquishFocus()
	{
	Group()->SetCurrentWindow(iOldFocus);
	}

EXPORT_C TInt CTDialog::Display()
	{
	TInt result;

	SetWindowSize();
	if (iWinActive)
		BaseWin()->SetVisible(ETrue);
	else
		{
		Activate();
		iWinActive=ETrue;
		}
	if (iTakeFocus)
		Group()->SetCurrentWindow(this);
	Group()->GroupWin()->SetOrdinalPosition(0);
	iResultPtr=&result;
	CTClient *client=Client();
	if (client->QueueRead())
		{
		client->iWs.Flush();
		client=NULL;
		}
	iIsActive=ETrue;
	iAutoKey->Activate(KAutoDelaySeconds);
	CActiveScheduler::Start();
	if (client)
		client->CancelRead();
	return(result);
	}

EXPORT_C void CTDialog::SetFlags(TUint aFlags)
	{
	iFlags=aFlags;
	}

void CTDialog::SetMaxWid(TInt &aMax, TInt aWid)
	{
	if (aWid>aMax)
		aMax=aWid;
	}

EXPORT_C void CTDialog::SetWindowSize()
	{
	if (iActivated)
		{
		TInt max=0;
		SetMaxWid(max,iFont->TextWidthInPixels(iTitle));
		SetMaxWid(max,iFont->TextWidthInPixels(iLine1));
		SetMaxWid(max,iFont->TextWidthInPixels(iLine2));
		max+=TextMargin*2;
		iButWid=0;
		if (iNumButtons>0)
			{
			for(TInt index=0;index<iNumButtons;index++)
				SetMaxWid(iButWid,iFont->TextWidthInPixels(iButton[index]));
			iButWid+=ButtonBorderMargin*2;
			SetMaxWid(max,iButWid*iNumButtons+ButtonGap*(iNumButtons-1)+ButtonBorderGap*2);
			}
		TSize parSize=Parent()->Size();
		TSize size(max,iFont->HeightInPixels()*8);
		TPoint pos((parSize.iWidth-size.iWidth)/2,(parSize.iHeight-size.iHeight)/2);
		if (iFlags&EDialogDisplayAtBottom)
			pos.iY*=2;
		if (iFlags&EDialogDisplayAtLeft)
			pos.iX=0;
		SetExt(pos,size);
		Invalidate();
		}
	}

EXPORT_C void CTDialog::SetLine1(const TDesC &aLine1)
	{
	iLine1.Copy(aLine1);
	}

EXPORT_C void CTDialog::SetLine2(const TDesC &aLine2)
	{
	iLine2.Copy(aLine2);
	}

EXPORT_C void CTDialog::SetNumButtons(TInt aNum)
	{
	if ((TUint)aNum>3)
		TbPanic(EDialogButtonCount);
	iNumButtons=aNum;
	}

EXPORT_C void CTDialog::SetButtonText(TInt aNum,const TDesC &aButton)
	{
	if ((TUint)aNum>(TUint)iNumButtons)
		TbPanic(EDialogButtonIndex);
	iButton[aNum].Copy(aButton);
	}

TRect CTDialog::ButtonRect(TInt aIndex) const
	{
	TInt chunk=(iSize.iWidth-ButtonBorderMargin*2)/iNumButtons;
	TInt midPos=ButtonBorderMargin+chunk*aIndex+chunk/2;
	return(TRect(midPos-iButWid/2,iFont->HeightInPixels()*6,midPos+iButWid/2,iFont->HeightInPixels()*7+ButtonBorderMargin*2));
	}

EXPORT_C void CTDialog::Draw()
	{
	CTTitledWindow::Draw();
	iGc->SetPenColor(TRgb::Gray16(0));
	iGc->DrawText(iLine1, TPoint((iSize.iWidth-iFont->TextWidthInPixels(iLine1))/2,iFont->HeightInPixels()*3));
	iGc->DrawText(iLine2, TPoint((iSize.iWidth-iFont->TextWidthInPixels(iLine2))/2,iFont->HeightInPixels()*4+2));
	if (iNumButtons!=0)
		{
		for(TInt index=0;index<iNumButtons;index++)
			{
			TRect rect=ButtonRect(index);
			iGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
			iGc->SetBrushColor(TRgb::Gray256(255));
			iGc->DrawRect(rect);
			iGc->DrawRect(rect);
			iGc->SetBrushStyle(CGraphicsContext::ENullBrush);
			TInt midPos=(rect.iTl.iX+rect.iBr.iX)/2;
			iGc->DrawText(iButton[index], TPoint((midPos-iFont->TextWidthInPixels(iButton[index])/2),
									iFont->HeightInPixels()*6+iFont->AscentInPixels()+ButtonBorderMargin));
			}
		}
	}

EXPORT_C void CTDialog::WinKeyL(const TKeyEvent &aKey,const TTime&)
	{
	switch(aKey.iCode)
		{
		case EKeyEscape:
		case '0':
			ButtonPressL(0);
			break;
		case EKeyEnter:
		case '1':
			ButtonPressL(iNumButtons>1 ? 1 : 0);	// Same as ESC on a single button dialog
			break;
		case ' ':
		case '2':
			ButtonPressL(2);
			break;
		}
	}

EXPORT_C void CTDialog::PointerL(const TPointerEvent &aPointer,const TTime &aTime)
	{
	if (aPointer.iType==TPointerEvent::EButton1Up)
		{
		if (iButtonClickOn>0)
			{
			ButtonPressL(iButtonClickOn-1);
			return;
			}
		}
	else if (aPointer.iType==TPointerEvent::EButton1Down)
		{
		for(TInt index=0;index<iNumButtons;index++)
			if (ButtonRect(index).Contains(aPointer.iPosition))
				{
				if (iFlags&EDialogWaitForButtonUp)
					iButtonClickOn=index+1;
				else
					{
					ButtonPressL(index);
					return;
					}
				}
		}
	CTTitledWindow::PointerL(aPointer, aTime);
	}

EXPORT_C void CTDialog::ButtonPressL(TInt aButton)
	{
	if (aButton<iNumButtons)
		{
		SetResult(aButton);
		CTTitledWindow::Delete(this);
		}
	}

void CTDialog::SetResult(TInt aButton)
	{
	if (iResultPtr)
		*iResultPtr=aButton;
	}

// Simple display dialog //

class CDisplayDialog : public CTDialog
	{		  
public:
	CDisplayDialog(CTWindowGroup *aGroupWin,CWindowGc *aGc);
	void ConstructLD();
private:
	CTWindowGroup *iGroupWin;
	CWindowGc *iGc;
	};

CDisplayDialog::CDisplayDialog(CTWindowGroup *aGroupWin,CWindowGc *aGc) : CTDialog(),
	iGroupWin(aGroupWin),
	iGc(aGc)
	{
	}

void CDisplayDialog::ConstructLD()
	{
	CTDialog::ConstructLD(*iGroupWin, *iGc);
	}

EXPORT_C void DisplayDialog(CTClient *aClient, const TWindowTitle &aTitle, const TDesC &aLine1, const TDesC &aLine2)
	{
	CDisplayDialog *dialog=NULL;
	dialog=new(ELeave) CDisplayDialog(aClient->iGroup, aClient->iGc);
	TRAPD(err,dialog->ConstructLD());
	if (err==KErrNone)
		{
		dialog->SetTitle(aTitle);
		dialog->SetLine1(aLine1);
		dialog->SetLine2(aLine2);
		dialog->SetNumButtons(1);
		dialog->SetButtonText(0,_L("Okay"));
		if (dialog->Display()!=0)		// delete dialog
			TbPanic(EDialogDisplay);
		}
	}

void doDisplayDialog(TInt aScreenNumber,const TWindowTitle &aTitle, const TDesC &aLine1, const TDesC &aLine2, CTClient *&aClient, const RWindowGroup *aGroup)
	{
	aClient=new(ELeave) CTClient();
	aClient->SetScreenNumber(aScreenNumber);
	aClient->ConstructL();
//
	aClient->iGroup=new(ELeave) CTWindowGroup(aClient);
	aClient->iGroup->ConstructL();
	aClient->iGroup->GroupWin()->SetOrdinalPosition(0,10);
	if (aGroup)
		aClient->iGroup->GroupWin()->SetOwningWindowGroup(aGroup->Identifier());
//
	TRAP_IGNORE(DisplayDialog(aClient, aTitle, aLine1, aLine2));
	}

void doDisplayDialog(const TWindowTitle &aTitle, const TDesC &aLine1, const TDesC &aLine2, CTClient *&aClient, const RWindowGroup *aGroup)
	{
	doDisplayDialog(KDefaultScreen,aTitle,aLine1,aLine2,aClient,aGroup);
	}

EXPORT_C void DisplayDialog(TInt aScreenNumber,const TWindowTitle &aTitle, const TDesC &aLine1, const TDesC &aLine2, const RWindowGroup *aGroup)
	{
	CTClient *client=NULL;
	TRAP_IGNORE(doDisplayDialog(aScreenNumber,aTitle,aLine1,aLine2,client,aGroup));
	delete client;
	}

EXPORT_C void DisplayDialog(const TWindowTitle &aTitle, const TDesC &aLine1, const TDesC &aLine2, const RWindowGroup *aGroup)
	{
	DisplayDialog(KDefaultScreen,aTitle,aLine1,aLine2,aGroup);
	}



//CInfoDialog

EXPORT_C CInfoDialog::CInfoDialog(CTWindowGroup *aGroupWin,CWindowGc *aGc) :CTDialog(), iGroupWin(aGroupWin), iGc(aGc)
	{}

EXPORT_C void CInfoDialog::ButtonPressL(TInt aButton)
	{
	if (aButton==0)
		{
		SetResult(0);
		BaseWin()->SetVisible(EFalse);
		CActiveScheduler::Stop();
		}
	}

EXPORT_C void CInfoDialog::ConstructLD()
	{
	_LIT(OK,"Okay");
	CTDialog::ConstructLD(*iGroupWin, *iGc);
	SetNumButtons(1);
	SetButtonText(0,OK);
	SetTakeFocus();
	}

EXPORT_C void CInfoDialog::TimerResults()
	{
	TProfile profile[eTimes];
	// TProfile only has default constructor -
	// constructor of TProfile does not initialize its members
	for (TInt jj=0; jj<eTimes; jj++)
		{
		profile[jj].iTime=0;
		profile[jj].iCount=0;
		}
	__PROFILE_DISPLAY(eTimes)
	TBuf<64> times;
	TBuf<32> counts;
	TInt ii=1;
	FOREVER
		{
		AppendProfileTime(times,profile[ii].iTime);
		AppendProfileCount(counts,profile[ii].iCount);
		if (++ii==eTimes)
			break;
		AddComma(times);
		AddComma(counts);
		}
	SetLine1(times);
	SetLine2(counts);
	times.Zero();
	AppendProfileTime(times,profile[0].iTime);
	SetTitle(times);
	}

void CInfoDialog::AppendProfileTime(TDes &aDes, TInt aNum)
	{
	_LIT(ThreeDP,"%d.%03d");
	aDes.AppendFormat(ThreeDP,aNum/eSeconds,(aNum%eSeconds)/1000);
	}

void CInfoDialog::AppendProfileCount(TDes &aDes, TInt aNum)
	{
	_LIT(Int,"%d");
	aDes.AppendFormat(Int,aNum);
	}

void CInfoDialog::AddComma(TDes &aDes)
	{
	_LIT(Comma,", ");
	aDes.Append(Comma);
	}

CTAutoKey::CTAutoKey(RWsSession& aWs): CActive(0), iWs(aWs)
	{
	CActiveScheduler::Add(this);
	}
	
CTAutoKey::~CTAutoKey()
	{
	Cancel();
	iTimer.Close();
	}
	
void CTAutoKey::ConstructL()
	{
	User::LeaveIfError(iTimer.CreateLocal());
	}
	
CTAutoKey* CTAutoKey::NewL(RWsSession& aWs)
	{
	CTAutoKey* self=new(ELeave) CTAutoKey(aWs);
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop();
	return self;
	}
	
void CTAutoKey::Activate(TInt aDelay)
	{
	if (IsActive())
		Cancel();
	
	iDelay=aDelay*1000000;
	iTimer.After(iStatus,iDelay);
	SetActive();
	}
void CTAutoKey::RunL()
	{
	// simulate key event, only needed to run once
	TKeyEvent keyEvent;
	keyEvent.iCode=EKeyEnter;
	keyEvent.iScanCode=EKeyEnter;
	keyEvent.iModifiers=0;
	keyEvent.iRepeats=0;
	iWs.SimulateKeyEvent(keyEvent);
	iWs.Flush();
	}
	
void CTAutoKey::DoCancel()
	{
	iTimer.Cancel();
	}