📄 statusoverlay.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 + -