/*
* Copyright (c) 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:
*
*/
// INCLUDE FILES
#include "perfmon_graphscontainer.h"
#include "perfmon.hrh"
#include "perfmon_document.h"
#include "perfmon_appui.h"
#include "perfmon_model.h"
#include <aknutils.h>
const TInt KAmountOfMicroSecondsFitsScreen = 20 * 1000000;
#define KRgbCustomGrey TRgb(0x808080)
_LIT(K100p, "100%");
_LIT(K50p, "50%");
_LIT(K0p, "0%");
_LIT(KPercentageFormat,"%S %d%%");
const TInt KMicroToSecondMultiplier = 1000000;
// ===================================== MEMBER FUNCTIONS =====================================
void CPerfMonGraphsContainer::ConstructL(const TRect& aRect)
{
iModel = static_cast<CPerfMonDocument*>(reinterpret_cast<CEikAppUi*>(iEikonEnv->AppUi())->Document())->Model();
//iFont = AknLayoutUtils::FontFromId(EAknLogicalFontPrimarySmallFont);
iFont = LatinBold12();
CreateWindowL();
SetRect(aRect);
SetBlank();
ActivateL();
}
// --------------------------------------------------------------------------------------------
CPerfMonGraphsContainer::~CPerfMonGraphsContainer()
{
}
// --------------------------------------------------------------------------------------------
void CPerfMonGraphsContainer::Draw(const TRect& aRect) const
{
// draw black background
CWindowGc& gc = SystemGc();
gc.SetBrushColor(KRgbBlack);
gc.Clear(aRect);
// activate font and get size
gc.UseFont(iFont);
TUint fontSize = iFont->FontMaxHeight();
//TInt fontBaseOffset = iFont->DescentInPixels();
// calculate time factor
TReal scaleFactor = (TReal) aRect.Width() / (TReal) KAmountOfMicroSecondsFitsScreen;
// calculate area height which is used to draw the grpahs
TInt drawAreaHeight = aRect.Height() - fontSize - fontSize;
// check if sample array has been constructed
if (iModel->SampleEntryArray())
{
// draw vertical time lines first
TInt verticalBarPeriodInSecs = iModel->Settings().iGraphsVerticalBarPeriod;
if (verticalBarPeriodInSecs >= 1 && iModel->SampleEntryArray()->At(0).iSampleDataArray->Count() > 0)
{
// get time from the first sample
TSampleData& firstSample = iModel->SampleEntryArray()->At(0).iSampleDataArray->At(0);
TInt64 currentMicroSeconds = firstSample.iTimeFromStart.Int64();
// calculate amount of microseconds exceeding value by using the modulo operator
TInt remainderInMicroSeconds = currentMicroSeconds % (verticalBarPeriodInSecs * 1000000);
// calculate first x pos
TInt vbarXpos = aRect.Width() - (remainderInMicroSeconds * scaleFactor);
// calculate the amount in seconds
TInt barSeconds = (currentMicroSeconds - remainderInMicroSeconds) / KMicroToSecondMultiplier;
// continue drawing periodically the vertical lines
while (vbarXpos >= 0 && barSeconds >= 0)
{
// draw vertical line
gc.SetPenColor(KRgbDarkRed);
gc.DrawLine(TPoint(vbarXpos,fontSize+1), TPoint(vbarXpos,aRect.Height()-fontSize));
// draw seconds value
gc.SetPenColor(KRgbCustomGrey);
TBuf<16> secsBuf;
secsBuf.AppendNum(barSeconds);
secsBuf.Append(_L("s"));
gc.DrawText(secsBuf, TPoint(vbarXpos-(iFont->TextWidthInPixels(secsBuf)/2), aRect.Height()));
// calculate new position
vbarXpos -= verticalBarPeriodInSecs * 1000000 * scaleFactor;
barSeconds -= verticalBarPeriodInSecs;
}
}
// draw the basic grid
gc.SetPenColor(KRgbCustomGrey);
gc.DrawLine(TPoint(0,fontSize), TPoint(aRect.Width(),fontSize)); // upper line
gc.DrawText(K100p, TPoint(0,fontSize));
gc.DrawLine(TPoint(0,aRect.Height()/2), TPoint(aRect.Width(),aRect.Height()/2)); // mid line
gc.DrawText(K50p, TPoint(0,aRect.Height()/2));
gc.DrawLine(TPoint(0,aRect.Height()-fontSize), TPoint(aRect.Width(),aRect.Height()-fontSize)); // bottom line
gc.DrawText(K0p, TPoint(0,aRect.Height()-fontSize));
TInt c(0);
// draw graphs for each sampled type
for (TInt i=0; i<iModel->SampleEntryArray()->Count(); i++)
{
// check if this setting has been enabled and it has some data
if (iModel->Settings().iGraphsSources.iSrcEnabled[i] && iModel->SampleEntryArray()->At(i).iSampleDataArray->Count() > 0)
{
// set pen color for the graph
gc.SetPenColor(iModel->SampleEntryArray()->At(i).iGraphColor);
// remember the position where drawing started
/*TReal*/TInt currentXPos(aRect.Width()); // start drawing from right
/*TReal*/TInt currentYPos(0);
// draw samples
for (TInt j=0; j<iModel->SampleEntryArray()->At(i).iSampleDataArray->Count() - 1; j++)
{
TSampleData& currentSample = iModel->SampleEntryArray()->At(i).iSampleDataArray->At(j);
TSampleData& previousSample = iModel->SampleEntryArray()->At(i).iSampleDataArray->At(j+1);
// calculate X position for previous (j+1)
/*TReal*/TInt previousXPos = currentXPos -
( (Abs(previousSample.iTimeFromStart.Int64() - currentSample.iTimeFromStart.Int64())) * scaleFactor );
// calculate initial Y position
if (j==0)
{
currentYPos = currentSample.iSize > 0 ? (TReal)(currentSample.iFree) / (TReal)currentSample.iSize * drawAreaHeight + fontSize : aRect.Height()-fontSize;
}
// calculate Y position for previous (j+1)
/*TReal*/TInt previousYPos = previousSample.iSize > 0 ? (TReal)(previousSample.iFree) / (TReal)previousSample.iSize * drawAreaHeight + fontSize : aRect.Height()-fontSize;
// draw a line between the previous and current
gc.DrawLine(TPoint((TInt)previousXPos,(TInt)previousYPos), TPoint((TInt)currentXPos,(TInt)currentYPos));
// draw current value in %
if (j==0) // draw the value of first sample
{
TBuf<16> buf;
buf.Format(KPercentageFormat, &iModel->SampleEntryArray()->At(i).iDescription, currentSample.iSize > 0 ? TInt( (1 - ((TReal)(currentSample.iFree) / (TReal)currentSample.iSize)) * 100) : 0 );
gc.DrawText(buf, TPoint(0,fontSize+fontSize+c*fontSize));
c++;
}
// stop drawing if we have run out of space
if (previousXPos < 0)
break;
// remeber previous values
currentXPos = previousXPos;
currentYPos = previousYPos;
}
}
}
}
gc.DiscardFont();
}
// --------------------------------------------------------------------------------------------
TKeyResponse CPerfMonGraphsContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
{
return CCoeControl::OfferKeyEventL(aKeyEvent, aType);
}
// --------------------------------------------------------------------------------------------
void CPerfMonGraphsContainer::HandleResourceChange(TInt aType)
{
if (aType == KEikDynamicLayoutVariantSwitch)
{
TRect mainPaneRect;
AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, mainPaneRect);
SetRect(mainPaneRect);
}
else
CCoeControl::HandleResourceChange(aType);
}
// --------------------------------------------------------------------------------------------
void CPerfMonGraphsContainer::DrawUpdate()
{
DrawDeferred();
}
// --------------------------------------------------------------------------------------------
// End of File