/*
* Copyright (c) 2006-2007 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: Implementation for button base and dragbar
*
*/
#include <featmgr.h>
#include <AknFepGlobalEnums.h>
#include "peninputlayoutbutton.h"
#include "peninputlayouttimer.h"
#include "peninputlayout.h"
#ifdef __WINS__
const TInt KSpriteMoveDrawInterval = 10000; // 1/100 second
#else
const TInt KSpriteMoveDrawInterval = 1000; // 1/1000 second
#endif
#define __USING_MOVING_FRAME__ //flag to use the moving frame when dragging the layout
// ============================ MEMBER FUNCTIONS ===============================
/******************** start of CButtonBase **********************************/
// ---------------------------------------------------------------------------
// CButtonBase::NewL
// factory function
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C CButtonBase* CButtonBase::NewL(const TRect& aRect,
CFepUiLayout* aUiLayout,TInt aCtrlId)
{
CButtonBase* btn=new (ELeave)CButtonBase(aRect,aUiLayout,aCtrlId);
CleanupStack::PushL(btn);
btn->BaseConstructL();
CleanupStack::Pop(btn);
return btn;
}
// ---------------------------------------------------------------------------
// CButtonBase::BaseConstructL
// Do base contruction
// ---------------------------------------------------------------------------
//
EXPORT_C void CButtonBase::BaseConstructL()
{
CFepUiBaseCtrl::BaseConstructL();
//tap accuracy enhancement
if( FeatureManager::FeatureSupported( KFeatureIdFfCapacitiveDisplay ))
{
EnableExtResponseArea( ETrue, TRect(TPoint(10,10),TSize(10,10)) );
}
}
// ---------------------------------------------------------------------------
// CButtonBase::CButtonBase
// C++ default constructor
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C CButtonBase::CButtonBase(const TRect& aRect,CFepUiLayout* aUiLayout,
TInt aCtrlId)
:CFepUiBaseCtrl(aRect,aUiLayout,aCtrlId),
iPressed(EFalse),
iStretchable(ETrue),
iBaseline(-1),
iCaptionColor(KRgbWhite), //white caption
iCaptionShadowColor(KRgbBlack) //black caption shadow
{
SetControlType(ECtrlButton | ECtrlTactileFeedback);
iDimmed = EFalse;
#ifdef __ALPHA_TRANCEPARENCY__
const TRgb KDefaultButtonBackCol = TRgb(30,30,30);
#else
const TRgb KDefaultButtonBackCol = TRgb(230,230,230);
#endif
SetBkColor(KDefaultButtonBackCol);
//todo code refactoring needed, move to BaseConstructL
#ifdef RD_TACTILE_FEEDBACK
//Advanced Tactile feedback REQ417-47932
if(aUiLayout)
{
if (aUiLayout->PenInputType() == EPluginInputModeFSQ||
aUiLayout->PenInputType() == EPluginInputModeVkb)
{
SetTactileFeedbackType(ETouchFeedbackBasicButton);
aUiLayout->RegisterFeedbackArea(reinterpret_cast<TInt>(this),aRect,ETouchFeedbackBasicButton);
}
else
{
SetTactileFeedbackType(ETouchFeedbackSensitiveInput);
aUiLayout->RegisterFeedbackArea(reinterpret_cast<TInt>(this),aRect,ETouchFeedbackSensitiveInput);
}
}
#endif //RD_TACTILE_FEEDBACK
}
// ---------------------------------------------------------------------------
// CButtonBase::~CButtonBase
// Destructor
// ---------------------------------------------------------------------------
//
EXPORT_C CButtonBase::~CButtonBase()
{
delete iCaption;
//only free the bitmaps in the pool
iBmpPool.ResetAndDestroy();
//must reset the background bmp otherwise CFepUiBaseCtrl will re-delete it.
SetBackgroundBmp(NULL);
SetBackgroundMaskBmp(NULL);
//font
if(iFontOwnership && iFont)
{
BitmapDevice()->ReleaseFont(iFont);
iFont = NULL;
}
delete iNoUsedBkbmp;
delete iNoUsedMaskBkbmp;
#ifdef RD_TACTILE_FEEDBACK
//de-register the area for tactile feedback
//if(aUiLayout) //there must be aUiLayout
UiLayout()->DeRegisterFeedbackArea(reinterpret_cast<TInt>(this),Rect());
#endif // RD_TACTILE_FEEDBACK
}
// ---------------------------------------------------------------------------
// CButtonBase::Draw
// Draw the control
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CButtonBase::Draw()
{
if(!AbleToDraw())
return;
if(iWndControl)
{
CFepUiBaseCtrl::Draw();
return;
}
CFbsBitGc* gc = static_cast<CFbsBitGc*>(BitGc());
DrawOpaqueMaskBackground(iStretchable);
//mask bitmaps
DrawBackground();
//draw caption if there is
//gc->SetClippingRegion(&ValidClipRegion()); //this cause crash in generic vkb
if(iCaption && iFont)
{
//use font
gc->UseFont(iFont);
gc->SetBrushStyle( CGraphicsContext::ENullBrush );
gc->SetPenStyle(CGraphicsContext::ESolidPen);
TRect rect(iRect);
//draw text shadow first
rect.Move(1,1);
TInt baseLine = iBaseline > 0 ? iBaseline :
rect.Height()*KDEFAULTBASELINERATIO;
//set pen color for text shadow
gc->SetPenColor(iCaptionShadowColor);
gc->DrawText(*iCaption,rect,baseLine,CGraphicsContext::ECenter );
//Now draw caption on top of the shadow
//re-cal the baseline
baseLine = iBaseline > 0 ? iBaseline :
iRect.Height()*KDEFAULTBASELINERATIO;
gc->SetPenColor(iCaptionColor);
gc->DrawText(*iCaption,iRect,baseLine,CGraphicsContext::ECenter );
gc->DiscardFont();
}
gc->CancelClipping();
}
// ---------------------------------------------------------------------------
// CButtonBase::HandleButtonDown
// Handle button down event
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C CFepUiBaseCtrl* CButtonBase::HandlePointerDownEventL(const TPoint& aPt)
{
if(iDimmed)
return NULL;
CFepUiBaseCtrl::HandlePointerDownEventL(aPt);
if(IsActive())
{
SetBackgroundBmp(iActiveBmpPressed);
SetBackgroundMaskBmp(iActiveMaskBmpPressed);
}
else
{
SetBackgroundBmp(iNonActiveBkBmpPressed);
SetBackgroundMaskBmp(iNonActiveBkMaskBmpPressed);
}
Draw();
UpdateArea(Rect(), EFalse);
ReportEvent(EEventButtonDown);
return this;
}
// ---------------------------------------------------------------------------
// CButtonBase::HandlePointerLeave
// Handle pointer leave event
// ---------------------------------------------------------------------------
//
EXPORT_C void CButtonBase::HandlePointerLeave(const TPoint& aPt)
{
if(iDimmed)
return;
if(IsActive())
{
SetBackgroundBmp(iActiveBmp);
SetBackgroundMaskBmp(iActiveMaskBmp);
}
else
{
SetBackgroundBmp(iNonActiveBkBmp);
SetBackgroundMaskBmp(iNonActiveBkMaskBmp);
}
Draw();
UpdateArea(Rect(), EFalse);
CFepUiBaseCtrl::HandlePointerLeave(aPt);
return ;
}
// ---------------------------------------------------------------------------
// CButtonBase::HandlePointerEnter
// Handle pointer enter event
// ---------------------------------------------------------------------------
//
EXPORT_C void CButtonBase::HandlePointerEnter(const TPoint& aPt)
{
if(iDimmed)
return;
if(IsActive())
{
SetBackgroundBmp(iActiveBmpPressed);
SetBackgroundMaskBmp(iActiveMaskBmpPressed);
}
else
{
SetBackgroundBmp(iNonActiveBkBmpPressed);
SetBackgroundMaskBmp(iNonActiveBkMaskBmpPressed);
}
Draw();
UpdateArea(Rect(), EFalse);
CFepUiBaseCtrl::HandlePointerEnter(aPt);
}
// ---------------------------------------------------------------------------
// CButtonBase::HandleButtonUpEventL
// Handle button up event
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C CFepUiBaseCtrl* CButtonBase::HandlePointerUpEventL(const TPoint& /*aPt*/)
{
if(iDimmed)
return NULL;
if(IsActive())
{
SetBackgroundBmp(iActiveBmp);
SetBackgroundMaskBmp(iActiveMaskBmp);
}
else
{
SetBackgroundBmp(iNonActiveBkBmp);
SetBackgroundMaskBmp(iNonActiveBkMaskBmp);
}
SetActive(ETrue);
Draw();
UpdateArea(Rect(), EFalse);
ReportEvent(EEventButtonUp);
return this;
}
// ---------------------------------------------------------------------------
// CButtonBase::HandleButtonMoveEventL
// Handle button move event
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C CFepUiBaseCtrl* CButtonBase::HandlePointerMoveEventL(const TPoint& /*aPt*/)
{
//do nothing
return this;
}
// ---------------------------------------------------------------------------
// CButtonBase::SetActive
// Set button active
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CButtonBase::SetActive(TBool aActiveFlag)
{
if(iDimmed)
return;
if(IsActive() != aActiveFlag)
{
CFepUiBaseCtrl::SetActive(aActiveFlag);
if(aActiveFlag)
{
SetBackgroundBmp(iActiveBmp);
SetBackgroundMaskBmp(iActiveMaskBmp);
}
else
{
SetBackgroundBmp(iNonActiveBkBmp);
SetBackgroundMaskBmp(iNonActiveBkMaskBmp);
}
if(BitGc())
{
Draw();
UpdateArea(Rect(),EFalse);
}
}
}
// ---------------------------------------------------------------------------
// CButtonBase::SetDimmed
// Dim button
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CButtonBase::SetDimmed(TBool aDimFlag)
{
if(iDimmed == aDimFlag)
return;
//Remove its active flag if dim an active button.
if(aDimFlag && IsActive())
SetActive(EFalse);
iDimmed = aDimFlag;
if(iDimmed)
{
SetBackgroundBmp(iDimmedBmp);
SetBackgroundMaskBmp(iDimmedMaskBmp);
}
else
{
// set the bmp according to current status
if(IsActive())
{
SetBackgroundBmp(iActiveBmp);
SetBackgroundMaskBmp(iActiveMaskBmp);
}
else
{
SetBackgroundBmp(iNonActiveBkBmp);
SetBackgroundMaskBmp(iNonActiveBkMaskBmp);
}
}
if(BitGc())
{
Draw();
UpdateArea(Rect(), EFalse);
}
#ifdef RD_TACTILE_FEEDBACK
if(IsKindOfControl(ECtrlTactileFeedback))
{
//if(aDimFlag)
UiLayout()->DeRegisterFeedbackArea(reinterpret_cast<TInt>(this),Rect());
if(!aDimFlag && !Hiden())
UiLayout()->RegisterFeedbackArea(reinterpret_cast<TInt>(this),Rect(),TactileFeedbackType());
}
#endif
}
// ---------------------------------------------------------------------------
// CButtonBase::SetBitmapL
// Set bitmap for given status
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CButtonBase::SetBitmapL(CFbsBitmap* aBitmap, TButtonBmpType aType)
{
CFbsBitmap* bmp = aBitmap;
if(!aBitmap)
return;
AddBmpToPool(aBitmap);
switch(aType)
{
case EBtnBmpNonActive :
{
iNonActiveBkBmp = bmp;
if(!IsActive())
SetBackgroundBmp(iNonActiveBkBmp);
}
break;
case EBtnBmpNonActivePressed :
iNonActiveBkBmpPressed = bmp;
break;
case EBtnBmpActive :
iActiveBmp = bmp;
if(IsActive())
SetBackgroundBmp(iActiveBmp);
break;
case EBtnBmpActivePressed :
iActiveBmpPressed = bmp;
break;
case EBtnBmpDimmed :
iDimmedBmp = bmp;
break;
default:
break;
}
}
// ---------------------------------------------------------------------------
// CButtonBase::Bitmap
// get bitmap for given type
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C CFbsBitmap* CButtonBase::Bitmap(TButtonBmpType aType, TBool aMaskFlag)
{
CFbsBitmap* bmp = NULL;
if(!aMaskFlag)
{
switch(aType)
{
case EBtnBmpNonActive :
{
bmp = iNonActiveBkBmp;
}
break;
case EBtnBmpNonActivePressed :
bmp = iNonActiveBkBmpPressed;
break;
case EBtnBmpActive :
bmp = iActiveBmp ;
break;
case EBtnBmpActivePressed :
bmp = iActiveBmpPressed;
break;
case EBtnBmpDimmed :
bmp = iDimmedBmp;
break;
default:
break;
}
}
else //get mask bitmap
{
switch(aType)
{
case EBtnBmpNonActive :
bmp = iNonActiveBkMaskBmp;
break;
case EBtnBmpNonActivePressed :
bmp = iNonActiveBkMaskBmpPressed;
break;
case EBtnBmpActive :
bmp = iActiveMaskBmp;
break;
case EBtnBmpActivePressed :
bmp = iActiveMaskBmpPressed;
break;
case EBtnBmpDimmed :
bmp = iDimmedMaskBmp;
break;
default:
break;
}
}
return bmp;
}
// ---------------------------------------------------------------------------
// CButtonBase::SetMaskBitmapL
// Set mask bitmap for given status
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CButtonBase::SetMaskBitmapL(CFbsBitmap* aBmp, TButtonBmpType aType)
{
if (!aBmp)
return;
AddBmpToPool(aBmp);
switch(aType)
{
case EBtnBmpNonActive :
iNonActiveBkMaskBmp = aBmp;
if(BkMaskBmp())
SetBackgroundMaskBmp(iNonActiveBkMaskBmp);
break;
case EBtnBmpNonActivePressed :
iNonActiveBkMaskBmpPressed = aBmp;
break;
case EBtnBmpActive :
iActiveMaskBmp = aBmp;
break;
case EBtnBmpActivePressed :
iActiveMaskBmpPressed = aBmp;
break;
case EBtnBmpDimmed :
iDimmedMaskBmp = aBmp;
break;
default:
break;
}
}
// ---------------------------------------------------------------------------
// CButtonBase::SetCaptionL
// Set mask bitmap for given status
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CButtonBase::SetCaptionL(const TDesC& aText)
{
TBool bRedraw(EFalse);
if(iCaption)
{
delete iCaption;
//already has a caption, redraw may be needed.
bRedraw = ETrue;
iCaption = NULL;
}
iCaption = aText.AllocL();
if(bRedraw)
{
Draw();
UpdateArea(iRect, EFalse);
}
}
// ---------------------------------------------------------------------------
// CButtonBase::SetFont
// Set caption font
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CButtonBase::SetFont(const TFontSpec& aFontSpec)
{
iFontSpec = aFontSpec;
//release old font
if(iFontOwnership && iFont)
{
BitmapDevice()->ReleaseFont(iFont);
iFont = NULL;
}
iFontOwnership = ETrue;
if(BitmapDevice())
{
if (KErrNone != BitmapDevice()->GetNearestFontInPixels(iFont,iFontSpec))
iFont = NULL;
}
}
// ---------------------------------------------------------------------------
// CButtonBase::SetFont
// Set caption font
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CButtonBase::SetFont(const CFont* aFont)
{
if(iFontOwnership && iFont)
{
BitmapDevice()->ReleaseFont(iFont);
}
iFontOwnership = EFalse;
iFont = const_cast<CFont*>(aFont);
if(iFont)
iFontSpec = iFont->FontSpecInTwips();
}
// ---------------------------------------------------------------------------
// CButtonBase::ResetBmpPool
// Rest bitmap pool
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CButtonBase::ResetBmpPool()
{
iBmpPool.ResetAndDestroy();
//must reset the background bmp otherwise CFepUiBaseCtrl will re-delete it.
SetBackgroundBmp(NULL);
SetBackgroundMaskBmp(NULL);
}
// ---------------------------------------------------------------------------
// CButtonBase::SetBackgroundBitmapL
// Set back ground bitmap
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CButtonBase::SetBackgroundBitmapL(CFbsBitmap* aBmp)
{
if(!aBmp)
return;
AddBmpToPool(aBmp);
SetBackgroundBmp(aBmp);
}
// ---------------------------------------------------------------------------
// CButtonBase::SetBackgroundMaskBitmapL
// Set back ground mask bitmap
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CButtonBase::SetBackgroundMaskBitmapL(CFbsBitmap* aBmp)
{
if(!aBmp)
return;
AddBmpToPool(aBmp);
SetBackgroundMaskBmp(aBmp);
}
EXPORT_C void CButtonBase::Hide(TBool aFlag)
{
CFepUiBaseCtrl::Hide(aFlag);
#ifdef RD_TACTILE_FEEDBACK
if(IsKindOfControl(ECtrlTactileFeedback))
{
if(aFlag || iDimmed)
UiLayout()->DeRegisterFeedbackArea(reinterpret_cast<TInt>(this),Rect());
}
#endif
}
// ---------------------------------------------------------------------------
// CButtonBase::AddBmpToPool
// add a bitmap to pool
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CButtonBase::AddBmpToPool(CFbsBitmap* aBmp)
{
//do we already has the bitmap?
if(KErrNotFound == iBmpPool.Find(aBmp))
{
TRAP_IGNORE(iBmpPool.AppendL(aBmp));
}
}
/********************** end of CButtonBase ****************************/
/******************** Implementation of CDragBar ************************/
// ---------------------------------------------------------------------------
// CDragBar::NewL
// factory function
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C CDragBar* CDragBar::NewL(const TRect& aRect,CFepUiLayout* aUiLayout,
TInt aCtrlId)
{
CDragBar* btn = new (ELeave)CDragBar(aRect,aUiLayout,aCtrlId);
CleanupStack::PushL(btn);
btn->ConstructL ();
CleanupStack::Pop(btn);
return btn;
}
// ---------------------------------------------------------------------------
// CDragBar::~CDragBar
// Destructor
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C CDragBar::~CDragBar()
{
iPosObserverList.Close();
delete iLongPressTimer;
delete iMoveTimer;
iLongPressTimer = NULL;
iDraggingCtrlList.Close();
}
// ---------------------------------------------------------------------------
// CDragBar::CDragBar
// Constructor
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C CDragBar::CDragBar(const TRect& aRect,CFepUiLayout* aUiLayout,
TInt aCtrlId)
:CButtonBase(aRect,aUiLayout,aCtrlId),
iIsDragging(EFalse),iMoved(EFalse),
iLayoutBeingDraged(EFalse),iNeedLongtimePress(EFalse),
iDraggingEnabled(ETrue),iDrawInterval(KSpriteMoveDrawInterval)
{
SetControlType(ECtrlDragBar);
iDragFrameRect = Rect();
SetPenSize(TSize(KDefaultFrameWidth,KDefaultFrameWidth));
iMovingIndicatorPos = aRect.iTl + PenSize();
}
// ---------------------------------------------------------------------------
// CDragBar::ConstructL
// Second phase constructor
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CDragBar::ConstructL()
{
BaseConstructL();
iLongPressTimer = CLayoutTimer::NewL(this,CLayoutTimer::ELongPressTimer);
iMoveTimer = CLayoutTimer::NewL(this,CLayoutTimer::EDragbarMoveTimer,ETrue);
iMoveTimer->SetPriority(CActive::EPriorityHigh);
AddPositionObserver(this);//add itself to be an position change observer
}
// ---------------------------------------------------------------------------
// CDragBar::HandleButtonDownEventL
// Handle pen down event in dragbar
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C CFepUiBaseCtrl* CDragBar::HandlePointerDownEventL(const TPoint& aPt)
{
if(!iDraggingEnabled) //not support dragging
{
CButtonBase::HandlePointerDownEventL(aPt);
return this;
}
//call base class to set state
CFepUiBaseCtrl::HandlePointerDownEventL(aPt);
//init status
iLongPressed = EFalse;
iMoved = EFalse;
iMoveOffset = TPoint(0,0);
iDraggingStartPt = aPt;
if(iLayoutBeingDraged)
{
//change draging start point to absolute point in layout dragging
iDraggingStartPt += UiLayout()->Position();
}
iCurrentPointerPos = aPt;
CapturePointer();
if(iNeedLongtimePress)
{
iIsDragging = EFalse;
iLongPressTimer->SetTimer(iLongtimePressTimeout);
}
else
{
//report event first, so other controls can prepare for dragging
ReportEvent(EEventDraggingStart);
iIsDragging = ETrue;
PrepareDragging();
#ifdef __USING_MOVING_FRAME__
DrawFrame(iDragFrameRect);
ShowMovingIndicator();
RootControl()->UpdateArea(iDragFrameRect, EFalse);
#endif
iMoveTimer->SetTimer(iDrawInterval);
}
return this;
}
// ---------------------------------------------------------------------------
// CDragBar::HandleButtonUpEventL
// Handle pen up event in dragbar
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C CFepUiBaseCtrl* CDragBar::HandlePointerUpEventL(const TPoint& aPt)
{
CapturePointer(EFalse);
if(!PointerDown())
return this;
if(!iDraggingEnabled)
{
return CButtonBase::HandlePointerUpEventL(aPt);
}
SetPointerDown(EFalse);
if(iNeedLongtimePress)
{
iLongPressTimer->Cancel();
iLongPressed = EFalse;
}
if(iIsDragging)
{
iIsDragging=EFalse;
iMoveTimer->Cancel();
AfterDragging();
ReportEvent(EEventDraggingEnd);
//Clear the frame of the last drawing
TRect rect;
#ifdef __USING_MOVING_FRAME__
rect = DrawFrame(iDragFrameRect,EFalse);
rect.BoundingRect(rect);
#endif
for(TInt i = iPosObserverList.Count()-1; i >= 0; i--)
{
if(iPosObserverList[i]->HandlePositionChange(iMoveOffset))
break;
}
#ifdef __USING_MOVING_FRAME__
if(iLayoutBeingDraged) //special handling when layout is Dragging
{
RootControl()->Draw();
}
else
{
//redraw the component.
RootControl()->DrawRect(rect,EFalse); //not draw the frame
UpdateArea(rect, EFalse);
}
RootControl()->UpdateValidRegion(NULL,EFalse);
#endif
iMoveOffset = TPoint(0,0);
}
else
{
if(iNeedLongtimePress)
{
ReportEvent(EEventButtonUp);
}
}
return this;
}
// ---------------------------------------------------------------------------
// CDragBar::HandleButtonMoveEventL
// Handle dragbar move event
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C CFepUiBaseCtrl* CDragBar::HandlePointerMoveEventL(const TPoint& aPt)
{
if(!iDraggingEnabled) //dragging not allowed
{
CButtonBase::HandlePointerMoveEventL(aPt);
return this;
}
if(!iIsDragging)
{
if(PointerDown())
{
iCurrentPointerPos = aPt;
}
}
else // being dragging
{
TBool verticalMove(EFalse);
TBool horizontalMove(EFalse);
if(iLayoutBeingDraged) //special handling when layout is Dragging
{
TRect dragRect(Rect());
//convert to screen coordinate
dragRect.Move(UiLayout()->Position());
TPoint pt = aPt + UiLayout()->Position();
TPoint offset = pt-iDraggingStartPt;
dragRect.Move(offset + iMoveOffset);
//check whether dragRect is a valid position
if(!UiLayout()->IsValidDestination(dragRect,this,verticalMove,
horizontalMove,ETrue))
{
// Not valid, then check H and V direction separately
if(verticalMove) //V is valid then H is not.
{
//set x offset to 0
offset.iX = 0;
}
else
{
if(horizontalMove)//H is valid then V is not.
{
// set y offset to 0
offset.iY = 0;
}
else
{
offset = TPoint(0,0);//return this;
//not valid in both direction. Can't move
}
}
}
iDraggingStartPt += offset;
iMoveOffset += offset;
ReportEvent(EEventDragging);
return this;
}
else //component moving inside layout area
{
if(IsValidDestination(aPt,verticalMove,horizontalMove))
{
iCurrentPointerPos = aPt;
ReportEvent(EEventDragging);
}
else
{
// Not valid, then check H and V direction separately
if(verticalMove)
{
//vertical move is allowed
iCurrentPointerPos.iY = aPt.iY;
}
else
{
if(horizontalMove)
{
//horizontal move is allowed
iCurrentPointerPos.iX = aPt.iX;
}
}
}
}
}
//When Dragging, eats the move event even it's not a valid destination
return this;
}
// ---------------------------------------------------------------------------
// CDragBar::IsValidDestination
// Test whether the destination is valid for dragbar
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C TBool CDragBar::IsValidDestination(const TPoint& aPt,TBool& aVInfo,
TBool& aHInfo)
{
TRect rect(iDragFrameRect);
TPoint offset(aPt-iDraggingStartPt);
rect.Move(offset);
return UiLayout()->IsValidDestination(rect,this,aVInfo,aHInfo,
iLayoutBeingDraged);
}
// ---------------------------------------------------------------------------
// CDragBar::Move
// Move control
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CDragBar::Move(const TPoint& aOffset)
{
CFepUiBaseCtrl::Move(aOffset);
iMovingIndicatorPos += aOffset;
iMoved = ETrue;
}
// ---------------------------------------------------------------------------
// CDragBar::AddPositionObserver
// Add position change observer
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CDragBar::AddPositionObserver(MPositionObserver* aObserver)
{
if(!aObserver)
return;
//is it already an observer?
if(KErrNotFound != iPosObserverList.Find(aObserver))
{
return; // do nothing
}
if(aObserver == static_cast<MPositionObserver*>(RootControl()) )
{
iLayoutBeingDraged = ETrue;
}
iPosObserverList.Append(aObserver);
iDragFrameRect.BoundingRect(aObserver->MovingArea());
if(aObserver->IsFepBaseControl())
{
CFepUiBaseCtrl* ctrl=static_cast<CFepUiBaseCtrl*>(aObserver);
ctrl->AddEventObserver(this);
}
}
// ---------------------------------------------------------------------------
// CDragBar::AddToDraggingCtrlList
// Add a control to dragging list
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CDragBar::AddToDraggingCtrlList(CFepUiBaseCtrl* aCtrl)
{
if(!aCtrl->Ready())
return;
if(aCtrl->IsKindOfControl(ECtrlControlGroup))
{
CControlGroup* group = reinterpret_cast<CControlGroup*>(aCtrl);
RPointerArray<CFepUiBaseCtrl> ctrlList = group->ControlList();
for(TInt i = 0; i < ctrlList.Count(); i++)
{
if(ctrlList[i]->Ready())
AddToDraggingCtrlList(ctrlList[i]);
}
}
else
{
if(aCtrl->Ready()) //root control is not included
iDraggingCtrlList.Append(aCtrl);
}
}
// ---------------------------------------------------------------------------
// CDragBar::PrepareDragging
// Change dragging control's state before dragging
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CDragBar::PrepareDragging()
{
TInt i;
//re-calculate the dragging area
ReCalculateDragArea();
iDraggingCtrlList.Reset();
for( i = 0; i < iPosObserverList.Count(); i++)
{
if(iPosObserverList[i]->IsFepBaseControl())
{
CFepUiBaseCtrl* ctrl=static_cast<CFepUiBaseCtrl*>(
iPosObserverList[i]);
if(ctrl != RootControl())
{
AddToDraggingCtrlList(ctrl);
}
}
}
for(i = 0; i < iDraggingCtrlList.Count(); i++)
{
iDraggingCtrlList[i]->SetReady(EFalse);
}
}
// ---------------------------------------------------------------------------
// CDragBar::AfterDragging
// Change dragging control's state after dragging
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CDragBar::AfterDragging()
{
TInt i;
for(i = 0; i < iDraggingCtrlList.Count(); i++)
{
iDraggingCtrlList[i]->SetReady(ETrue);
}
}
// ---------------------------------------------------------------------------
// CDragBar::RemovePositionObserver
// Remove position change observer
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CDragBar::RemovePositionObserver(MPositionObserver* aObserver)
{
TInt index = iPosObserverList.Find(aObserver);
if(KErrNotFound != index)
{
if(aObserver == RootControl())
iLayoutBeingDraged = EFalse;
iPosObserverList.Remove(index);
//re-calculate the moving rect
iDragFrameRect = Rect();
for(TInt i = 0; i < iPosObserverList.Count(); i++)
iDragFrameRect.BoundingRect(iPosObserverList[i]->MovingArea());
}
}
// ---------------------------------------------------------------------------
// CDragBar::SetLongpressTimer
// Set long time press time out
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CDragBar::SetLongpressTimer(TTimeIntervalMicroSeconds32 aTime)
{
if(aTime.Int() <= 0)
iNeedLongtimePress = EFalse;
else
{
iNeedLongtimePress = ETrue;
iLongtimePressTimeout = aTime;
}
}
// ---------------------------------------------------------------------------
// CDragBar::HandleTimerOut
// Handle long press time out event
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CDragBar::HandleTimerOut(TInt aTimeType)
{
switch(aTimeType)
{
//long press timeout
case CLayoutTimer::ELongPressTimer:
if(PointerDown() && Contains(iCurrentPointerPos))
{
//report event
ReportEvent(EEventButtonLongPress);
//report event first
ReportEvent(EEventDraggingStart);
iLongPressed = ETrue;
iIsDragging = ETrue;
//need redraw to show that moving starts
PrepareDragging();
#ifdef __USING_MOVING_FRAME__
TRect dirtyRect = DrawFrame(iDragFrameRect);
ShowMovingIndicator();
UpdateArea(dirtyRect, EFalse);
#endif
iMoveTimer->SetTimer(iDrawInterval);
}
break;
case CLayoutTimer::EDragbarMoveTimer:
if(iLayoutBeingDraged)
{
static_cast<MPositionObserver*>(RootControl())->
HandlePositionChange(iMoveOffset);
iMoveOffset = TPoint(0,0);
}
else
{
//clear previous frame rect
TRect rect = DrawFrame(iDragFrameRect,EFalse);
TPoint offset = iCurrentPointerPos - iDraggingStartPt;
iMoveOffset += offset;
iDragFrameRect.Move(offset);
#ifdef __USING_MOVING_FRAME__
TRect dirtyRect = DrawFrame(iDragFrameRect);
ShowMovingIndicator();
rect.BoundingRect(dirtyRect);
#else
rect = iDragFrameRect;
#endif
iDraggingStartPt = iCurrentPointerPos;
UpdateArea(rect, EFalse);
}
break;
default:
break;
}
}
// ---------------------------------------------------------------------------
// CDragBar::ReCalculateDragArea
// Update moving area.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CDragBar::ReCalculateDragArea()
{
iDragFrameRect = Rect();
for(TInt i = 0; i < iPosObserverList.Count(); i++)
{
iDragFrameRect.BoundingRect(
iPosObserverList[i]->MovingArea());
}
}
// ---------------------------------------------------------------------------
// CDragBar::HandleControlEvent
// Handle event from control which being observed
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CDragBar::HandleControlEvent(TInt aEventType, CFepUiBaseCtrl* aCtrl,
const TDesC& /*aEventData*/)
{
//only handle control size event change
switch(aEventType)
{
case EEventSizeChanged:
{
if(aCtrl && !aCtrl->Hiden())
{
/* TInt index = iPosObserverList.Find(aCtrl);
if(KErrNotFound != index)
{
//recaculate the bounding rect
ReCalculateDragArea();
} */
if(aCtrl == this)
{
iMovingIndicatorPos = Rect().iTl + PenSize();
}
}
}
break;
default:
break;
}
}
// ---------------------------------------------------------------------------
// CDragBar::SetBitmapL
// Set bitmap for given status
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CDragBar::SetBitmapL(CFbsBitmap* aBitmap, TButtonBmpType aType)
{
CFbsBitmap* bmp = aBitmap;
if(!aBitmap)
return;
if(EBtnBmpMovingIndicator == aType)
{
iMovingIndicatorBmp = bmp;
iMovingIndicatorPos = Rect().iTl + PenSize();
}
CButtonBase::SetBitmapL(bmp,aType);
}
// ---------------------------------------------------------------------------
// CDragBar::ShowMovingIndicator
// Show dragging indicator
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CDragBar::ShowMovingIndicator(TBool aDrawFlag)
{
if(iMovingIndicatorBmp && aDrawFlag)
{
CFbsBitGc* gc = static_cast<CFbsBitGc*>(BitGc());
TSize bmpSize = iMovingIndicatorBmp->SizeInPixels();
bmpSize -= PenSize();
TRect bmpRect(TPoint(0,0),bmpSize);
TPoint bmpPos = iMovingIndicatorPos + iMoveOffset;
gc->Activate( MaskBitmapDevice() );
gc->SetBrushStyle( CGraphicsContext::ESolidBrush );
gc->SetBrushColor( TRgb(KOpaqueColor) );
TRect rect = bmpRect;
rect.Move(bmpPos);
gc->DrawRect(rect);
//mask will not be used if no bmp
if(iMovingIndicatorMaskBmp)
{
gc->BitBlt(bmpPos,iMovingIndicatorMaskBmp,bmpRect);
}
gc->Activate( BitmapDevice() );
gc->SetBrushColor( KRgbWhite );
gc->BitBlt(bmpPos,iMovingIndicatorBmp,bmpRect);
}
}
// ---------------------------------------------------------------------------
// CDragBar::DrawFrame
// Draw moving frame
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TRect CDragBar::DrawFrame(const TRect& aFrameRect, TBool aDrawFlag)
{
return RootControl()->DrawFrame(aFrameRect,aDrawFlag);
}
// ---------------------------------------------------------------------------
// CDragBar::SetMaskBitmapL
// Set bitmap for given status
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CDragBar::SetMaskBitmapL(CFbsBitmap* aBitmap, TButtonBmpType aType)
{
if(!aBitmap)
return;
switch(aType)
{
case EBtnBmpMovingIndicator:
iMovingIndicatorMaskBmp = aBitmap;
break;
default:
CButtonBase::SetBitmapL(aBitmap,aType);
break;
}
}
// ---------------------------------------------------------------------------
// CDragBar::IsDraggingComponent
// Test whether this control belongs to a dragbar
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C TBool CDragBar::IsDraggingComponent(CFepUiBaseCtrl* aControl)
{
for(TInt i = 0; i < iPosObserverList.Count(); i++)
{
if(aControl == iPosObserverList[i])
return ETrue;
}
return EFalse;
}
// ---------------------------------------------------------------------------
// CDragBar::OnDeActivate
// Response to layout de activation event
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CDragBar::OnDeActivate()
{
//simulates a pointer up event to end the draging.
TRAP_IGNORE(HandlePointerUpEventL(TPoint(0,0)));
CFepUiBaseCtrl::OnDeActivate();
}
// ---------------------------------------------------------------------------
// CDragBar::CancelPointerDownL
// Cancel pointer down event
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
EXPORT_C void CDragBar::CancelPointerDownL()
{
HandlePointerUpEventL(TPoint(0,0));
}
//end of CDragBar