--- a/uifw/EikStd/coctlsrc/AknButton.cpp Tue Aug 31 15:28:30 2010 +0300
+++ b/uifw/EikStd/coctlsrc/AknButton.cpp Wed Sep 01 12:16:19 2010 +0100
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2005-2008 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2005-2010 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"
@@ -264,7 +264,10 @@
// Sets bitmaps to resource provider (if one exists)
void SetProviderPressedBmpsL();
-
+
+ //Verify new rectagle size equals to the original
+ TBool TextRectSizeChanged( TRect aNewRect );
+
private: // Data
CAknButton& iButton;
@@ -284,6 +287,16 @@
CFbsBitmap* iPressedDownBmp;
CFbsBitmap* iPressedDownBmpMask;
CAknResourceProvider* iResourceProvider;
+
+ //Previous touch down or drag position, valid only with pressed state.
+ TPoint iPrePointerPos;
+ CAknsFrameBackgroundControlContext* iHighlightContext;
+ // buffer for visually ordered text
+ TBuf<255 + KAknBidiExtraSpacePerLine> iVisualText;
+ TBool iFeedbackEnabled;
+ TAknsItemID iBackgroundSkinIID;
+ TRect iBgFrameRect;
+ TRect iTextRect;
};
// ============================ MEMBER FUNCTIONS ===============================
@@ -303,7 +316,8 @@
iVerticalIconAlignment( CAknButton::ECenter ),
iHorizontalIconAlignment( CAknButton::ECenter ),
iTextAndIconAlignment( CAknButton::EIconBeforeText ),
- iResourceProvider( 0 )
+ iResourceProvider( 0 ),
+ iFeedbackEnabled( ETrue )
{
// default margins, these are applied to both text and icon
iMargins.SetAllValuesTo(
@@ -317,6 +331,7 @@
iIconSize = layoutRect.Rect().Size();
iFlags.Set( EUseDefaultIconSize );
iFlags.Set( EUseDefaultMargins );
+ iTextRect = TRect::EUninitialized;
}
// -----------------------------------------------------------------------------
@@ -330,6 +345,7 @@
iPictographInterface = NULL; // not owned
iFrameAndCenterIds.Close();
DeletePressedBmps();
+ delete iHighlightContext;
}
// -----------------------------------------------------------------------------
@@ -368,6 +384,13 @@
// Latched dimmed frame and center
iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonInactive );
iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonCenterInactive );
+ if ( !iHighlightContext )
+ {
+ iHighlightContext = CAknsFrameBackgroundControlContext::NewL(
+ KAknsIIDNone, TRect(), TRect(), EFalse );
+ iHighlightContext->SetFrame( KAknsIIDQsnFrButtonHighlight );
+ iHighlightContext->SetCenter( KAknsIIDQsnFrButtonHighlightCenter );
+ }
}
// -----------------------------------------------------------------------------
@@ -499,6 +522,20 @@
}
}
+//Verify new rectangle size equals to the original
+TBool CAknButtonExtension::TextRectSizeChanged( TRect aNewRect )
+ {
+ TBool result( ETrue );
+ if ( !iTextRect.IsEmpty() && !aNewRect.IsEmpty() )
+ {
+ if ( iTextRect.Width() == aNewRect.Width()
+ && iTextRect.Height() == aNewRect.Height() )
+ {
+ result = EFalse;
+ }
+ }
+ return result;
+ }
//
@@ -514,6 +551,10 @@
void CAknButtonExtension::HandleFeedbackAreaChange()
{
+ if ( !iFeedbackEnabled )
+ {
+ return;
+ }
// it is possible that feedback does not exist, eg. while booting.
// try getting one, and give up if that fails.
if ( !iFeedback )
@@ -579,6 +620,8 @@
TAknsItemID iPressedId;
TAknsItemID iHoverId;
TScaleMode iScaleMode;
+ TBool iFlagsChanged;
+ TBool iTextChanged;
};
// ============================ MEMBER FUNCTIONS ===============================
@@ -991,6 +1034,7 @@
iText = NULL;
iText = aText.AllocL();
+ iExtension->iTextChanged = ETrue;
}
// -----------------------------------------------------------------------------
@@ -1013,6 +1057,11 @@
//
EXPORT_C void CAknButtonState::SetFlags( const TInt aFlags )
{
+ if ( ( iFlags & KAknButtonStateHasLatchedFrame ) !=
+ ( aFlags & KAknButtonStateHasLatchedFrame ) )
+ {
+ iExtension->iFlagsChanged = ETrue;
+ }
iFlags = aFlags;
}
@@ -1070,7 +1119,21 @@
LoadButtonIcon( iPressedIcon );
LoadButtonIcon( iHoverIcon );
}
-
+// -----------------------------------------------------------------------------
+// CAknButtonState::UpdateExtensionInfoL
+// Updates extension information.
+// -----------------------------------------------------------------------------
+void CAknButtonState::UpdateExtensionInfoL( TInt aResource )
+ {
+ if ( iExtension )
+ {
+ iExtension->ConfigureExtensionFromResourceL( aResource );
+ LoadButtonIcon( iIcon );
+ LoadButtonIcon( iDimmedIcon );
+ LoadButtonIcon( iPressedIcon );
+ LoadButtonIcon( iHoverIcon );
+ }
+ }
// -----------------------------------------------------------------------------
// CAknButtonState::SizeChanged
// Scales function graphics to the given size
@@ -1321,6 +1384,44 @@
{
iExtension->iGeneratedDimmedIcon = aDimmedIconCreatedByButton;
}
+// -----------------------------------------------------------------------------
+// CAknButtonState::FlagsChanged
+// Returns ETrue if button state flags are changed so that
+// KAknStateHasLatchedDownFrame is setted or cleared
+// -----------------------------------------------------------------------------
+TBool CAknButtonState::FlagsChanged()
+ {
+ return iExtension->iFlagsChanged;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::ResetFlagsChanged
+// Frame has been updated so boolean iFlagsChanged can be set to EFalse
+// -----------------------------------------------------------------------------
+void CAknButtonState::ResetFlagsChanged()
+ {
+ iExtension->iFlagsChanged = EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::TextChanged
+// Returns ETrue if text is changed and button's visual text has
+// not been updated.
+// -----------------------------------------------------------------------------
+TBool CAknButtonState::TextChanged()
+ {
+ return iExtension->iTextChanged;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::ResetTextChanged
+// Visual text has been updated so boolean iTextChanged can be set to EFalse
+// -----------------------------------------------------------------------------
+void CAknButtonState::ResetTextChanged()
+ {
+ iExtension->iTextChanged = EFalse;
+ }
+
// -----------------------------------------------------------------------------
// CAknButtonState::Extension
@@ -1562,7 +1663,12 @@
{
OverrideColorL( EColorButtonText, textColor );
}
-
+
+ if ( AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), textColor,
+ iTextColorTableId, EAknsCIQsnTextColorsCG84 ) == KErrNone )
+ {
+ OverrideColorL( EColorButtonTextPressed, textColor );
+ }
if ( !iStates )
{
iStates = new ( ELeave ) CArrayPtrFlat<CAknButtonState>( 2 );
@@ -1594,6 +1700,7 @@
iHorizontalAlignment = CGraphicsContext::ELeft;
}
iExtension->HandleFeedbackAreaChange();
+ SetFrameIDs();
}
// -----------------------------------------------------------------------------
@@ -1796,6 +1903,11 @@
TRAP_IGNORE( OverrideColorL( EColorButtonText, textColor ) );
}
+ if ( AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), textColor,
+ iTextColorTableId, EAknsCIQsnTextColorsCG84 ) == KErrNone )
+ {
+ TRAP_IGNORE( OverrideColorL( EColorButtonTextPressed, textColor ) );
+ }
// generated pressed frame has to be regenerated
if ( iFlags & KAknButtonNoFrame && iFlags & KAknButtonPressedDownFrame )
{
@@ -1889,7 +2001,6 @@
HideHelp();
iButtonPressed = EFalse;
}
-
if ( aDimmed )
{
iExtension->iFlags.Set( CAknButtonExtension::EDimmed );
@@ -1898,7 +2009,7 @@
{
iExtension->iFlags.Clear( CAknButtonExtension::EDimmed );
}
- if ( iExtension->iFeedback )
+ if ( iExtension->iFeedbackEnabled && iExtension->iFeedback )
{
if ( aDimmed )
{
@@ -1933,6 +2044,7 @@
{
CCoeControl::SetDimmed( aDimmed );
}
+ SetFrameIDs();
}
// -----------------------------------------------------------------------------
@@ -1962,6 +2074,9 @@
{
// show press changes
iButtonPressed = ETrue;
+ iExtension->iPrePointerPos.SetXY( -1, -1 );
+
+ SetFrameIDs();
if ( NeedsRedrawWhenPressed() )
{
DrawNow();
@@ -1996,6 +2111,7 @@
if ( iButtonPressed )
{
iButtonPressed = EFalse;
+ SetFrameIDs();
if ( NeedsRedrawWhenPressed() )
{
@@ -2032,14 +2148,14 @@
iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported );
iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported );
}
-
- if ( iKeyDownReported && RequestExit() && Observer() )
+
+ TInt reported = iKeyDownReported;
+ iKeyDownReported = EFalse;
+ if ( reported && RequestExit() && Observer() )
{
Observer()->HandleControlEventL( this,
MCoeControlObserver::EEventRequestExit );
- }
-
- iKeyDownReported = EFalse;
+ }
}
// we don't want aKeyEvent to go somewhere else :)
return EKeyWasConsumed;
@@ -2058,7 +2174,7 @@
if ( aVisible != IsVisible() )
{
CAknControl::MakeVisible( aVisible );
- if ( iExtension->iFeedback )
+ if ( iExtension->iFeedbackEnabled && iExtension->iFeedback )
{
if ( aVisible )
{
@@ -2071,7 +2187,11 @@
}
CAknButtonState* state = State();
- if ( !aVisible && state && state->HasHelp() )
+ if ( !aVisible && iButtonPressed )
+ {
+ ResetState();
+ }
+ else if ( !aVisible && state && state->HasHelp() )
{
HideHelp();
}
@@ -2120,6 +2240,11 @@
//
EXPORT_C void CAknButton::SizeChanged()
{
+ //Reset state if observer modified the rectangel.
+ if ( iButtonPressed && !Rect().Contains( iExtension->iPrePointerPos ) )
+ {
+ ResetState();
+ }
// If default icon size from LAF is used re-request that, otherwise trust
// that size will be updated by the utilising application.
if ( iExtension->iFlags.IsSet( CAknButtonExtension::EUseDefaultIconSize ) )
@@ -2149,6 +2274,7 @@
{
TRAP_IGNORE( CreatePressedDownFrameL() );
}
+ SetFrameRects();
iExtension->HandleFeedbackAreaChange();
}
@@ -2171,6 +2297,10 @@
}
return;
}
+ if ( iExtension )
+ {
+ iExtension->iPrePointerPos = aPointerEvent.iPosition;
+ }
TBool buttonEvent( TouchArea().Contains( aPointerEvent.iPosition ) );
CAknButtonState* state = State();
if ( !state )
@@ -2198,6 +2328,7 @@
if ( !iButtonPressed )
{
iButtonPressed = ETrue;
+ SetFrameIDs();
// feedback/basic on down event, if hit test is
// used. Area registry is used for rectangular
// buttons
@@ -2227,7 +2358,8 @@
{
// State is changed on button down event
ChangeState( EFalse );
- redrawNeeded = ETrue;
+ redrawNeeded = EFalse;
+ DrawNow(); //Redraw before noticing the observer for observer might open dialog
if ( Observer() )
{
Observer()->HandleControlEventL( this,
@@ -2264,10 +2396,10 @@
// Redraw button, if needed
if ( NeedsRedrawWhenPressed() )
{
- iButtonPressed = EFalse;
redrawNeeded = ETrue;
}
iButtonPressed = EFalse;
+ SetFrameIDs();
StopKeyRepeatTimer();
StopLongPressTimer();
@@ -2289,6 +2421,7 @@
else if ( buttonEvent && !iButtonPressed && !IsDimmed() )
{
iButtonPressed = ETrue;
+ SetFrameIDs();
// Redraw button, if needed
if ( NeedsRedrawWhenPressed() )
@@ -2315,6 +2448,10 @@
case TPointerEvent::EButton1Up:
{
+ if ( iExtension )
+ {
+ iExtension->iPrePointerPos.SetXY( -1, -1 );
+ }
iNumberOfDragEvents = 0;
HideHelp();
@@ -2333,8 +2470,10 @@
}
}
iButtonPressed = EFalse;
+ SetFrameIDs();
}
+ TBool hasDrawn( EFalse );
if ( buttonEvent && !IsDimmed() )
{
// feedback/BasicButton on up event, if hit test is
@@ -2357,7 +2496,12 @@
!( iExtension->iFlags.IsSet( CAknButtonExtension::EKeyRepeatEventReported ) ) )
{
ChangeState( EFalse );
- redrawNeeded = ETrue;
+ if ( !hasDrawn )
+ {
+ DrawNow();
+ hasDrawn = ETrue;
+ }
+
if ( Observer() )
{
Observer()->HandleControlEventL( this,
@@ -2368,6 +2512,11 @@
{
if ( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) && Observer() )
{
+ if ( redrawNeeded && !hasDrawn )
+ {
+ DrawNow();
+ hasDrawn = ETrue;
+ }
Observer()->HandleControlEventL( this,
static_cast<MCoeControlObserver::TCoeEvent>(
CAknButton::ELongPressEndedEvent ) );
@@ -2378,6 +2527,11 @@
if ( RequestExit() && Observer() )
{
+ if ( redrawNeeded && !hasDrawn )
+ {
+ DrawNow();
+ hasDrawn = ETrue;
+ }
Observer()->HandleControlEventL( this,
MCoeControlObserver::EEventRequestExit );
}
@@ -2385,6 +2539,11 @@
if ( !buttonEvent && !IsDimmed() && Observer() )
{
+ if ( redrawNeeded && !hasDrawn )
+ {
+ DrawNow();
+ hasDrawn = ETrue;
+ }
Observer()->HandleControlEventL( this,
MCoeControlObserver::EEventRequestCancel );
@@ -2397,7 +2556,10 @@
iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported );
}
}
-
+ if ( hasDrawn )
+ {
+ redrawNeeded = EFalse;
+ }
break;
}
@@ -2420,6 +2582,13 @@
{
if ( iExtension ) iExtension->HandleFeedbackAreaChange();
CAknControl::PositionChanged();
+
+ //Reset state if observer moved button position.
+ if ( iButtonPressed && iExtension && !Rect().Contains( iExtension->iPrePointerPos ) )
+ {
+ ResetState();
+ }
+ SetFrameRects();
}
// -----------------------------------------------------------------------------
@@ -2432,6 +2601,7 @@
if ( !IsFocused() && iButtonPressed )
{
iButtonPressed = EFalse;
+ SetFrameIDs();
iKeyDownReported = EFalse;
}
if ( IsVisible() )
@@ -2476,49 +2646,14 @@
EXPORT_C void CAknButton::Draw( const TRect& /*aRect*/ ) const
{
TRect rect( Rect() );
- TAknLayoutRect centerLayout;
- centerLayout.LayoutRect( rect,
- AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() );
- TRect innerRect( centerLayout.Rect() );
TRect highlightRect( HighlightRect() );
CWindowGc& gc = SystemGc();
CAknButtonState* state = State();
- // Skin ids are determined here (a bit too early than necessary) so that
- // we can avoid doing the same thing in DrawMaskedL.
- if ( !( iFlags & KAknButtonNoFrame ) )
+ if ( !( iFlags & KAknButtonNoFrame ) && !iButtonPressed && state &&
+ state->FlagsChanged() )
{
- TInt frameIdIndex = KFrameId;
-
- if ( iButtonPressed )
- {
- frameIdIndex = KPressedFrameId;
- }
- else if ( state && state->Flags() & KAknButtonStateHasLatchedFrame )
- {
- if ( IsDimmed() )
- {
- // dimmed latched frame
- frameIdIndex = KLatchedDimmedFrameId;
- }
- else
- {
- // latched down
- frameIdIndex = KLatchedFrameId;
- }
- }
- else if ( IsDimmed())
- {
- // dimmed frame
- frameIdIndex = KDimmedFrameId;
- }
-
- if ( SkinIID( frameIdIndex ) != KAknsIIDNone )
- {
- iBgContext->SetFrame( SkinIID( frameIdIndex ) );
- iBgContext->SetCenter( SkinIID( ++frameIdIndex ) );
- iBgContext->SetFrameRects( rect, innerRect );
- }
+ SetFrameIDs();
}
if ( !iExtension->iFlags.IsSet( CAknButtonExtension::EUseAdditionalMask ) )
@@ -2540,13 +2675,10 @@
if ( IsFocused() && !highlightRect.IsEmpty() )
{
- iBgContext->SetFrame( KAknsIIDQsnFrButtonHighlight );
- iBgContext->SetCenter( KAknsIIDQsnFrButtonHighlightCenter );
- iBgContext->SetFrameRects( rect, innerRect );
-
// frame graphics
- if ( !AknsDrawUtils::Background( skin, iBgContext, NULL, gc,
- rect, KAknsDrawParamNoClearUnderImage ) )
+ if ( !AknsDrawUtils::Background( skin,
+ iExtension->iHighlightContext, NULL, gc, rect,
+ KAknsDrawParamNoClearUnderImage ) )
{
gc.SetBrushColor( KRgbRed );
gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
@@ -2624,6 +2756,7 @@
}
TRAP_IGNORE( SetStateIndexL( newIndex ) );
+ SetFrameIDs();
if ( aDrawNow )
{
DrawNow();
@@ -2713,10 +2846,13 @@
// -----------------------------------------------------------------------------
//
EXPORT_C void CAknButton::SetButtonFlags( const TInt aFlags )
- {
- if ( !(iFlags & KAknButtonNoFrame ) && aFlags & KAknButtonNoFrame )
+ {
+ if ( !( iFlags & KAknButtonNoFrame ) )
{
- iExtension->iMargins.SetAllValuesTo( 0 );
+ if ( aFlags & KAknButtonNoFrame )
+ {
+ iExtension->iMargins.SetAllValuesTo( 0 );
+ }
}
if ( aFlags & KAknButtonHitTest )
{
@@ -2791,6 +2927,7 @@
{
skinIds[KLatchedDimmedCenterId] = aLatchedDimmedCenterId;
}
+ SetFrameIDs();
}
// -----------------------------------------------------------------------------
@@ -2822,6 +2959,7 @@
EXPORT_C void CAknButton::SetTextFont( const CFont* aFont )
{
iFont = aFont;
+ ConvertTextToVisualAndClip( iExtension->iTextRect );
}
// -----------------------------------------------------------------------------
@@ -3116,6 +3254,8 @@
}
TRAP_IGNORE( SetStateIndexL( newIndex ) );
+ // Updating background context might be needed if states flags differ
+ SetFrameIDs();
if ( aDrawNow )
{
@@ -3294,6 +3434,7 @@
StopKeyRepeatTimer();
StopLongPressTimer();
iButtonPressed = EFalse;
+ SetFrameIDs();
HideHelp();
if ( iExtension )
{
@@ -3383,24 +3524,28 @@
//
void CAknButton::DrawTextButton( CWindowGc& aGc ) const
{
+ TRect textRect;
+
+ TRect iconRect; //this is no use
+ GetCurrentStateTextAndIconRect( iconRect, textRect );
+
CAknButtonState* state = State();
- if ( !state || !state->HasText() )
- return;
-
+ if ( state->TextChanged() || iExtension->TextRectSizeChanged( textRect ) )
+ {
+ ConvertTextToVisualAndClip( textRect );
+ }
+ DrawText( aGc, textRect );
+ }
+
+// -----------------------------------------------------------------------------
+// CAknButton::DrawText
+// Continues drawing of the button which has text
+// -----------------------------------------------------------------------------
+//
+void CAknButton::DrawText( CWindowGc& aGc, TRect& aTextRect ) const
+ {
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
- TRect textRect = iExtension->iMargins.InnerRect( Rect() );
-
- if ( !( iFlags & KAknButtonNoFrame ) &&
- ( iFlags & KAknButtonTextInsideFrame ) )
- {
- TAknLayoutRect center;
- center.LayoutRect( Rect(),
- AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() );
-
- textRect = center.Rect();
- }
-
aGc.SetBrushStyle( CGraphicsContext::ENullBrush );
TRgb penColor;
@@ -3418,17 +3563,6 @@
aGc.SetUnderlineStyle( iExtension->iUnderlineStyle );
- // buffer for visually ordered text
- TBuf<255 + KAknBidiExtraSpacePerLine> visualText;
- TInt clipWidth = textRect.Width();
-
- // bidi processing - using AknBidiTextUtils.
- AknBidiTextUtils::ConvertToVisualAndClip(
- state->Text(),
- visualText,
- *font,
- clipWidth,
- clipWidth );
TInt baselineOffset = 0;
switch ( iVerticalAlignment )
@@ -3438,22 +3572,24 @@
break;
case EBottom:
- baselineOffset = textRect.Height();
+ baselineOffset = aTextRect.Height();
break;
default: // centered
baselineOffset = font->AscentInPixels() +
- ( textRect.Height() - font->AscentInPixels() ) / 2;
+ ( aTextRect.Height() - font->AscentInPixels() ) / 2;
}
CGraphicsContext::TTextAlign horAlignment = iHorizontalAlignment;
- aGc.DrawText( visualText, textRect, baselineOffset, horAlignment );
+ aGc.DrawText( iExtension->iVisualText, aTextRect, baselineOffset,
+ horAlignment );
if ( iExtension->iPictographInterface )
{
// For Japanese variant only
iExtension->iPictographInterface->Interface()->DrawPictographsInText(
- aGc, *font, visualText, textRect, baselineOffset, horAlignment );
+ aGc, *font, iExtension->iVisualText, aTextRect, baselineOffset,
+ horAlignment );
}
}
@@ -3464,13 +3600,13 @@
//
void CAknButton::DrawIconButton( CWindowGc& aGc ) const
{
- TRect iconRect( iExtension->iMargins.InnerRect( Rect() ) );
+ TRect iconRect;
+ TRect textRect;
+ GetCurrentStateTextAndIconRect( iconRect, textRect );
aGc.SetBrushStyle( CGraphicsContext::ENullBrush );
const CGulIcon* icon = GetCurrentIcon();
- if ( !icon )
- return;
CFbsBitmap* buttonBmp = icon->Bitmap();
CFbsBitmap* buttonMask = icon->Mask();
@@ -3552,98 +3688,24 @@
if ( !state || !state->HasText() )
{
return;
- }
+ }
const CGulIcon* icon = GetCurrentIcon();
- if ( !icon )
- {
- return;
- }
-
- TRect rect = iExtension->iMargins.InnerRect( Rect() );
+
+
TRect iconRect;
TRect textRect;
+ GetCurrentStateTextAndIconRect( iconRect, textRect );
- if ( !( iFlags & KAknButtonNoFrame ) &&
- ( iFlags & KAknButtonTextInsideFrame ))
- {
- TAknLayoutRect centerLayout;
- centerLayout.LayoutRect( rect,
- AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() );
- rect = centerLayout.Rect();
- }
-
CFbsBitmap* buttonBmp = icon->Bitmap();
CFbsBitmap* buttonMask = icon->Mask();
TSize iconSize ( buttonBmp->SizeInPixels());
- // Set rects for icon and text according to their positioning
- // First icon rect according to icon size - rest is for text
-
- switch ( iExtension->iTextAndIconAlignment )
+
+ if ( state->TextChanged() || iExtension->TextRectSizeChanged( textRect ) )
{
- case EIconBeforeText:
- if ( AknLayoutUtils::LayoutMirrored() )
- {
- textRect.SetRect( rect.iTl.iX, rect.iTl.iY,
- rect.iBr.iX - iconSize.iWidth, rect.iBr.iY);
- iconRect.SetRect( rect.iTl.iX +
- rect.Width() -iconSize.iWidth,
- rect.iTl.iY, rect.iBr.iX, rect.iBr.iY );
- }
- else
- {
- iconRect.SetRect( rect.iTl.iX, rect.iTl.iY,
- rect.iTl.iX + iconSize.iWidth, rect.iBr.iY);
- textRect.SetRect( rect.iTl.iX + iconSize.iWidth,
- rect.iTl.iY, rect.iBr.iX, rect.iBr.iY );
- }
-
- break;
-
- case EIconAfterText:
- if ( AknLayoutUtils::LayoutMirrored() )
- {
- iconRect.SetRect( rect.iTl.iX, rect.iTl.iY,
- rect.iTl.iX + iconSize.iWidth, rect.iBr.iY);
- textRect.SetRect( rect.iTl.iX + iconSize.iWidth,
- rect.iTl.iY, rect.iBr.iX, rect.iBr.iY );
- }
- else
- {
- textRect.SetRect( rect.iTl.iX, rect.iTl.iY,
- rect.iBr.iX - iconSize.iWidth, rect.iBr.iY);
- iconRect.SetRect( rect.iTl.iX +
- rect.Width() -iconSize.iWidth,
- rect.iTl.iY, rect.iBr.iX, rect.iBr.iY );
- }
- break;
-
- case EIconOverText:
- iconRect.SetRect( rect.iTl.iX, rect.iTl.iY,
- rect.iBr.iX, rect.iTl.iY + iconSize.iHeight );
- textRect.SetRect( rect.iTl.iX, rect.iTl.iY + iconSize.iHeight,
- rect.iBr.iX, rect.iBr.iY );
- break;
-
- case EIconUnderText:
- textRect.SetRect( rect.iTl.iX, rect.iTl.iY,
- rect.iBr.iX, rect.iBr.iY - iconSize.iHeight );
- iconRect.SetRect( rect.iTl.iX, rect.iBr.iY - iconSize.iHeight,
- rect.iBr.iX, rect.iBr.iY );
- break;
-
- case EOverlay:
- {
- textRect = rect;
- iconRect = rect;
- }
- break;
-
- default:
- return;
+ ConvertTextToVisualAndClip( textRect );
}
-
// Draw icon
TPoint iconPoint;
switch ( iExtension->iHorizontalIconAlignment )
@@ -3708,57 +3770,7 @@
aGc.BitBlt( iconPoint, buttonBmp, iconRect.Size() );
}
- const CFont* font = iFont;
- if ( !font )
- {
- font = iCoeEnv->NormalFont();
- }
- aGc.UseFont( font );
-
- TRgb penColor;
- TRgb brushColor;
- GetTextColors( penColor, brushColor );
- aGc.SetPenColor( penColor );
- aGc.SetBrushColor( brushColor );
-
- aGc.SetUnderlineStyle( iExtension->iUnderlineStyle );
-
- TBuf<255 + KAknBidiExtraSpacePerLine> visualText; // buffer for visually ordered text
- TInt clipWidth = textRect.Width();
-
- // bidi processing - using AknBidiTextUtils.
- AknBidiTextUtils::ConvertToVisualAndClip(
- state->Text(),
- visualText,
- *font,
- clipWidth,
- clipWidth );
-
- TInt baselineOffset = 0;
- switch ( iVerticalAlignment )
- {
- case ETop:
- baselineOffset = font->AscentInPixels();
- break;
-
- case EBottom:
- baselineOffset = textRect.Height();
- break;
-
- default: // centered
- baselineOffset = font->AscentInPixels() +
- ( textRect.Height() - font->AscentInPixels() ) / 2;
- }
-
- CGraphicsContext::TTextAlign horAlignment = iHorizontalAlignment;
-
- aGc.DrawText( visualText, textRect, baselineOffset, horAlignment );
- if ( iExtension->iPictographInterface )
- {
- // For Japanese variant only
- iExtension->iPictographInterface->Interface()->DrawPictographsInText(
- aGc, *font, visualText, textRect, baselineOffset, horAlignment );
- }
+ DrawText( aGc, textRect );
}
// -----------------------------------------------------------------------------
@@ -4345,6 +4357,7 @@
iStates->Delete( iStateIndex );
iStateIndex <= 0 ? iStateIndex = 0 : iStateIndex--;
+ SetFrameIDs();
DrawNow();
}
}
@@ -4442,10 +4455,271 @@
iHelpNote->SetTimeDelayBeforeShow( iHelpNoteWaitInterval );
iHelpNote->SetTimePopupInView( iHelpNoteInViewInterval );
iHelpNote->SetTooltipModeL( ETrue );
+
+ //When state changed, empty rect to enable recalculate the
+ //visual text if text exists in current state.
+ if ( !(iExtension->iTextRect.IsEmpty()) )
+ {
+ iExtension->iTextRect = TRect::EUninitialized;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetFrameIDs
+// Sets frame ids for background context
+// -----------------------------------------------------------------------------
+//
+void CAknButton::SetFrameIDs() const
+ {
+ // Skin ids are determined here (a bit too early than necessary) so that
+ // we can avoid doing the same thing in DrawMaskedL.
+ CAknButtonState* state = State();
+ if ( !( iFlags & KAknButtonNoFrame ) )
+ {
+ TInt frameIdIndex = KFrameId;
+
+ if ( iButtonPressed )
+ {
+ frameIdIndex = KPressedFrameId;
+ }
+ else if ( state && state->Flags() & KAknButtonStateHasLatchedFrame )
+ {
+ if ( IsDimmed() )
+ {
+ // dimmed latched frame
+ frameIdIndex = KLatchedDimmedFrameId;
+ }
+ else
+ {
+ // latched down
+ frameIdIndex = KLatchedFrameId;
+ }
+ }
+ else if ( IsDimmed() )
+ {
+ // dimmed frame
+ frameIdIndex = KDimmedFrameId;
+ }
+
+ TAknsItemID skinIID( SkinIID( frameIdIndex ) );
+
+ // Only change the background frame graphics if necessary.
+ if ( skinIID != KAknsIIDNone &&
+ skinIID != iExtension->iBackgroundSkinIID )
+ {
+ iBgContext->SetFrame( skinIID );
+ iBgContext->SetCenter( SkinIID( ++frameIdIndex) );
+ iExtension->iBackgroundSkinIID = skinIID;
+ }
+ }
+ if ( state )
+ {
+ state->ResetFlagsChanged();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetFrameRects
+// -----------------------------------------------------------------------------
+//
+void CAknButton::SetFrameRects()
+ {
+ TRect rect( Rect() );
+
+ // Only change the frame rects is the button rectangle is valid and the
+ // button size has changed.
+ if ( !rect.IsEmpty() && iExtension->iBgFrameRect != rect )
+ {
+ TAknLayoutRect centerLayout;
+ centerLayout.LayoutRect( rect,
+ AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() );
+ TRect innerRect( centerLayout.Rect() );
+
+ iBgContext->SetFrameRects( rect, innerRect );
+ iExtension->iHighlightContext->SetFrameRects( rect, innerRect );
+ iExtension->iBgFrameRect = rect;
}
}
// -----------------------------------------------------------------------------
+// CAknButton::ConvertTextToVisualAndClip
+// -----------------------------------------------------------------------------
+//
+void CAknButton::ConvertTextToVisualAndClip( const TRect& aRect ) const
+ {
+ CAknButtonState* state = State();
+ if ( !state || !state->HasText() )
+ {
+ if ( state )
+ {
+ state->ResetTextChanged();
+ }
+ return;
+ }
+
+ TRect textRect( aRect );
+ //Using given rect to calculate the visual text if it's not empty.
+ if ( !textRect.IsEmpty() )
+ {
+ iExtension->iTextRect = textRect;
+ }
+ //Calculate text area.
+ //This branch means that it's the first calling after the state changed
+ //or client using new font before this is shown.
+ else
+ {
+ TRect iconRect;
+ GetCurrentStateTextAndIconRect( iconRect, textRect );
+ iExtension->iTextRect = textRect;
+ }
+
+ TInt clipWidth = textRect.Width();
+
+ const CFont* font = iFont;
+ if ( !font )
+ {
+ font = iCoeEnv->NormalFont();
+ }
+
+ // bidi processing - using AknBidiTextUtils.
+ AknBidiTextUtils::ConvertToVisualAndClip(
+ state->Text(),
+ iExtension->iVisualText,
+ *font,
+ clipWidth,
+ clipWidth );
+ }
+
+// -----------------------------------------------------------------------------
+// CAknButton::GetCurrentStateTextAndIconRect()
+// Get rect for icon and text of the current button state .
+// -----------------------------------------------------------------------------
+//
+void CAknButton::GetCurrentStateTextAndIconRect( TRect& aIconRect,
+ TRect& aTextRect ) const
+ {
+ TRect iconRect( TRect::EUninitialized ) ;
+ TRect textRect( TRect::EUninitialized );
+
+ CAknButtonState* state = State();
+
+ //Return directly if no state
+ if ( !state )
+ {
+ aIconRect = iconRect;
+ aTextRect = textRect;
+ return;
+ }
+
+ TBool hasText( state->HasText() );
+ TBool hasIcon( EFalse );
+
+ const CGulIcon* icon = GetCurrentIcon();
+ if ( icon )
+ {
+ hasIcon = ETrue;
+ }
+
+ TRect rect = iExtension->iMargins.InnerRect( Rect() );
+
+ //Icon area is not effected by the frame flags.
+ if ( hasIcon )
+ {
+ iconRect = rect;
+ }
+
+ if ( !( iFlags & KAknButtonNoFrame ) &&
+ ( iFlags & KAknButtonTextInsideFrame ))
+ {
+ TAknLayoutRect centerLayout;
+ centerLayout.LayoutRect( rect,
+ AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() );
+ rect = centerLayout.Rect();
+ }
+
+ if ( hasText )
+ {
+ textRect = rect;
+ }
+
+
+ if ( hasText && hasIcon )
+ {
+ CFbsBitmap* buttonBmp = icon->Bitmap();
+ CFbsBitmap* buttonMask = icon->Mask();
+ TSize iconSize ( buttonBmp->SizeInPixels());
+
+ // Set rects for icon and text according to their positioning
+ // First icon rect according to icon size - rest is for text
+
+ switch ( iExtension->iTextAndIconAlignment )
+ {
+ case CAknButton::EIconBeforeText:
+ if ( AknLayoutUtils::LayoutMirrored() )
+ {
+ textRect.SetRect( rect.iTl.iX, rect.iTl.iY,
+ rect.iBr.iX - iconSize.iWidth, rect.iBr.iY);
+ iconRect.SetRect( rect.iTl.iX +
+ rect.Width() -iconSize.iWidth,
+ rect.iTl.iY, rect.iBr.iX, rect.iBr.iY );
+ }
+ else
+ {
+ iconRect.SetRect( rect.iTl.iX, rect.iTl.iY,
+ rect.iTl.iX + iconSize.iWidth, rect.iBr.iY);
+ textRect.SetRect( rect.iTl.iX + iconSize.iWidth,
+ rect.iTl.iY, rect.iBr.iX, rect.iBr.iY );
+ }
+
+ break;
+
+ case CAknButton::EIconAfterText:
+ if ( AknLayoutUtils::LayoutMirrored() )
+ {
+ iconRect.SetRect( rect.iTl.iX, rect.iTl.iY,
+ rect.iTl.iX + iconSize.iWidth, rect.iBr.iY);
+ textRect.SetRect( rect.iTl.iX + iconSize.iWidth,
+ rect.iTl.iY, rect.iBr.iX, rect.iBr.iY );
+ }
+ else
+ {
+ textRect.SetRect( rect.iTl.iX, rect.iTl.iY,
+ rect.iBr.iX - iconSize.iWidth, rect.iBr.iY);
+ iconRect.SetRect( rect.iTl.iX +
+ rect.Width() -iconSize.iWidth,
+ rect.iTl.iY, rect.iBr.iX, rect.iBr.iY );
+ }
+ break;
+
+ case CAknButton::EIconOverText:
+ iconRect.SetRect( rect.iTl.iX, rect.iTl.iY,
+ rect.iBr.iX, rect.iTl.iY + iconSize.iHeight );
+ textRect.SetRect( rect.iTl.iX, rect.iTl.iY + iconSize.iHeight,
+ rect.iBr.iX, rect.iBr.iY );
+ break;
+
+ case CAknButton::EIconUnderText:
+ textRect.SetRect( rect.iTl.iX, rect.iTl.iY,
+ rect.iBr.iX, rect.iBr.iY - iconSize.iHeight );
+ iconRect.SetRect( rect.iTl.iX, rect.iBr.iY - iconSize.iHeight,
+ rect.iBr.iX, rect.iBr.iY );
+ break;
+
+ case CAknButton::EOverlay:
+ {
+ textRect = rect;
+ iconRect = rect;
+ }
+ break;
+ default:
+ break; //Do nothing.
+ }
+ }
+ aTextRect = textRect;
+ aIconRect = iconRect;
+ }
+// -----------------------------------------------------------------------------
// CAknButton::TouchArea
// Returns the button touchable area.
// -----------------------------------------------------------------------------
@@ -4463,4 +4737,49 @@
}
return touchRect;
}
+
+// -----------------------------------------------------------------------------
+// CAknButton::EnableFeedback
+// Enables or disables tactile feedback
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::EnableFeedback( TBool aEnable )
+ {
+ if ( iExtension->iFeedbackEnabled == aEnable )
+ {
+ return;
+ }
+ iExtension->iFeedbackEnabled = aEnable;
+ if ( aEnable )
+ {
+ if ( !iExtension->iFeedback )
+ {
+ iExtension->iFeedback = MTouchFeedback::Instance();
+ }
+ if ( !iExtension->iFeedback )
+ {
+ return;
+ }
+ if ( IsVisible() )
+ {
+ iExtension->iFeedback->MoveFeedbackAreaToFirstPriority( this,
+ 0 );
+ iExtension->iFeedback->EnableFeedbackForControl(
+ this,
+ !IsDimmed() );
+ }
+ iExtension->HandleFeedbackAreaChange();
+ }
+ else
+ {
+ // MTouchFeedback instance lives in AknAppUi. If there is no
+ // MTouchFeedback instance there is no need to remove any areas
+ // either.
+ MTouchFeedback* fb = MTouchFeedback::Instance();
+ if ( fb )
+ {
+ fb->RemoveFeedbackForControl( this );
+ }
+ }
+ }
// end of file