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

📄 statusoverlay.cpp

📁 SYMBIAN GPS NMEA协议实现
💻 CPP
字号:
/************************************************************************/
/* Bluetooth Test      			The.Berlin.Factor   		April 2003	*/
/************************************************************************/

#include <CoeCntrl.h>
#include <EikEnv.h>

#include "util/BitmapMethods.h"
#include "util/TimeOutTimer.h"

#include "ui/StatusOverlay.h"
#include "ui/UserInterface.h"



static const TInt KDefaultStatusLength = 256;



CStatusOverlay::CStatusOverlay( CCoeControl * aOwningControl, const TRect aStatusRect ) {

	iOwner = aOwningControl;
	iStatusRect = aStatusRect;
	iOffScreenRect.SetSize( aStatusRect.Size( ) );

	iBackgroundColor = TRgb( 210, 210, 210 );
	iBorderColor = TRgb( 190, 190, 190 );
	iTextColor = TRgb( 1, 1, 1 );

	iInsets = TPoint( 4, 4 );

}



CStatusOverlay::~CStatusOverlay( ) {

	delete( iOffScreenGc ); iOffScreenGc = NULL;
	delete( iOffScreenDevice ); iOffScreenDevice = NULL;
	delete( iOffScreenBitmap ); iOffScreenBitmap = NULL;

	delete( iTimer ); iTimer = NULL;
	delete( iStatusText ); iStatusText = NULL;

	iOwner = NULL;

	iMutex.Close( );

}



CStatusOverlay * CStatusOverlay::NewL( CCoeControl * aOwningControl, const TRect aStatusRect ) {

	CStatusOverlay * self = new ( ELeave ) CStatusOverlay( aOwningControl, aStatusRect );
	CleanupStack::PushL( self );
	self->ConstructL( );
	CleanupStack::Pop( self );

	return( self );

}



void CStatusOverlay::ConstructL( ) {

	User::LeaveIfError( iMutex.CreateLocal( ) );

	iStatusText = HBufC::NewL( KDefaultStatusLength );
	iTimer = CTimeOutTimer::NewL( EPriorityNormal, *this );

	TDisplayMode mode = CUserInterface::DisplayMode( );

	// Bitmap fuer das OffScreen Zeichnen erzeugen.
	iOffScreenBitmap = NBitmapMethods::CreateBitmapL( iStatusRect.Size( ), mode );
	iOffScreenDevice = NBitmapMethods::CreateBitmapDeviceL( *iOffScreenBitmap );
	iOffScreenGc = NBitmapMethods::CreateGraphicsContextL( *iOffScreenDevice );

}



void CStatusOverlay::SetStatus( const TDesC16 & aMessage, TBool aFadeOut ) {

	iTimer->Cancel( );

	iMutex.Wait( );

	// Neuen Text uebernehmen und OffScreen Bitmap damit neu zeichnen.

	TPtr16 status = iStatusText->Des( );

	status.SetLength( 0 );
	for ( TInt idx = 0; idx < aMessage.Length( ); idx++ )
		if ( idx < status.MaxLength( ) )
			status.Append( aMessage[ idx ] );

	UpdateOffScreenBitmap( );

	iDisplayState = EShowStatus;

	// Timer fuer das Ausblenden der Statusmeldung starten.
	if ( aFadeOut )
		iTimer->After( 2 * 1000 * 1000 ); // 2 Sekunden anzeigen

	iMutex.Signal( );

	// Jetzt die Statusmeldung ueber den Umweg der Komponente neu
	// zeichnen.
	iOwner->DrawDeferred( );

}



void CStatusOverlay::SetStatus( const TDesC8 & aMessage, TBool aFadeOut ) {

	iTimer->Cancel( );

	iMutex.Wait( );

	// Neuen Text uebernehmen und OffScreen Bitmap damit neu zeichnen.

	TPtr16 status = iStatusText->Des( );

	status.SetLength( 0 );
	for ( TInt idx = 0; idx < aMessage.Length( ); idx++ )
		if ( idx < status.MaxLength( ) )
			status.Append( aMessage[ idx ] );

	UpdateOffScreenBitmap( );

	iDisplayState = EShowStatus;

	// Timer fuer das Ausblenden der Statusmeldung starten.
	if ( aFadeOut )
		iTimer->After( 2 * 1000 * 1000 ); // 2 Sekunden anzeigen

	iMutex.Signal( );

	// Jetzt die Statusmeldung ueber den Umweg der Komponente neu
	// zeichnen.
	iOwner->DrawDeferred( );

}



void CStatusOverlay::SetStatusL( TInt aTextResourceId, TBool aFadeOut ) {

	HBufC * text = CEikonEnv::Static( )->AllocReadResourceL( aTextResourceId );
	SetStatus( *text, aFadeOut );
	delete( text );

}



void CStatusOverlay::DrawInto( CWindowGc & aGc ) {

	if ( iDisplayState == EDoNotDisplay || iMutex.IsBlocked( ) )
		return;

	iMutex.Wait( );

	TRect destination( iStatusRect );
	destination.SetHeight( iOffScreenRect.Height( ) );

	aGc.DrawBitmap( destination, iOffScreenBitmap, iOffScreenRect );

	iMutex.Signal( );

}



void CStatusOverlay::TimerExpired( ) {

	switch ( iDisplayState ) {

		case EDoNotDisplay:

			// Was geht hier?
			break;

		case EShowStatus:

			// Nach dem der Status eine Zeit lang gezeigt wurde, langsam
			// ausblenden.
			iDisplayState = EDoNotDisplay;
			break;
	}

	iOwner->DrawDeferred( );

}


void CStatusOverlay::UpdateOffScreenBitmap( ) {

	CFbsBitGc & gc = *iOffScreenGc;

	// Zunaechst die komplette Bitmap loeschen. Das ist wichtig, damit die
	// leeren Teile der Bitmap korrekt ausmaskiert werden koennen.
	gc.Clear( );

	// Schrift initialisieren.
	const CFont * font = CEikonEnv::Static( )->DenseFont( );
	gc.UseFont( font );

	// Bereich fuer den Text bestimmen.
	TRect textRect;
	textRect.SetSize( iStatusRect.Size( ) );
	textRect.Shrink( iInsets.iX, iInsets.iY );

	// Anzahl der Zeilen bestimmen.
	TInt lines = DrawText( font, textRect, EFalse );

	// Jetzt den tatsaechlich benoetigten Bereich der Bitmap bestimmen..
	iOffScreenRect.SetHeight( font->HeightInPixels( ) * lines + iInsets.iY * 2 );

	// ..und mit der Hintergrundfarbe fuellen.
	gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
	gc.SetBrushColor( iBackgroundColor );
	gc.SetPenColor( iBorderColor );
	gc.SetDrawMode( CGraphicsContext::EDrawModePEN );
	gc.DrawRect( iOffScreenRect );

	// Gc zuruecksetzen.
	gc.SetBrushStyle( CGraphicsContext::ENullBrush );
	gc.SetPenColor( iTextColor );
	gc.SetDrawMode( CGraphicsContext::EDrawModePEN );

	// Text zeichnen.
	DrawText( font, textRect );

	// Schrift freigeben.
	gc.DiscardFont( );

}



TInt CStatusOverlay::DrawText( const CFont * aFont, const TRect & aRect, TBool aReallyDrawFlag ) {

	if ( aRect.Width( ) == 0 || aRect.Height( ) == 0 )
		return( 0 );

	TInt verticalPos = aFont->AscentInPixels( );
	TInt fontHeight = aFont->HeightInPixels( );

	TInt idx = 0;
	TInt lines = 0;

	TPtr16 status = iStatusText->Des( );

	while ( idx < status.Length( ) ) {

		lines++;

		TInt lineStart = idx;
		TInt lineLengthInChars = 0;
		TInt lineLengthInPixels = 0;

		while ( lineLengthInPixels < aRect.Width( ) ) {

			TChar next = status[ idx ];

			TInt charWidth = aFont->CharWidthInPixels( next );

			if ( lineLengthInPixels + charWidth > aRect.Width( ) )
				break;

			lineLengthInChars++;
			lineLengthInPixels += charWidth;

			if ( ++idx >= status.Length( ) )
				break;
		}

		TPtrC16 line( status.Ptr( ) + lineStart, lineLengthInChars );

		if ( aReallyDrawFlag )
			iOffScreenGc->DrawText( line, aRect, verticalPos );

		verticalPos += fontHeight;
	}

	return( lines );

}

⌨️ 快捷键说明

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