javauis/lcdui_akn/lcdui/src/CMIDCustomItem.cpp
branchRCL_3
changeset 19 04becd199f91
child 60 6c158198356e
equal deleted inserted replaced
16:f5050f1da672 19:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  ?Description
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <coemain.h>
       
    20 #include <eiklabel.h>
       
    21 #include <hal.h>
       
    22 #include <AknsDrawUtils.h>// skin
       
    23 #include <AknsBasicBackgroundControlContext.h> //skin
       
    24 
       
    25 #ifdef RD_INTELLIGENT_TEXT_INPUT
       
    26 #include <PtiEngine.h>
       
    27 #endif //RD_INTELLIGENT_TEXT_INPUT
       
    28 
       
    29 #include "CMIDForm.h"
       
    30 #include "CMIDFormPhysics.h"
       
    31 #include "CMIDCustomItem.h"
       
    32 // API for iLabelControl
       
    33 #include "CMIDItemLabel.h"
       
    34 // API needed for retrieving current displayable from iForm when background drawing
       
    35 #include "CMIDDisplayable.h"
       
    36 
       
    37 // retrieving CMIDRemConObserver from CMIDKeyDecoder
       
    38 #include "CMIDKeyDecoder.h"
       
    39 // needed for adding (removing) media keys observer to remConObserver
       
    40 #include "CMIDRemConObserver.h"
       
    41 #include "CMIDUIManager.h"
       
    42 #include <eikenv.h>
       
    43 #include <j2me/jdebug.h>
       
    44 
       
    45 // LAF
       
    46 // AknLayoutScalable_Avkon::form2_midp_content_pane
       
    47 #include <aknlayoutscalable_avkon.cdl.h>
       
    48 
       
    49 #ifdef RD_JAVA_ADVANCED_TACTILE_FEEDBACK
       
    50 #include <touchfeedback.h>
       
    51 #endif //RD_JAVA_ADVANCED_TACTILE_FEEDBACK
       
    52 
       
    53 /** The custom item uses a different value for limiting the max sizes because
       
    54 it needs to draw bitmaps with these sizes. @see KMaxScreenSizeFactor */
       
    55 const TInt KCIMaxScreenSizeFactor = 2;
       
    56 
       
    57 CMIDCustomItem* CMIDCustomItem::NewL(
       
    58     MMIDEnv& aEnv, const TDesC& aLabel, CMIDUIManager* aUIManager)
       
    59 {
       
    60     CMIDCustomItem* item = new(ELeave) CMIDCustomItem(aEnv, aUIManager);
       
    61     CleanupStack::PushL(item);
       
    62     item->ConstructL(aLabel);
       
    63     CleanupStack::Pop(item);
       
    64     return item;
       
    65 }
       
    66 
       
    67 CMIDCustomItem::CMIDCustomItem(MMIDEnv& aEnv, CMIDUIManager* aUIManager)
       
    68         : CMIDControlItem(EDefault, aUIManager)
       
    69         , iEntered(EFalse)
       
    70         , iSupportsInternalTraversal(ETrue)
       
    71         , iEnv(aEnv)
       
    72         , iResetFrameBuffer(ETrue)
       
    73         , iDirectAreaAddedToDisplayable(EFalse)
       
    74         , iS60SelectionKeyCompatibility(EFalse)
       
    75 #ifndef RD_JAVA_NGA_ENABLED
       
    76         , iDirectPaused(ETrue)
       
    77 #endif
       
    78         , iRestoreDirectContentWhenUnfaded(EFalse)
       
    79         , iPreviousVisibility(EFalse)
       
    80         , iConsumerWaitingForDSAResourcesCallback(NULL)
       
    81 {
       
    82     iMMidItem = this;
       
    83 
       
    84     //Default values for PointerEventSuppressor
       
    85     iPESPointerMovementInTwips = CMIDUIManager::EPESPointerMovementInTwips;
       
    86     iPESTimeInMilliseconds = CMIDUIManager:: EPESTimeInMilliseconds;
       
    87 }
       
    88 
       
    89 void CMIDCustomItem::ConstructL(const TDesC& aLabel)
       
    90 {
       
    91     DEBUG("< CMIDCustomItem::ConstructL");
       
    92 
       
    93     CMIDControlItem::ConstructL();
       
    94     SetLabelL(aLabel);
       
    95     UpdateMargins();
       
    96     ActivateL();
       
    97 
       
    98     // CustomItem listens media key events if CMIDRemConObserver is initialized and media keys keys are enabled
       
    99     ASSERT(iMenuHandler);
       
   100     ASSERT(iUIManager);
       
   101     iKeyDecoder = iUIManager->OpenKeyDecoderL();
       
   102     ASSERT(iKeyDecoder);
       
   103     iRemConObserver = iKeyDecoder->GetRemConObserver();
       
   104     if (iRemConObserver && iKeyDecoder->MediaKeysEnabled())
       
   105     {
       
   106         iRemConObserver->AddMediaKeysListenerL(static_cast<MMIDMediaKeysListener*>(this));
       
   107     }
       
   108 
       
   109 #ifdef RD_TACTILE_FEEDBACK
       
   110     iTactileFeedback = new(ELeave) CMIDTactileFeedbackExtension(this, 2);
       
   111 #endif
       
   112     //Create PointerEventSuppressor with default values or JAD parameter defined values
       
   113     iPointerEventSuppressor = CAknPointerEventSuppressor::NewL();
       
   114     TInt pointerMovementInPixels =
       
   115         ControlEnv()->ScreenDevice()->HorizontalTwipsToPixels(iPESPointerMovementInTwips);
       
   116     TSize suppressorValues =
       
   117         iUIManager->ReadPointerEventSuppressorValues();
       
   118     if (!(suppressorValues.iWidth == KPESErrorValue &&
       
   119             suppressorValues.iHeight == KPESErrorValue))
       
   120     {
       
   121         iPESTimeInMilliseconds = suppressorValues.iHeight;
       
   122         pointerMovementInPixels =
       
   123             ControlEnv()->ScreenDevice()->HorizontalTwipsToPixels(suppressorValues.iWidth);
       
   124     }
       
   125     iPointerEventSuppressor->SetMaxTapDuration(iPESTimeInMilliseconds * 1000);
       
   126     iPointerEventSuppressor->SetMaxTapMove(TSize(pointerMovementInPixels,
       
   127                                            pointerMovementInPixels));
       
   128 
       
   129     DEBUG("> CMIDCustomItem::ConstructL");
       
   130 }
       
   131 
       
   132 void  CMIDCustomItem::UpdateMargins()
       
   133 {
       
   134     TAknWindowLineLayout layout =
       
   135         AknLayoutScalable_Avkon::form2_midp_content_pane(1).LayoutLine();
       
   136 
       
   137     iContentMargins.iTop    = layout.it;
       
   138     iContentMargins.iLeft   = layout.il;
       
   139     iContentMargins.iRight  = layout.ir;
       
   140     iContentMargins.iBottom = layout.ib;
       
   141 
       
   142 }
       
   143 
       
   144 /** */
       
   145 void CMIDCustomItem::ResetBuffers()
       
   146 {
       
   147     delete iFrameBuffer;
       
   148     delete iFrameContext;
       
   149     delete iFrameDevice;
       
   150 
       
   151     iFrameBuffer  = NULL;
       
   152     iFrameContext = NULL;
       
   153     iFrameDevice  = NULL;
       
   154 
       
   155     delete iOffScreenBuffer;
       
   156     delete iOffScreenContext;
       
   157     delete iOffScreenDevice;
       
   158 
       
   159     iOffScreenBuffer  = NULL;
       
   160     iOffScreenContext = NULL;
       
   161     iOffScreenDevice  = NULL;
       
   162 }
       
   163 
       
   164 /** Creates the frame buffer with its associated device and context and the
       
   165 offscreen buffer with its device and context. They are both of the same size,
       
   166 the size of the content rect. The skin background is then printed on the
       
   167 frame buffer via the frame context.
       
   168 
       
   169 Note: This method is called each time the content size changes. If it leaves
       
   170 it is trapped in SizeChanged() and then ResetBuffers() is called so that we
       
   171 are not left in an unconsistent situation in Out Of Memory. So care must be
       
   172 taken in the code to always check that the buffers or their devices or contextes
       
   173 do exist - because they may not exist in OOM.
       
   174 */
       
   175 void CMIDCustomItem::CreateBuffersL()
       
   176 {
       
   177     DEBUG("< CMIDCustomItem::CreateBuffersL");
       
   178     ResetBuffers();
       
   179 
       
   180     TRect rect = TRect(0,0,iContentRect.Size().iWidth, iContentRect.Size().iHeight);
       
   181 
       
   182     iFrameBuffer = new(ELeave) CFbsBitmap;
       
   183     User::LeaveIfError(iFrameBuffer->Create(rect.Size(), iEnv.DisplayMode()));
       
   184 
       
   185     iFrameDevice = CFbsBitmapDevice::NewL(iFrameBuffer);
       
   186     User::LeaveIfError(iFrameDevice->CreateContext(iFrameContext));
       
   187 
       
   188     iOffScreenBuffer = new(ELeave) CFbsBitmap;
       
   189     User::LeaveIfError(iOffScreenBuffer->Create(rect.Size(), iEnv.DisplayMode()));
       
   190 
       
   191     iOffScreenDevice = CFbsBitmapDevice::NewL(iOffScreenBuffer);
       
   192     User::LeaveIfError(iOffScreenDevice->CreateContext(iOffScreenContext));
       
   193 
       
   194     if (iForm)
       
   195     {
       
   196         AknsDrawUtils::DrawBackground(AknsUtils::SkinInstance(),
       
   197                                       iForm->CurrentDisplayable().BackGroundControlContext(), this,
       
   198                                       *iFrameContext, TPoint(0,0), iContentRect, KAknsDrawParamDefault);
       
   199     }
       
   200     DEBUG("> CMIDCustomItem::CreateBuffersL");
       
   201 }
       
   202 
       
   203 // Start Direct screen access in order to switch off Transition effects,
       
   204 // which could damage the DSA (video)
       
   205 void CMIDCustomItem::SetContainerWindowL(const CCoeControl& aWindow)
       
   206 {
       
   207     DEBUG("< CMIDCustomItem::SetContainerWindowL");
       
   208 #ifndef RD_JAVA_NGA_ENABLED
       
   209     if (iDirectAccess)
       
   210     {
       
   211         iDirectAccess->Cancel();
       
   212         delete iDirectAccess;
       
   213         iDirectAccess = NULL;
       
   214     }
       
   215 #endif
       
   216 
       
   217     CMIDControlItem::SetContainerWindowL(aWindow);
       
   218 
       
   219 #ifndef RD_JAVA_NGA_ENABLED
       
   220     RWsSession&      session = ControlEnv()->WsSession();
       
   221     CWsScreenDevice* device  = ControlEnv()->ScreenDevice();
       
   222 
       
   223     iDirectAccess = CDirectScreenAccess::NewL(
       
   224                         session,
       
   225                         *device,
       
   226                         *DrawableWindow(),
       
   227                         *this
       
   228                     );
       
   229 #endif
       
   230 
       
   231     if (iConsumerWaitingForDSAResourcesCallback)
       
   232     {
       
   233         // Invoke the pending callback from LCDUI ES thread
       
   234         iEnv.ToLcduiObserver().InvokeDSAResourcesCallback(
       
   235             *this, *iConsumerWaitingForDSAResourcesCallback);
       
   236         iConsumerWaitingForDSAResourcesCallback = NULL;
       
   237     }
       
   238 
       
   239     DEBUG("> CMIDCustomItem::SetContainerWindowL");
       
   240 }
       
   241 
       
   242 CMIDCustomItem::~CMIDCustomItem()
       
   243 {
       
   244     DEBUG("< CMIDCustomItem::~CMIDCustomItem");
       
   245     if (iDirectContent)
       
   246     {
       
   247         iDirectContent->MdcContainerDestroyed();
       
   248     }
       
   249 
       
   250 #ifndef RD_JAVA_NGA_ENABLED
       
   251     if (iDirectAccess)
       
   252     {
       
   253         iDirectAccess->Cancel();
       
   254         delete iDirectAccess;
       
   255         iDirectAccess = NULL;
       
   256     }
       
   257 #endif
       
   258 
       
   259     ResetBuffers();
       
   260 
       
   261     // CustomItem removes itself from the CMIDRemConObserver.
       
   262     ASSERT(iKeyDecoder);
       
   263     if (iRemConObserver && iKeyDecoder->MediaKeysEnabled())
       
   264     {
       
   265         iRemConObserver->RemoveMediaKeysListener(static_cast<MMIDMediaKeysListener*>(this));
       
   266     }
       
   267 #ifdef RD_TACTILE_FEEDBACK
       
   268     delete iTactileFeedback;
       
   269 #endif
       
   270 
       
   271     if (iPointerEventSuppressor)
       
   272     {
       
   273         delete iPointerEventSuppressor;
       
   274         iPointerEventSuppressor = NULL;
       
   275     }
       
   276 
       
   277     DEBUG("> CMIDCustomItem::~CMIDCustomItem");
       
   278 }
       
   279 
       
   280 /**
       
   281  *
       
   282  */
       
   283 TInt CMIDCustomItem::ItemPreferredHeightWithoutLabel()
       
   284 {
       
   285     return PreferredContentSize().iHeight + iContentMargins.iTop + iContentMargins.iBottom;
       
   286 }
       
   287 
       
   288 /**
       
   289  * Gets the available interaction modes. This method is intended to be called by
       
   290  * CustomItem subclass code in order for it to determine what kinds of input are
       
   291  * available from this device
       
   292  */
       
   293 TInt CMIDCustomItem::InteractionModes() const
       
   294 {
       
   295     DEBUG("< CMIDCustomItem::InteractionModes");
       
   296     TInt modes = 0;
       
   297 
       
   298     if (AknLayoutUtils::PenEnabled())
       
   299     {
       
   300         // Drag is not supported if physics scrolling is in use
       
   301         if (CMIDFormPhysics::FeatureEnabled())
       
   302         {
       
   303             modes |= ETraverseHorizontal | ETraverseVertical |
       
   304                      EPointerPress | EPointerRelease;
       
   305         }
       
   306         else
       
   307         {
       
   308             modes |= ETraverseHorizontal | ETraverseVertical |
       
   309                      EPointerPress | EPointerRelease | EPointerDrag;
       
   310         }
       
   311     }
       
   312 
       
   313     TRAP_IGNORE(modes |= KeyboardInteractionModesL());
       
   314 
       
   315     DEBUG_INT("> CMIDCustomItem::InteractionModes = %d", modes);
       
   316     return modes;
       
   317 }
       
   318 
       
   319 TInt CMIDCustomItem::KeyboardInteractionModesL() const
       
   320 {
       
   321     DEBUG("< CMIDCustomItem::KeyboardInteractionModesL");
       
   322     TInt modes = 0;
       
   323 
       
   324 #ifdef RD_INTELLIGENT_TEXT_INPUT
       
   325     RArray<TPtiKeyboardType> keyboards;
       
   326     CleanupClosePushL(keyboards);
       
   327 
       
   328     CPtiEngine* ptiEngine = CPtiEngine::NewL();
       
   329     CleanupStack::PushL(ptiEngine);
       
   330 
       
   331     ptiEngine->ListAvailablePhysicalKeyboardsL(keyboards);
       
   332 
       
   333     if (keyboards.Count() > 0)
       
   334     {
       
   335         modes |= ETraverseHorizontal | ETraverseVertical |
       
   336                  EKeyPress | EKeyRelease | EKeyRepeat;
       
   337     }
       
   338 
       
   339     CleanupStack::PopAndDestroy(ptiEngine);
       
   340     CleanupStack::PopAndDestroy(&keyboards);
       
   341 #endif //RD_INTELLIGENT_TEXT_INPUT    
       
   342 
       
   343     DEBUG_INT("> CMIDCustomItem::KeyboardInteractionModesL = %d", modes);
       
   344     return modes;
       
   345 }
       
   346 
       
   347 TBool CMIDCustomItem::SupportsInternalTraversal() const
       
   348 {
       
   349     return iSupportsInternalTraversal;
       
   350 }
       
   351 
       
   352 /**
       
   353  * This is a return value from Traverse method in Java.
       
   354  * It returns whether it should traverse within the CustomItem and Rect that it should
       
   355  * traverse to until it returns false and traverse out of CustomItem
       
   356  */
       
   357 void CMIDCustomItem::SetFocusAndScroll(TBool aFocus,const TRect* aRect,TInt aDirection)
       
   358 {
       
   359     DEBUG("< CMIDCustomItem::SetFocusAndScroll");
       
   360     // Make sure we know if this CustomItem subclass supports internal traversal.
       
   361 
       
   362     // When the item is entered for the very first time, check what the traverse
       
   363     // method returned. If false, there is no internal traversal and we will
       
   364     // handle this based on aFocus.
       
   365     // If true, the item supports internal traversal and additional code is needed
       
   366     if (!iEntered)
       
   367     {
       
   368         // iSupportsInternalTraversal is sampled on the first call only
       
   369         iEntered = ETrue;
       
   370         iSupportsInternalTraversal = aFocus;
       
   371         // this will ensure that we get the focus on first traverse
       
   372         aFocus = ETrue;
       
   373 
       
   374         // Form must be updated when the focus enters to the non-traversal CustomItem for the first time.
       
   375         // The reason is that the default value of iSupportsInternalTraversal is ETrue,
       
   376         // which means that CMIDCustomItem::Draw() function has not updated focus before.
       
   377         if (iForm && !iSupportsInternalTraversal)
       
   378         {
       
   379 
       
   380             iForm->DrawNow();
       
   381         }
       
   382     }
       
   383 
       
   384     // Handle focus for items that do not support internal traversal
       
   385     if (!iSupportsInternalTraversal)
       
   386     {
       
   387         // The focus is passed from java side
       
   388         if (!aFocus && iForm)
       
   389         {
       
   390             iForm->Traverse((CMIDForm::TDirection)aDirection);
       
   391         }
       
   392         return;
       
   393     }
       
   394 
       
   395     // This calculates top/bottom rect for Form to scroll to.
       
   396     if (aRect && aFocus && iForm)
       
   397     {
       
   398         TRect  view = iForm->GetClientArea();
       
   399 
       
   400         if (aRect->iTl.iY < view.iTl.iY) //top is off screen
       
   401         {
       
   402             // scroll up so that the focused area top is at the screen top
       
   403             TInt scrollUp = view.iTl.iY - aRect->iTl.iY ;
       
   404             if (iForm)
       
   405             {
       
   406                 iForm->RawScroll(scrollUp);
       
   407             }
       
   408         }
       
   409         else if (aRect->iBr.iY > view.iBr.iY) //bottom is off screen
       
   410         {
       
   411             // scroll down so that the focused area bottom is at the screen bottom
       
   412             TInt scrollDown = view.iBr.iY - aRect->iBr.iY ;
       
   413             if (iForm)
       
   414             {
       
   415                 iForm->RawScroll(scrollDown);
       
   416             }
       
   417         }
       
   418     }
       
   419 
       
   420 
       
   421     // If losing focus, tell the Form to advance focus
       
   422     //
       
   423     if (!aFocus && iForm)
       
   424     {
       
   425         iForm->Traverse((CMIDForm::TDirection)aDirection);
       
   426     }
       
   427 
       
   428     DEBUG("> CMIDCustomItem::SetFocusAndScroll");
       
   429 }
       
   430 
       
   431 CFbsBitmap* CMIDCustomItem::FrameBuffer() const
       
   432 {
       
   433     return iFrameBuffer;
       
   434 }
       
   435 
       
   436 void CMIDCustomItem::SetLabelL(const TDesC& aLabel)
       
   437 {
       
   438     CMIDControlItem::SetLabelL(aLabel);
       
   439     SetPreferredSizeL(iRequestedPreferredSize);
       
   440 }
       
   441 
       
   442 /** */
       
   443 void CMIDCustomItem::SetPreferredSizeL(const TSize& aSize)
       
   444 {
       
   445     DEBUG("< CMIDCustomItem::SetPreferredSizeL");
       
   446     DEBUG_INT2("+ CMIDCustomItem::SetPreferredSizeL - requested size = ( %d x %d )", aSize.iWidth, aSize.iHeight);
       
   447 
       
   448     iRequestedPreferredSize = CheckRequestedSize(aSize);
       
   449 
       
   450     if (iRequestedPreferredSize.iWidth == -1)
       
   451     { // Width is not locked
       
   452         iPreferredSize.iWidth = Min(FormClientAreaWidth(),
       
   453                                     PreferredContentSize().iWidth + iContentMargins.iLeft + iContentMargins.iRight);
       
   454     }
       
   455     else
       
   456     {
       
   457         iPreferredSize.iWidth  = Min(FormClientAreaWidth(),
       
   458                                      Max(MinimumSize().iWidth, iRequestedPreferredSize.iWidth));
       
   459     }
       
   460 
       
   461     if (iLabelControl)
       
   462     {
       
   463         iLabelControl->SetWidthL(iPreferredSize.iWidth);
       
   464     }
       
   465 
       
   466 
       
   467     if (iRequestedPreferredSize.iHeight == -1)
       
   468     { // Height is not locked
       
   469         iPreferredSize.iHeight = PreferredContentSize().iHeight + iContentMargins.iTop
       
   470                                  + iContentMargins.iBottom + LabelHeight();
       
   471     }
       
   472     else
       
   473     {
       
   474         iPreferredSize.iHeight = Max(MinimumSize().iHeight, iRequestedPreferredSize.iHeight);
       
   475     }
       
   476 
       
   477     DEBUG_INT2("+ CMIDCustomItem::SetPreferredSizeL - preferred size = ( %d x %d )", iPreferredSize.iWidth, iPreferredSize.iHeight);
       
   478 
       
   479     TRAP_IGNORE(AdjustToSizeL(iPreferredSize));
       
   480 
       
   481     DEBUG("> CMIDCustomItem::SetPreferredSizeL");
       
   482 }
       
   483 
       
   484 /**
       
   485 * Parameter aSize includes margins
       
   486 */
       
   487 void CMIDCustomItem::AdjustToSizeL(const TSize& aSize)
       
   488 {
       
   489     DEBUG("< CMIDCustomItem::AdjustToSizeL");
       
   490 
       
   491     TInt availableHeight = aSize.iHeight - iContentMargins.iTop - iContentMargins.iBottom;
       
   492     DEBUG_INT("+ CMIDCustomItem::AdjustToSizeL - available height = %d", availableHeight);
       
   493     TInt requestedHeight = PreferredContentSize().iHeight + LabelHeight();
       
   494     DEBUG_INT("+ CMIDCustomItem::AdjustToSizeL - requested height = %d", requestedHeight);
       
   495 
       
   496     if (requestedHeight > availableHeight)
       
   497     {// label + control do not fit
       
   498         if (iLabelControl && iLabelControl->Text()->Length() > 0)
       
   499         {
       
   500             //reserve one line to the control
       
   501             TInt heightForLabel =
       
   502                 ((availableHeight - PreferredContentSize().iHeight) > OneLineLabelHeight()) ?
       
   503                 availableHeight - PreferredContentSize().iHeight :
       
   504                 availableHeight - MinimumContentSize().iHeight;
       
   505 
       
   506             //By setting a temporary max number of lines and then calling
       
   507             //SetWidthL() we limit the number of lines to the temporary max number
       
   508             //However then the max number must be resetted
       
   509             TInt oldMaxNumLabelLines = iLabelControl->MaxNumLines();
       
   510             iLabelControl->SetMaxNumLines(
       
   511                 (heightForLabel - iLabelControl->ItemLabelMargin()) / iLabelControl->LineHeight());
       
   512             iLabelControl->SetWidthL(aSize.iWidth);
       
   513             iLabelControl->SetMaxNumLines(oldMaxNumLabelLines);
       
   514         }
       
   515     }
       
   516     DEBUG("> CMIDCustomItem::AdjustToSizeL");
       
   517 }
       
   518 
       
   519 /**
       
   520  * Updates CustomItem with new MinContentSize and PrefContentSize received
       
   521  * from CustomItem subclass
       
   522  *
       
   523  * Parameters doesn't include margins. iMinimumContentSize and iPreferredContentSize
       
   524  * doesn't include margins.
       
   525  */
       
   526 void CMIDCustomItem::Invalidate(const TSize& aMinSize, const TSize& aPrefSize)
       
   527 {
       
   528     DEBUG("< CMIDCustomItem::Invalidate");
       
   529 
       
   530     iMinimumContentSize = CheckRequestedSize(aMinSize);
       
   531 
       
   532     if (iMinimumContentSize.iWidth < 1)
       
   533     {
       
   534         iMinimumContentSize.iWidth = 1;
       
   535     }
       
   536     if (iMinimumContentSize.iHeight < 1)
       
   537     {
       
   538         iMinimumContentSize.iHeight = 1;
       
   539     }
       
   540 
       
   541     TInt maxContentWidth = FormClientAreaWidth() - iContentMargins.iLeft -
       
   542                            iContentMargins.iRight;
       
   543 
       
   544     if (iMinimumContentSize.iWidth > maxContentWidth)
       
   545     {
       
   546         iMinimumContentSize.iWidth = maxContentWidth;
       
   547     }
       
   548 
       
   549     iPreferredContentSize = CheckRequestedSize(aPrefSize);
       
   550 
       
   551     if (iPreferredContentSize.iWidth < iMinimumContentSize.iWidth)
       
   552     {
       
   553         iPreferredContentSize.iWidth = iMinimumContentSize.iWidth;
       
   554     }
       
   555     if (iPreferredContentSize.iHeight < iMinimumContentSize.iHeight)
       
   556     {
       
   557         iPreferredContentSize.iHeight = iMinimumContentSize.iHeight;
       
   558     }
       
   559 
       
   560     if (iPreferredContentSize.iWidth > maxContentWidth)
       
   561     {
       
   562         iPreferredContentSize.iWidth = maxContentWidth;
       
   563     }
       
   564 
       
   565     if (iForm)
       
   566     {
       
   567         TRAP_IGNORE(iForm->RequestLayoutL());
       
   568     }
       
   569 
       
   570     DEBUG("> CMIDCustomItem::Invalidate");
       
   571 }
       
   572 
       
   573 MMIDBufferProcessor* CMIDCustomItem::Processor()
       
   574 {
       
   575     return this;
       
   576 }
       
   577 
       
   578 void CMIDCustomItem::Dispose()
       
   579 {
       
   580     delete this;
       
   581 }
       
   582 
       
   583 void CMIDCustomItem::AddCommandL(MMIDCommand* aCommand)
       
   584 {
       
   585     CMIDItem::AddCommandL(aCommand);
       
   586 }
       
   587 
       
   588 void CMIDCustomItem::RemoveCommand(MMIDCommand* aCommand)
       
   589 {
       
   590     CMIDItem::RemoveCommand(aCommand);
       
   591 }
       
   592 
       
   593 void CMIDCustomItem::SetDefaultCommand(MMIDCommand* aCommand)
       
   594 {
       
   595     CMIDItem::SetDefaultCommand(aCommand);
       
   596 }
       
   597 
       
   598 TSize CMIDCustomItem::PreferredSize() const
       
   599 {
       
   600     return iPreferredSize;
       
   601 }
       
   602 
       
   603 TSize CMIDCustomItem::MinimumSize() const
       
   604 {
       
   605     DEBUG("< CMIDCustomItem::MinimumSize");
       
   606     TSize minimumSize = MinimumContentSize() +
       
   607                         TSize(iContentMargins.iLeft + iContentMargins.iRight,
       
   608                               iContentMargins.iTop + iContentMargins.iBottom);
       
   609 
       
   610     if (iLabelControl && (iLabelControl->Text()->Length() > 0))
       
   611     {
       
   612         minimumSize.iHeight += OneLineLabelHeight();
       
   613     }
       
   614     DEBUG_INT2("> CMIDCustomItem::MinimumSize = ( %d x %d )", minimumSize.iWidth, minimumSize.iHeight);
       
   615     return minimumSize;
       
   616 }
       
   617 
       
   618 void CMIDCustomItem::SetLayoutL(TLayout aLayout)
       
   619 {
       
   620     CMIDItem::SetLayoutL(aLayout);
       
   621 }
       
   622 
       
   623 const TSize& CMIDCustomItem::MinimumContentSize() const
       
   624 {
       
   625     return iMinimumContentSize;
       
   626 }
       
   627 
       
   628 const TSize& CMIDCustomItem::PreferredContentSize() const
       
   629 {
       
   630     return iPreferredContentSize;
       
   631 }
       
   632 
       
   633 void CMIDCustomItem::AbortAsync()
       
   634 {
       
   635     // nop
       
   636 }
       
   637 
       
   638 enum TOpCode
       
   639 {
       
   640     ESync,
       
   641     ESyncRect
       
   642 };
       
   643 
       
   644 /** Copy the content (iFrameBuffer) into iOffScreenBuffer and then draw.
       
   645 Either do a full copy or copy only the clipped area.
       
   646 */
       
   647 #ifdef RD_JAVA_NGA_ENABLED
       
   648 TBool CMIDCustomItem::ProcessL(
       
   649     const TMIDBufferOp*& aOp, const TMIDBufferOp* aEnd,
       
   650     TInt& /*aCycles*/, java::util::Monitor* /*aMonitor*/)
       
   651 #else
       
   652 TBool CMIDCustomItem::ProcessL(
       
   653     const TMIDBufferOp*& aOp, const TMIDBufferOp* aEnd,
       
   654     TInt& /*aCycles*/, TRequestStatus* /*aStatus*/)
       
   655 #endif
       
   656 {
       
   657     DEBUG("< CMIDCustomItem::ProcessL");
       
   658 
       
   659     // after coping iFrameBuffer to iOffScreenContext
       
   660     // iFrameBuffer should be reset in Draw()
       
   661     iResetFrameBuffer = ETrue;
       
   662 
       
   663     while (aOp< aEnd)
       
   664     {
       
   665         switch (aOp->OpCode())
       
   666         {
       
   667         case ESync:
       
   668             if (iFrameBuffer && iOffScreenContext)
       
   669             {
       
   670                 iOffScreenContext->BitBlt(TPoint(0,0), iFrameBuffer);
       
   671             }
       
   672             DrawNow();
       
   673 
       
   674             break;
       
   675 
       
   676         case ESyncRect:
       
   677             TRect clip = *static_cast<const TRect*>(aOp->Data());
       
   678 
       
   679             if (iFrameBuffer && iOffScreenContext)
       
   680             {
       
   681                 iOffScreenContext->BitBlt(clip.iTl, iFrameBuffer, clip);
       
   682             }
       
   683 
       
   684             clip.Move(iContentRect.iTl);
       
   685             clip.Intersection(Rect());
       
   686 
       
   687             ActivateGc();
       
   688             Draw(clip);
       
   689             DeactivateGc();
       
   690 
       
   691             break;
       
   692         }
       
   693         aOp += aOp->Size();
       
   694     }
       
   695 
       
   696     // disable resetting of iFrameBuffer (it has been reset already in Draw())
       
   697     iResetFrameBuffer = EFalse;
       
   698 
       
   699     DEBUG("> CMIDCustomItem::ProcessL");
       
   700     return EFalse;
       
   701 }
       
   702 
       
   703 TSize CMIDCustomItem::MinimumSize()
       
   704 {
       
   705     return ((MMIDCustomItem*)this)->MinimumSize();
       
   706 }
       
   707 
       
   708 TInt CMIDCustomItem::CountComponentControls() const
       
   709 {
       
   710     return 1;
       
   711 }
       
   712 
       
   713 CCoeControl* CMIDCustomItem::ComponentControl(TInt aIndex) const
       
   714 {
       
   715     switch (aIndex)
       
   716     {
       
   717     case 0:
       
   718         return iLabelControl;
       
   719     }
       
   720     return NULL;
       
   721 }
       
   722 
       
   723 #ifndef RD_JAVA_NGA_ENABLED
       
   724 void CMIDCustomItem::PauseDirectAccess()
       
   725 {
       
   726     if (iDirectAccess)
       
   727     {
       
   728         StopDirectAccess();
       
   729         iDirectPaused = ETrue;
       
   730     }
       
   731 }
       
   732 
       
   733 
       
   734 void CMIDCustomItem::ResumeDirectAccess()
       
   735 {
       
   736     if (iDirectAccess)
       
   737     {
       
   738         iDirectPaused = EFalse;
       
   739         StartDirectAccess();
       
   740     }
       
   741 }
       
   742 
       
   743 void CMIDCustomItem::StartDirectAccess()
       
   744 {
       
   745     DEBUG("< CMIDCustomItem::StartDirectAccess");
       
   746 
       
   747     if (!iDirectPaused && !iDirectAccess->IsActive())
       
   748     {
       
   749         TRAPD(err, iDirectAccess->StartL());
       
   750         if (KErrNone != err)
       
   751         {
       
   752             iDirectAccess->Cancel();
       
   753             return;
       
   754         }
       
   755 
       
   756         if (iDirectContent)
       
   757         {
       
   758             // Check that the dc region is fully visible
       
   759             // to prevent covering of external dialogs.
       
   760             RRegion* dsaRegion = iDirectAccess->DrawingRegion();
       
   761 
       
   762             // Form must have four rectangles on drawing region
       
   763             // (form area minus scroll bar)
       
   764             if (dsaRegion->Count() == 4)
       
   765             {
       
   766                 TRect itemRect(MdcContentBounds());
       
   767                 RRegion dcRegion(itemRect);
       
   768 
       
   769                 dcRegion.Intersect(*dsaRegion);
       
   770                 dcRegion.Tidy();
       
   771                 TBool dsaRegionOk = dcRegion.Count() == 1 &&
       
   772                                     dcRegion[0] == itemRect;
       
   773                 dcRegion.Close();
       
   774 
       
   775                 if (iDirectContent && dsaRegionOk)
       
   776                 {
       
   777                     // Notify DirectContent to resume DSA
       
   778                     iDirectContent->MdcResumeDSA();
       
   779                 }
       
   780             }
       
   781         }
       
   782     }
       
   783 
       
   784     DEBUG("> CMIDCustomItem::StartDirectAccess");
       
   785 }
       
   786 void CMIDCustomItem::StopDirectAccess()
       
   787 {
       
   788     if (iDirectContent)
       
   789     {
       
   790         // Notify DirectContent to abort DSA
       
   791         iDirectContent->MdcAbortDSA();
       
   792     }
       
   793 
       
   794     if (iDirectAccess)
       
   795     {
       
   796         iDirectAccess->Cancel();
       
   797     }
       
   798 }
       
   799 
       
   800 // MDirectScreenAccess
       
   801 void CMIDCustomItem::Restart(RDirectScreenAccess::TTerminationReasons /*aReasons*/)
       
   802 {
       
   803     DEBUG("< CMIDCustomItem::Restart");
       
   804     if (iDirectAccess)
       
   805     {
       
   806         StartDirectAccess();
       
   807     }
       
   808     DEBUG("> CMIDCustomItem::Restart");
       
   809 }
       
   810 
       
   811 // MDirectScreenAccess
       
   812 void CMIDCustomItem::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReasons*/)
       
   813 {
       
   814     DEBUG("< CMIDCustomItem::AbortNow");
       
   815 
       
   816     if (iDirectAccess)
       
   817     {
       
   818         StopDirectAccess();
       
   819     }
       
   820 
       
   821     DEBUG("> CMIDCustomItem::AbortNow");
       
   822 }
       
   823 #endif
       
   824 
       
   825 
       
   826 /** First draws the skin background and the border. Then draw the
       
   827 content. The content is double buffered, hence it must have already
       
   828 been copied into iOffScreenBuffer. Finally reset the frame buffer by
       
   829 drawing the skin background.
       
   830 
       
   831 @see: ProcessL() - which copies the content into iOffScreenBuffer
       
   832 */
       
   833 void CMIDCustomItem::Draw(const TRect& aRect) const
       
   834 {
       
   835     DEBUG("< CMIDCustomItem::Draw");
       
   836 
       
   837     CWindowGc& gc = SystemGc();
       
   838     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   839 
       
   840     if (!SupportsInternalTraversal())
       
   841     {
       
   842         // doesn't support internal traversal - CMIDControlItem draws background
       
   843         CMIDControlItem::Draw(aRect);
       
   844     }
       
   845     else
       
   846     {
       
   847         // does support internal traversal, draw background itself
       
   848         AknsDrawUtils::Background(skin, iForm->CurrentDisplayable().BackGroundControlContext(),
       
   849                                   this, gc, aRect);
       
   850     }
       
   851 
       
   852     if (iOffScreenBuffer)
       
   853     {
       
   854         gc.BitBlt(iContentRect.iTl, iOffScreenBuffer);
       
   855     }
       
   856 
       
   857     if (iForm && iFrameContext && iResetFrameBuffer)
       
   858     {
       
   859         MAknsControlContext* cc = !SupportsInternalTraversal() ? AknsDrawUtils::ControlContext(this) :
       
   860                                   iForm->CurrentDisplayable().BackGroundControlContext();
       
   861 
       
   862         // Don't do the following action in case of something is rendered into offscreen buffer (GIF)
       
   863         if (!iDirectContent)
       
   864         {
       
   865             AknsDrawUtils::DrawBackground(skin, cc,
       
   866                                           this, *iFrameContext, TPoint(0,0), iContentRect, KAknsDrawParamDefault);
       
   867         }
       
   868     }
       
   869     DEBUG("> CMIDCustomItem::Draw");
       
   870 }
       
   871 
       
   872 #ifdef RD_SCALABLE_UI_V2
       
   873 void CMIDCustomItem::HandlePointerEventL(const TPointerEvent &aPointerEvent)
       
   874 {
       
   875     DEBUG("< CMIDCustomItem::HandlePointerEventL");
       
   876 
       
   877     if (AknLayoutUtils::PenEnabled())
       
   878     {
       
   879         if (!iForm->TryDetectLongTapL(aPointerEvent))
       
   880         {
       
   881             TRect drawableRect = Rect();
       
   882             drawableRect.SetHeight(
       
   883                 drawableRect.Height() - iContentMargins.iTop -
       
   884                 iContentMargins.iBottom - iLabelControl->Size().iHeight);
       
   885             drawableRect.SetWidth(drawableRect.Width() -
       
   886                                   iContentMargins.iLeft - iContentMargins.iRight);
       
   887             drawableRect.Move(iContentMargins.iLeft,
       
   888                               iContentMargins.iTop + iLabelControl->Size().iHeight);
       
   889             TPoint point = aPointerEvent.iPosition;
       
   890 
       
   891 #ifdef RD_JAVA_ADVANCED_TACTILE_FEEDBACK
       
   892             if (!drawableRect.Contains(point) && !iForm->IsFocusChangingWithPen())
       
   893             {
       
   894                 switch (aPointerEvent.iType)
       
   895                 {
       
   896                 case TPointerEvent::EButton1Down:
       
   897                 case TPointerEvent::EButton1Up:
       
   898                     MTouchFeedback* feedback = MTouchFeedback::Instance();
       
   899                     if (feedback)
       
   900                     {
       
   901                         feedback->InstantFeedback(ETouchFeedbackList);
       
   902                     }
       
   903                     break;
       
   904                 }
       
   905             }
       
   906 #endif //RD_JAVA_ADVANCED_TACTILE_FEEDBACK
       
   907 
       
   908             point.iX = point.iX - drawableRect.iTl.iX;
       
   909             point.iY = point.iY - drawableRect.iTl.iY;
       
   910             TEventType type;
       
   911             switch (aPointerEvent.iType)
       
   912             {
       
   913             case TPointerEvent::EButton1Down:
       
   914             case TPointerEvent::EButton2Down:
       
   915             case TPointerEvent::EButton3Down:
       
   916                 type = EPointerPressed;
       
   917                 iPointerPressedCoordinates = TPoint(point.iX, point.iY);
       
   918                 break;
       
   919             case TPointerEvent::EButton1Up:
       
   920             case TPointerEvent::EButton2Up:
       
   921             case TPointerEvent::EButton3Up:
       
   922                 type = EPointerReleased;
       
   923                 if (iPointerEventSuppressionOngoing)
       
   924                 {
       
   925                     point.iX = iPointerPressedCoordinates.iX;
       
   926                     point.iY = iPointerPressedCoordinates.iY;
       
   927                 }
       
   928                 break;
       
   929             case TPointerEvent::EDrag:
       
   930                 type = EPointerDragged;
       
   931                 break;
       
   932             default:
       
   933                 type = ENoType;
       
   934             }
       
   935 
       
   936             if (iPointerEventSuppressor->SuppressPointerEvent(aPointerEvent))
       
   937             {
       
   938                 iPointerEventSuppressionOngoing = ETrue;
       
   939                 return;
       
   940             }
       
   941             else
       
   942             {
       
   943                 iPointerEventSuppressionOngoing = EFalse;
       
   944             }
       
   945 
       
   946             iEnv.PostJavaEvent(*this, EItem, type, point.iX, point.iY, 0);
       
   947         }
       
   948     }
       
   949 
       
   950     DEBUG("> CMIDCustomItem::HandlePointerEventL");
       
   951 }
       
   952 #endif //RD_SCALABLE_UI_V2
       
   953 
       
   954 
       
   955 void CMIDCustomItem::HandleCurrentL(TBool aCurrent)
       
   956 {
       
   957     DEBUG("< CMIDCustomItem::HandleCurrentL");
       
   958     if (aCurrent)
       
   959     {
       
   960         PostFocusTransferEvent(ETrue, CMIDForm::ENone);
       
   961     }
       
   962     DEBUG("> CMIDCustomItem::HandleCurrentL");
       
   963 }
       
   964 
       
   965 
       
   966 void CMIDCustomItem::SizeChanged()
       
   967 {
       
   968     DEBUG("< CMIDCustomItem::SizeChanged");
       
   969 
       
   970     const TRect oldRect = iContentRect;
       
   971     DEBUG_INT2("+ CMIDCustomItem::SizeChanged - old size = ( %d x %d )", oldRect.Width(), oldRect.Height());
       
   972 
       
   973     // Rect() returns control area including content, margins and possible label
       
   974     // iContentRect is the item content area exluding margins
       
   975     iContentRect = Rect();
       
   976 
       
   977     if (iLabelControl && iLabelControl->Text()->Length())
       
   978     {
       
   979         TRect rect(iContentRect);
       
   980         rect.iBr.iY = rect.iTl.iY + LabelHeight();
       
   981         iLabelControl->SetRect(rect);
       
   982         // Content
       
   983         iContentRect.iTl.iY += LabelHeight();
       
   984     }
       
   985 
       
   986     iContentRect.SetRect(
       
   987         iContentRect.iTl.iX + iContentMargins.iLeft,
       
   988         iContentRect.iTl.iY + iContentMargins.iTop,
       
   989         iContentRect.iBr.iX - iContentMargins.iRight,
       
   990         iContentRect.iBr.iY - iContentMargins.iBottom);
       
   991 
       
   992     if (oldRect != iContentRect)
       
   993     {
       
   994 #ifndef RD_JAVA_NGA_ENABLED
       
   995         // Pause DSA during framebuffers are being changed
       
   996         PauseDirectAccess();
       
   997 #endif
       
   998         const TSize canvasSize(iContentRect.Size());
       
   999         DEBUG_INT2("+ CMIDCustomItem::SizeChanged - new size = ( %d x %d )", canvasSize.iWidth, canvasSize.iHeight);
       
  1000         if (!iFrameBuffer || canvasSize != iFrameBuffer->SizeInPixels())
       
  1001         {
       
  1002             TRAPD(err, CreateBuffersL());
       
  1003 
       
  1004             if (err != KErrNone)
       
  1005             {
       
  1006                 ResetBuffers();
       
  1007             }
       
  1008         }
       
  1009 
       
  1010         CMIDControlItem::SizeChanged();
       
  1011 
       
  1012         //
       
  1013         // send SizeChanged event only if the size changes
       
  1014         //
       
  1015         if (oldRect.Size() != canvasSize)
       
  1016         {
       
  1017             iEnv.PostJavaEvent(*this, EItem, ESizeChanged, canvasSize.iWidth , canvasSize.iHeight, 0);
       
  1018         }
       
  1019 #ifdef RD_TACTILE_FEEDBACK
       
  1020         UpdateTactileFeedback();
       
  1021 #endif
       
  1022 
       
  1023         if (iDirectContent && iForm)
       
  1024         {
       
  1025             // Store the window position to be used later
       
  1026             // from non-LCDUI ES thread
       
  1027             iLastWindowPosition = DrawableWindow()->Position();
       
  1028 
       
  1029             if (iDirectAreaAddedToDisplayable)
       
  1030             {
       
  1031                 // Update the direct content area according the new size
       
  1032                 UpdateDirectContentBounds();
       
  1033             }
       
  1034 
       
  1035             TRect itemRect(iContentRect);
       
  1036             itemRect.Move(iLastWindowPosition);
       
  1037             iDirectContent->MdcItemContentRectChanged(itemRect,MdcContentBounds());
       
  1038         }
       
  1039 
       
  1040 #ifndef RD_JAVA_NGA_ENABLED
       
  1041         if (MdcContainerVisibility())
       
  1042         {
       
  1043             ResumeDirectAccess();
       
  1044         }
       
  1045 #endif
       
  1046     }
       
  1047     DEBUG("> CMIDCustomItem::SizeChanged");
       
  1048 }
       
  1049 
       
  1050 void CMIDCustomItem::PositionChanged()
       
  1051 {
       
  1052     DEBUG("< CMIDCustomItem::PositionChanged");
       
  1053     iContentRect = Rect();
       
  1054     iContentRect.iTl.iY += LabelHeight();
       
  1055 
       
  1056     iContentRect.SetRect(
       
  1057         iContentRect.iTl.iX + iContentMargins.iLeft,
       
  1058         iContentRect.iTl.iY + iContentMargins.iTop,
       
  1059         iContentRect.iBr.iX - iContentMargins.iRight,
       
  1060         iContentRect.iBr.iY - iContentMargins.iBottom);
       
  1061 
       
  1062     if (iDirectContent && iForm)
       
  1063     {
       
  1064         // Store the window position to be used later
       
  1065         // from non-LCDUI ES thread
       
  1066         iLastWindowPosition = DrawableWindow()->Position();
       
  1067 
       
  1068         if (iDirectAreaAddedToDisplayable)
       
  1069         {
       
  1070             // Update the direct content area according the new size
       
  1071             UpdateDirectContentBounds();
       
  1072         }
       
  1073 
       
  1074         TRect itemRect(iContentRect);
       
  1075         itemRect.Move(iLastWindowPosition);
       
  1076         iDirectContent->MdcItemContentRectChanged(itemRect,MdcContentBounds());
       
  1077     }
       
  1078     DEBUG("> CMIDCustomItem::PositionChanged");
       
  1079 }
       
  1080 
       
  1081 TKeyResponse CMIDCustomItem::OfferKeyEventL(const TKeyEvent& aEvent, TEventCode aType)
       
  1082 {
       
  1083     DEBUG("< CMIDCustomItem::OfferKeyEventL");
       
  1084 
       
  1085     DEBUG_INT("+ CMIDCustomItem::OfferKeyEventL - received: iCode = %d", aEvent.iCode);
       
  1086     DEBUG_INT("+ CMIDCustomItem::OfferKeyEventL - received: iModifiers = %d", aEvent.iModifiers);
       
  1087     DEBUG_INT("+ CMIDCustomItem::OfferKeyEventL - received: iRepeats = %d", aEvent.iRepeats);
       
  1088     DEBUG_INT("+ CMIDCustomItem::OfferKeyEventL - received: iScanCode = %d", aEvent.iScanCode);
       
  1089 
       
  1090     // map key event data
       
  1091     TKeyEvent wsEvent = aEvent;
       
  1092     iEnv.MappingDataForKey(wsEvent, aType);
       
  1093 
       
  1094     TMIDKeyEvent event;
       
  1095     if (iEnv.TranslateKeyL(event, wsEvent, aType))
       
  1096     {
       
  1097         DEBUG_INT("+ CMIDCustomItem::OfferKeyEventL - translated: iEvents = %d", event.iEvents);
       
  1098         DEBUG_INT("+ CMIDCustomItem::OfferKeyEventL - translated: iKeyCode = %d", event.iKeyCode);
       
  1099         DEBUG_INT("+ CMIDCustomItem::OfferKeyEventL - translated: iRepeats = %d", event.iRepeats);
       
  1100 
       
  1101         // 9-way Navigation Support
       
  1102         // Send two arrow events generated when press diagonal direction
       
  1103         switch (event.iKeyCode)
       
  1104         {
       
  1105             //KeyLeftUpArrow
       
  1106         case EKeyLeftUpArrow:
       
  1107         {
       
  1108             TKeyEvent pevent;
       
  1109             pevent.iCode = EKeyUpArrow;
       
  1110             pevent.iScanCode = EStdKeyUpArrow;
       
  1111             pevent.iModifiers = aEvent.iModifiers;
       
  1112             pevent.iRepeats = event.iRepeats;
       
  1113             this->OfferKeyEventL(pevent, aType);
       
  1114             pevent.iCode = EKeyLeftArrow;
       
  1115             pevent.iScanCode = EStdKeyLeftArrow;
       
  1116             pevent.iModifiers = aEvent.iModifiers;
       
  1117             pevent.iRepeats = event.iRepeats;
       
  1118             this->OfferKeyEventL(pevent, aType);
       
  1119 
       
  1120             break;
       
  1121         }
       
  1122         //KeyRightUpArrow
       
  1123         case EKeyRightUpArrow:
       
  1124         {
       
  1125             TKeyEvent pevent;
       
  1126             pevent.iCode = EKeyUpArrow;
       
  1127             pevent.iScanCode = EStdKeyUpArrow;
       
  1128             pevent.iModifiers = aEvent.iModifiers;
       
  1129             pevent.iRepeats = event.iRepeats;
       
  1130             this->OfferKeyEventL(pevent, aType);
       
  1131             pevent.iCode = EKeyRightArrow;
       
  1132             pevent.iScanCode = EStdKeyRightArrow;
       
  1133             pevent.iModifiers = aEvent.iModifiers;
       
  1134             pevent.iRepeats = event.iRepeats;
       
  1135             this->OfferKeyEventL(pevent, aType);
       
  1136 
       
  1137             break;
       
  1138         }
       
  1139         //KeyRightDownArrow
       
  1140         case EKeyRightDownArrow:
       
  1141         {
       
  1142             TKeyEvent pevent;
       
  1143             pevent.iCode = EKeyDownArrow;
       
  1144             pevent.iScanCode = EStdKeyDownArrow;
       
  1145             pevent.iModifiers = aEvent.iModifiers;
       
  1146             pevent.iRepeats = event.iRepeats;
       
  1147             this->OfferKeyEventL(pevent, aType);
       
  1148             pevent.iCode = EKeyRightArrow;
       
  1149             pevent.iScanCode = EStdKeyRightArrow;
       
  1150             pevent.iModifiers = aEvent.iModifiers;
       
  1151             pevent.iRepeats = event.iRepeats;
       
  1152             this->OfferKeyEventL(pevent, aType);
       
  1153 
       
  1154             break;
       
  1155         }
       
  1156         //KeyLeftDownArrow
       
  1157         case EKeyLeftDownArrow:
       
  1158         {
       
  1159             TKeyEvent pevent;
       
  1160             pevent.iCode = EKeyDownArrow;
       
  1161             pevent.iScanCode = EStdKeyDownArrow;
       
  1162             pevent.iModifiers = aEvent.iModifiers;
       
  1163             pevent.iRepeats = event.iRepeats;
       
  1164             this->OfferKeyEventL(pevent, aType);
       
  1165             pevent.iCode = EKeyLeftArrow;
       
  1166             pevent.iScanCode = EStdKeyLeftArrow;
       
  1167             pevent.iModifiers = aEvent.iModifiers;
       
  1168             pevent.iRepeats = event.iRepeats;
       
  1169             this->OfferKeyEventL(pevent, aType);
       
  1170 
       
  1171             break;
       
  1172         }
       
  1173         default:
       
  1174             iEnv.PostKeyEvent(*this, event);
       
  1175         }//switch
       
  1176     }
       
  1177     //  }
       
  1178 
       
  1179     if (aType != EEventKey)
       
  1180         return EKeyWasNotConsumed;
       
  1181 
       
  1182     if (!SupportsInternalTraversal() || aEvent.iCode == EKeyDevice3)
       
  1183     {
       
  1184         DEBUG("> CMIDCustomItem::OfferKeyEventL - returns EKeyWasNotConsumed");
       
  1185         return EKeyWasNotConsumed;
       
  1186     }
       
  1187 
       
  1188     CMIDForm::TDirection direction = TranslateKey(aEvent);
       
  1189     if (direction != CMIDForm::ENone)
       
  1190     {
       
  1191         PostFocusTransferEvent(ETrue, direction);
       
  1192     }
       
  1193 
       
  1194     DEBUG("> CMIDCustomItem::OfferKeyEventL - returns EKeyWasConsumed");
       
  1195     return EKeyWasConsumed;
       
  1196 }
       
  1197 
       
  1198 TSize CMIDCustomItem::ResetPreferredSize() const
       
  1199 {
       
  1200     TRAP_IGNORE(const_cast<CMIDCustomItem*>(this)->SetPreferredSizeL(iRequestedPreferredSize));
       
  1201     return iPreferredSize;
       
  1202 }
       
  1203 
       
  1204 /** If the specified height or width or the requested size are bigger that the
       
  1205 screen height or width times KCIMaxScreenSizeFactor then return these limit values.
       
  1206 Otherwise return the size unchanged. @see KCIMaxScreenSizeFactor */
       
  1207 TSize CMIDCustomItem::CheckRequestedSize(const TSize& aRequestedSize) const
       
  1208 {
       
  1209     DEBUG("< CMIDCustomItem::CheckRequestedSize");
       
  1210     TSize size = aRequestedSize;
       
  1211 
       
  1212     const TRect formClientAreaRect = FormClientAreaRect();
       
  1213 
       
  1214     size.iWidth = size.iWidth < KCIMaxScreenSizeFactor * formClientAreaRect.Width() ?
       
  1215                   size.iWidth : KCIMaxScreenSizeFactor * formClientAreaRect.Width();
       
  1216 
       
  1217     size.iHeight = size.iHeight < KCIMaxScreenSizeFactor * formClientAreaRect.Height() ?
       
  1218                    size.iHeight : KCIMaxScreenSizeFactor * formClientAreaRect.Height();
       
  1219 
       
  1220     DEBUG_INT2("> CMIDCustomItem::CheckRequestedSize = ( %d x %d )", size.iWidth, size.iHeight);
       
  1221     return size;
       
  1222 }
       
  1223 
       
  1224 void CMIDCustomItem::FocusChanged(TDrawNow aDrawNow)
       
  1225 {
       
  1226     DEBUG("< CMIDCustomItem::FocusChanged");
       
  1227     if (iForm)
       
  1228     {
       
  1229         //Item is on Form:
       
  1230         //Check if CustomItem changed its visibility (previous state is
       
  1231         //stored in iPreviousVisibility).
       
  1232         //current visibility:
       
  1233         TBool contentRectVisible = MdcContainerVisibility();
       
  1234         if (iPreviousVisibility != contentRectVisible)
       
  1235         {
       
  1236             //Event is sent only if CustomItem changed visibility:
       
  1237             //1. CustomItem is now at least partially visible,
       
  1238             //   when it previously had been completely invisible
       
  1239             //   -> CustomItem gains visibility,
       
  1240             //      showNotify is invoked on java side
       
  1241             //2. CustomItem is now completely invisible, when it previously
       
  1242             //   had been at least partially visible
       
  1243             //   -> CustomItem loses visibility,
       
  1244             //      hideNotify is invoked on java side
       
  1245             iEnv.PostJavaEvent(*this, EItem, EVisible, contentRectVisible);
       
  1246 
       
  1247             if (!iRestoreDirectContentWhenUnfaded)
       
  1248             {
       
  1249                 ChangeDirectContainerVisibility(contentRectVisible);
       
  1250             }
       
  1251 
       
  1252             //Current status of visibility is always stored
       
  1253             iPreviousVisibility = contentRectVisible;
       
  1254         }
       
  1255     }
       
  1256 
       
  1257     CMIDControlItem::FocusChanged(aDrawNow);
       
  1258 
       
  1259     DEBUG("> CMIDCustomItem::FocusChanged");
       
  1260 }
       
  1261 
       
  1262 void CMIDCustomItem::ChangeDirectContainerVisibility(TBool aVisible)
       
  1263 {
       
  1264     DEBUG("< CMIDCustomItem::ChangeDirectContainerVisibility");
       
  1265     if (iForm)
       
  1266     {
       
  1267         iLastWindowPosition = DrawableWindow()->Position();
       
  1268     }
       
  1269 
       
  1270 #ifndef RD_JAVA_NGA_ENABLED
       
  1271     if (iDirectAccess && (iDirectPaused == aVisible))
       
  1272     {
       
  1273         if (aVisible)
       
  1274         {
       
  1275             ResumeDirectAccess();
       
  1276         }
       
  1277         else
       
  1278         {
       
  1279             PauseDirectAccess();
       
  1280         }
       
  1281     }
       
  1282 #endif
       
  1283 
       
  1284     if (iDirectContent)
       
  1285     {
       
  1286         // Restore direct content
       
  1287         iDirectContent->MdcContainerVisibilityChanged(aVisible);
       
  1288     }
       
  1289 
       
  1290     DEBUG("> CMIDCustomItem::ChangeDirectContainerVisibility");
       
  1291 }
       
  1292 
       
  1293 /** Handles change in displaying item - calls same
       
  1294 events as in focus change.
       
  1295 */
       
  1296 void CMIDCustomItem::HandleVisibilityChange()
       
  1297 {
       
  1298     FocusChanged(ENoDrawNow);
       
  1299 }
       
  1300 
       
  1301 void CMIDCustomItem::SetForm(CMIDForm* aForm)
       
  1302 {
       
  1303     DEBUG("< CMIDCustomItem::SetForm");
       
  1304     CMIDItem::SetForm(aForm);
       
  1305 
       
  1306     if (iForm)
       
  1307     {
       
  1308         // Set S60 Selection Key Compatibility
       
  1309         // to provide MSK key events to canvas
       
  1310         iS60SelectionKeyCompatibility = iEnv.MidletAttributeIsSetToVal(
       
  1311                                             LcduiMidletAttributes::KAttribS60SelectionKeyCompatibility,
       
  1312                                             LcduiMidletAttributeValues::KTrueValue
       
  1313                                         );
       
  1314     }
       
  1315     DEBUG("> CMIDCustomItem::SetForm");
       
  1316 }
       
  1317 
       
  1318 void CMIDCustomItem::ItemAddedToFormL()
       
  1319 {
       
  1320     CMIDItem::ItemAddedToFormL();
       
  1321 
       
  1322     if (iDirectContent)
       
  1323     {
       
  1324         iDirectContent->MdcContainerWindowRectChanged(MdcContainerWindowRect());
       
  1325     }
       
  1326 
       
  1327     if (iPreviousVisibility)
       
  1328     {
       
  1329         ChangeDirectContainerVisibility(ETrue);
       
  1330     }
       
  1331 }
       
  1332 
       
  1333 void CMIDCustomItem::ItemRemovedFromForm()
       
  1334 {
       
  1335     CMIDItem::ItemRemovedFromForm();
       
  1336 
       
  1337     ChangeDirectContainerVisibility(EFalse);
       
  1338 }
       
  1339 
       
  1340 void CMIDCustomItem::PostFocusTransferEvent(
       
  1341     TBool aFocus,CMIDForm::TDirection aDirection)
       
  1342 {
       
  1343     DEBUG("< CMIDCustomItem::PostFocusTransferEvent");
       
  1344 
       
  1345     TRect customItemRect = iContentRect;
       
  1346 
       
  1347     if (iForm)
       
  1348     {
       
  1349         iForm->CurrentDisplayable().SetS60SelectionKeyCompatibility(
       
  1350             iS60SelectionKeyCompatibility && aFocus
       
  1351         );
       
  1352         TRect formRect = iForm->GetClientArea();
       
  1353         if (customItemRect.Intersects(formRect))
       
  1354         {
       
  1355             customItemRect.Intersection(formRect);
       
  1356         }
       
  1357         else
       
  1358         {
       
  1359             customItemRect.SetRect(0, 0, 0, 0);
       
  1360         }
       
  1361 
       
  1362         TInt eventData = aFocus << 16 | aDirection;
       
  1363         TInt eventData1 = customItemRect.iTl.iX << 16 | customItemRect.iTl.iY;
       
  1364         TInt eventData2 = customItemRect.Width() << 16 | customItemRect.Height();
       
  1365         iEnv.PostJavaEvent(*this, EItem, EFocusTraversal,
       
  1366                            eventData, eventData1, eventData2);
       
  1367     }
       
  1368     DEBUG("> CMIDCustomItem::PostFocusTransferEvent");
       
  1369 }
       
  1370 
       
  1371 CMIDForm::TDirection CMIDCustomItem::TranslateKey(const TKeyEvent& aEvent)
       
  1372 {
       
  1373     switch (aEvent.iCode)
       
  1374     {
       
  1375     case EKeyLeftArrow:
       
  1376         return CMIDForm::ELeft;
       
  1377     case EKeyRightArrow:
       
  1378         return CMIDForm::ERight;
       
  1379     case EKeyUpArrow:
       
  1380         return CMIDForm::EUp;
       
  1381     case EKeyDownArrow:
       
  1382         return CMIDForm::EDown;
       
  1383     }
       
  1384     return CMIDForm::ENone;
       
  1385 }
       
  1386 
       
  1387 MDirectContainer& CMIDCustomItem::DirectContainer()
       
  1388 {
       
  1389     return *this;
       
  1390 }
       
  1391 
       
  1392 void CMIDCustomItem::MdcAddContent(MDirectContent* aContent)
       
  1393 {
       
  1394     // Item can only have one content.
       
  1395     iDirectContent = aContent;
       
  1396 
       
  1397     // Register this control to observer
       
  1398     // in order to provide calls to this control from
       
  1399     // non-LCDUI ES thread.
       
  1400     // Unregistration is done in MdcRemoveContent.
       
  1401     iEnv.ToLcduiObserver().RegisterControl(*this);
       
  1402 }
       
  1403 
       
  1404 void CMIDCustomItem::MdcRemoveContent(MDirectContent* /*aContent*/)
       
  1405 {
       
  1406     iDirectContent = NULL;
       
  1407 
       
  1408     // Unregister the component from the observer
       
  1409     // if it were previously registered from MdcAddContent.
       
  1410     iEnv.ToLcduiObserver().UnregisterControl(*this);
       
  1411 }
       
  1412 
       
  1413 TRect CMIDCustomItem::MdcContainerWindowRect() const
       
  1414 {
       
  1415     TRect rect;
       
  1416     if (iForm)
       
  1417     {
       
  1418         // Form has always the same size as the RWindow
       
  1419         rect = TRect(iForm->PositionRelativeToScreen(), iForm->Size());
       
  1420     }
       
  1421     return rect;
       
  1422 }
       
  1423 
       
  1424 /** Return the item visibility. If the form has lost focus it is probably
       
  1425 because we have a menu or something else in front so we assume we have lost
       
  1426 visibility.
       
  1427 The direct container uses this to start/stop direct screen access.
       
  1428 */
       
  1429 TBool CMIDCustomItem::MdcContainerVisibility() const
       
  1430 {
       
  1431     return (iForm ? iForm->IsFocused() : EFalse) &&
       
  1432            (MdcContentBounds().Size().iHeight > 0);
       
  1433 }
       
  1434 
       
  1435 TRect CMIDCustomItem::MdcContentBounds() const
       
  1436 {
       
  1437     DEBUG("< CMIDCustomItem::MdcContentBounds");
       
  1438 
       
  1439     TRect visibleRect;
       
  1440 
       
  1441     // Cannot use iContentRect because it's not updated
       
  1442     // if the CustomItem is scrolled out
       
  1443     TRect contentRect = Rect();
       
  1444     contentRect.SetRect(
       
  1445         contentRect.iTl.iX + iContentMargins.iLeft,
       
  1446         contentRect.iTl.iY + iContentMargins.iTop,
       
  1447         contentRect.iBr.iX - iContentMargins.iRight,
       
  1448         contentRect.iBr.iY - iContentMargins.iBottom);
       
  1449 
       
  1450     DEBUG_INT2("+ CMIDCustomItem::MdcContentBounds - contentRect.iTl = [ %d, %d ]", contentRect.iTl.iX, contentRect.iTl.iY);
       
  1451     DEBUG_INT2("+ CMIDCustomItem::MdcContentBounds - contentRect.iBr = [ %d, %d ]", contentRect.iBr.iX, contentRect.iBr.iY);
       
  1452     if (iForm)
       
  1453     {
       
  1454         TRect formRect = iForm->GetClientArea();
       
  1455         if (contentRect.Intersects(formRect))
       
  1456         {
       
  1457             visibleRect = contentRect;
       
  1458             visibleRect.Intersection(formRect);
       
  1459 
       
  1460             visibleRect.Move(iLastWindowPosition);
       
  1461         }
       
  1462     }
       
  1463 
       
  1464     DEBUG_INT2("+ CMIDCustomItem::MdcContentBounds - visibleRect.iTl = [ %d, %d ]", visibleRect.iTl.iX, visibleRect.iTl.iY);
       
  1465     DEBUG_INT2("+ CMIDCustomItem::MdcContentBounds - visibleRect.iBr = [ %d, %d ]", visibleRect.iBr.iX, visibleRect.iBr.iY);
       
  1466     DEBUG("> CMIDCustomItem::MdcContentBounds");
       
  1467     return visibleRect;
       
  1468 }
       
  1469 
       
  1470 void CMIDCustomItem::MdcItemContentRect(TRect& aContentRect,
       
  1471                                         TRect& aScreenRect) const
       
  1472 {
       
  1473     DEBUG("< CMIDCustomItem::MdcItemContentRect");
       
  1474 
       
  1475     aScreenRect = MdcContentBounds(); //The clipped rect
       
  1476 
       
  1477     aContentRect = iContentRect; //The item rect
       
  1478     aContentRect.Move(iLastWindowPosition);
       
  1479 
       
  1480     DEBUG("> CMIDCustomItem::MdcItemContentRect");
       
  1481 }
       
  1482 
       
  1483 void CMIDCustomItem::MdcHandlePointerEventL(TPointerEvent& /*aPointerEvent*/)
       
  1484 {
       
  1485     // This method should not be called
       
  1486     __ASSERT_DEBUG(EFalse, User::Invariant());
       
  1487 }
       
  1488 
       
  1489 void CMIDCustomItem::MdcFlushContainer(const TRect& aRect)
       
  1490 {
       
  1491     if (iFrameBuffer && iOffScreenContext)
       
  1492     {
       
  1493         iOffScreenContext->BitBlt(TPoint(0,0), iFrameBuffer);
       
  1494 
       
  1495         // Flush the framebuffer on screen
       
  1496         iEnv.ToLcduiObserver().FlushControl(*this, aRect);
       
  1497     }
       
  1498 }
       
  1499 
       
  1500 void CMIDCustomItem::MdcGetDSAResources(MUiEventConsumer& aConsumer)
       
  1501 {
       
  1502     if (DrawableWindow())
       
  1503     {
       
  1504         // May run in non-LCDUI ES thread
       
  1505         // Invoke the callback from LCDUI ES thread
       
  1506         iEnv.ToLcduiObserver().InvokeDSAResourcesCallback(*this, aConsumer);
       
  1507     }
       
  1508     else
       
  1509     {
       
  1510         // Drawable window is not set
       
  1511         // Callback will be invoked from within
       
  1512         // SetContainerWindowL method.
       
  1513         iConsumerWaitingForDSAResourcesCallback = &aConsumer;
       
  1514     }
       
  1515 }
       
  1516 
       
  1517 void CMIDCustomItem::MdcGetUICallback(
       
  1518     MUiEventConsumer& aConsumer,
       
  1519     TInt aCallbackId)
       
  1520 {
       
  1521     // May run in non-LCDUI ES thread
       
  1522     // Invoke the callback from LCDUI ES thread
       
  1523     iEnv.ToLcduiObserver().InvokeUICallback(aConsumer, aCallbackId);
       
  1524 }
       
  1525 
       
  1526 // ---------------------------------------------------------------------------
       
  1527 //
       
  1528 // ---------------------------------------------------------------------------
       
  1529 //
       
  1530 void CMIDCustomItem::MdcAddContentBounds(const TRect& /*aRect*/)
       
  1531 {
       
  1532     iDirectAreaAddedToDisplayable = UpdateDirectContentBounds();
       
  1533 }
       
  1534 
       
  1535 // ---------------------------------------------------------------------------
       
  1536 //
       
  1537 // ---------------------------------------------------------------------------
       
  1538 //
       
  1539 void CMIDCustomItem::MdcRemoveContentBounds(const TRect& /*aRect*/)
       
  1540 {
       
  1541     if (iForm && iDirectAreaAddedToDisplayable)
       
  1542     {
       
  1543         // Remove clipping rect
       
  1544         Form()->CurrentDisplayable().RemoveDirectContentArea(iDirectArea);
       
  1545         iDirectAreaAddedToDisplayable = EFalse;
       
  1546     }
       
  1547 }
       
  1548 
       
  1549 void CMIDCustomItem::ResolutionChange(TInt /*aType*/)
       
  1550 {
       
  1551     UpdateMargins();
       
  1552     if (iDirectContent)
       
  1553     {
       
  1554         iDirectContent->MdcContainerWindowRectChanged(MdcContainerWindowRect());
       
  1555     }
       
  1556 }
       
  1557 
       
  1558 void CMIDCustomItem::HandleWindowFade(TBool aFaded)
       
  1559 {
       
  1560     if (iDirectContent)
       
  1561     {
       
  1562         TBool contentRectVisible = MdcContainerVisibility();
       
  1563         if ((contentRectVisible))
       
  1564         {
       
  1565             ChangeDirectContainerVisibility(!aFaded);
       
  1566         }
       
  1567     }
       
  1568     iRestoreDirectContentWhenUnfaded = aFaded;
       
  1569 }
       
  1570 
       
  1571 void CMIDCustomItem::HandleMediaKeyEvent(TMIDKeyEvent& aKeyEvent)
       
  1572 {
       
  1573     DEBUG_INT3("CMIDCustomItem::HandleMediaKeyEvent - PostKeyEvent() - JAVA code %d type %d repeats %d", aKeyEvent.iKeyCode, aKeyEvent.iEvents, aKeyEvent.iRepeats);
       
  1574     iEnv.PostKeyEvent(*this, aKeyEvent);
       
  1575 }
       
  1576 
       
  1577 #ifdef RD_TACTILE_FEEDBACK
       
  1578 
       
  1579 MMIDTactileFeedbackComponent* CMIDCustomItem::TactileFeedbackComponent()
       
  1580 {
       
  1581     return this;
       
  1582 }
       
  1583 
       
  1584 void CMIDCustomItem::UpdateTactileFeedback()
       
  1585 {
       
  1586     DEBUG("< CMIDCustomItem::UpdateTactileFeedback");
       
  1587     TInt areaCount = iTactileFeedback->GetAreasCount();
       
  1588 
       
  1589     for (TInt i=0; i < areaCount; i++)
       
  1590     {
       
  1591         CMIDTactileFeedbackExtension::FeedbackArea* area = iTactileFeedback->GetArea(i);
       
  1592         TRect physicalRect = area->rect;
       
  1593         physicalRect.Move(iContentRect.iTl.iX,
       
  1594                           iContentRect.iTl.iY);
       
  1595 
       
  1596         iTactileFeedback->SetFeedbackArea(area->id, physicalRect, (TInt)area->style);
       
  1597     }
       
  1598     DEBUG("> CMIDCustomItem::UpdateTactileFeedback");
       
  1599 }
       
  1600 
       
  1601 void CMIDCustomItem::RegisterFeedbackArea(TInt aId, TRect aRect, TInt aStyle)
       
  1602 {
       
  1603     iTactileFeedback->RegisterFeedbackArea(aId, aRect, aStyle);
       
  1604 }
       
  1605 
       
  1606 void CMIDCustomItem::UnregisterFeedbackArea(TInt aId)
       
  1607 {
       
  1608     iTactileFeedback->UnregisterFeedbackArea(aId);
       
  1609 }
       
  1610 
       
  1611 void CMIDCustomItem::UnregisterFeedbackForControl()
       
  1612 {
       
  1613     iTactileFeedback->UnregisterFeedbackForControl();
       
  1614 }
       
  1615 
       
  1616 void CMIDCustomItem::MoveAreaToFirstPriority(TInt aId)
       
  1617 {
       
  1618     iTactileFeedback->MoveAreaToFirstPriority(aId);
       
  1619 }
       
  1620 #endif //RD_TACTILE_FEEDBACK
       
  1621 
       
  1622 
       
  1623 // ---------------------------------------------------------------------------
       
  1624 // CMIDCustomItem::UpdateDirectContentBounds
       
  1625 // Notifies the current displayable about the direct content position update
       
  1626 // ---------------------------------------------------------------------------
       
  1627 //
       
  1628 TBool CMIDCustomItem::UpdateDirectContentBounds()
       
  1629 {
       
  1630     if (iForm)
       
  1631     {
       
  1632         TRect currentDirectArea(MdcContentBounds());
       
  1633 
       
  1634         currentDirectArea.Move(-iLastWindowPosition);
       
  1635 
       
  1636         if (iDirectAreaAddedToDisplayable)
       
  1637         {
       
  1638             Form()->CurrentDisplayable().RemoveDirectContentArea(
       
  1639                 iDirectArea);
       
  1640         }
       
  1641 
       
  1642         iDirectArea = currentDirectArea;
       
  1643 
       
  1644         // Add clipping rect to protect direct content from being redrawn
       
  1645         this->Form()->CurrentDisplayable().AddDirectContentArea(
       
  1646             iDirectArea);
       
  1647 
       
  1648         return ETrue;
       
  1649     }
       
  1650     return EFalse;
       
  1651 }