javauis/lcdui_akn/lcdui/src/CMIDChoiceGroupItem.cpp
branchRCL_3
changeset 19 04becd199f91
child 25 9ac0a0a7da70
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/lcdui_akn/lcdui/src/CMIDChoiceGroupItem.cpp	Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,818 @@
+/*
+* Copyright (c) 2003-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:  CMIDChoiceGroupItem implements the MID Form ChoiceGroup item
+*
+*/
+
+
+#include <avkon.mbg>
+#include <j2me/jdebug.h>
+
+#include "CMIDChoiceGroupItem.h"
+#include "CMIDChoiceGroupControl.h"
+// API for iLabelControl
+#include "CMIDItemLabel.h"
+#include "CMIDCommandList.h"
+#include "CMIDCommand.h"
+#include "CMIDPopupNoteController.h"
+// needed API for CMIDDisplayable and CMIDCommandList in UpdateCommands function
+#include "CMIDDisplayable.h"
+
+/** This macro is executed each time a trapped call returns an error code different than KErrNone */
+#undef  TRAP_INSTRUMENTATION_LEAVE
+#define TRAP_INSTRUMENTATION_LEAVE(aResult) DEBUG_INT2("In CMIDChoiceGroupItem.cpp, trapped method was called at line %D and got exception %D", __LINE__, aResult);
+
+
+// class CMIDChoiceGroupItem
+
+CMIDChoiceGroupItem* CMIDChoiceGroupItem::NewL(
+    MMIDEnv& aMIDEnv, const TDesC& aLabel, TInt aType,
+    RArray<TPtrC>& aStringArray, RArray<MMIDImage*>& aImageArray, CMIDUIManager* aUIManager)
+{
+    CMIDChoiceGroupItem* self = new(ELeave) CMIDChoiceGroupItem(
+        aMIDEnv, aType, aStringArray, aImageArray, aUIManager);
+    CleanupStack::PushL(self);
+    self->ConstructL(aLabel);
+    CleanupStack::Pop(self);
+    return self;
+}
+
+
+CMIDChoiceGroupItem::CMIDChoiceGroupItem(
+    MMIDEnv& aMIDEnv,
+    TInt aType,
+    RArray<TPtrC>& aStringArray,
+    RArray<MMIDImage*>& aImageArray,
+    CMIDUIManager* aUIManager)
+        : CMIDControlItem(MMIDItem::EDefault, aUIManager),
+        iChoiceType((MMIDChoiceGroup::TChoiceType) aType),
+        iFitPolicy(EWrapDefault),
+        iMIDEnv(aMIDEnv),
+        iStringArray(aStringArray),
+        iImageArray(aImageArray)
+{
+    // Set this to be a MMIDItem interface implementor
+    iMMidItem = this;
+
+    // This is a focusing item
+    SetFocusing(ETrue);
+}
+
+CMIDChoiceGroupItem::~CMIDChoiceGroupItem()
+{
+    delete iChoiceGroupControl;
+    if (iSelectCommand)
+    {
+        iSelectCommand->SetObserver(NULL);
+        iSelectCommand->Dispose();
+        iSelectCommand = NULL;
+    }
+    if (iMarkCommand)
+    {
+        iMarkCommand->SetObserver(NULL);
+        iMarkCommand->Dispose();
+        iMarkCommand = NULL;
+    }
+    if (iUnmarkCommand)
+    {
+        iUnmarkCommand->SetObserver(NULL);
+        iUnmarkCommand->Dispose();
+        iUnmarkCommand = NULL;
+    }
+}
+
+void CMIDChoiceGroupItem::ConstructL(const TDesC& aLabel)
+{
+    // Allow parent to construct parts that are common
+    CMIDControlItem::ConstructL();
+
+    // Create built-in commands to makes selections in the list
+    HBufC* label = NULL;
+    if (iChoiceType == EPopup)
+    {
+        label = iEikonEnv->AllocReadResourceL(R_QTN_MSK_CHANGE);
+    }
+    else
+    {
+        label = iEikonEnv->AllocReadResourceL(R_QTN_MSK_SELECT);
+    }
+    CleanupStack::PushL(label);
+    iSelectCommand = CMIDCommand::NewBuiltInCommandL(label->Des(),
+                     CMIDCommand::EItem, CMIDCommand::EChoiceGroupSelectCommandId);
+    CleanupStack::PopAndDestroy(label); // command creates a copy of the string
+    label = iEikonEnv->AllocReadResourceL(R_QTN_MSK_MARK);
+    CleanupStack::PushL(label);
+    iMarkCommand = CMIDCommand::NewBuiltInCommandL(label->Des(),
+                   CMIDCommand::EItem, CMIDCommand::EChoiceGroupMarkCommandId);
+    CleanupStack::PopAndDestroy(label); // command creates a copy of the string
+    label = iEikonEnv->AllocReadResourceL(R_QTN_MSK_UNMARK);
+    CleanupStack::PushL(label);
+    iUnmarkCommand = CMIDCommand::NewBuiltInCommandL(label->Des(),
+                     CMIDCommand::EItem, CMIDCommand::EChoiceGroupUnmarkCommandId);
+    CleanupStack::PopAndDestroy(label); // command creates a copy of the string
+    iSelectCommand->SetObserver(this);
+    iMarkCommand->SetObserver(this);
+    iUnmarkCommand->SetObserver(this);
+    if (iChoiceType == EPopup)
+    { // in popup the command is always available
+        SetBuiltInMSKCommand(iSelectCommand);
+    }
+
+    // Parent created label control, set label in it
+    SetLabelL(aLabel);
+    iLabelControl->SetWidthL(FormClientAreaWidth());
+
+    // Create the choicegroup control to hold the items
+    // passed in. The actual control is created when the
+    // choicegroup item is added to a form, otherwise it won't
+    // have a parent window, and the listbox doesn't like that
+    iChoiceGroupControl = new(ELeave) CMIDChoiceGroupControl(iChoiceType, this);
+    iChoiceGroupControl->ConstructL(iStringArray, iImageArray);
+
+    // Spy on control
+    iChoiceGroupControl->SetObserver(this);
+
+#ifdef RD_SCALABLE_UI_V2
+    SetAllowStrayPointers();
+#endif
+
+    // This control is ready
+    ActivateL();
+}
+
+void CMIDChoiceGroupItem::UpdateCommands()
+{
+    // MSK
+    // This method must be called when ever the current list item or list selection changes.
+    // It sets the command such that it tells the user what can be done next. E.g. in exlusive
+    // list if current item is selected, then we enable context sensitive menu by setting
+    // MSK command to NULL. In multiple lists, the command label changes depending on the
+    // selected state of the current list item.
+    CMIDCommand* cmd = iSelectCommand;
+    if (iChoiceType == EExclusive)
+    {
+        TInt numberOfOkMenuCmds(0);
+        if (iForm)
+        { // check for number of context menu commands
+            CMIDDisplayable& displayable = iForm->CurrentDisplayable();
+            numberOfOkMenuCmds = displayable.NumCommandsForOkOptionsMenu();
+        }
+        // If item is selected and there are commands for context menu
+        // then context menu should be displayed - set MSK command to NULL.
+        // Since number of context menu commands queried from CMIDDisplayable
+        // may not be synchronized with iCommandList at this stage, we also
+        // check the number of commands in iCommandList.
+        if (iChoiceGroupControl->IsCurrentItemSelected() &&
+                (DefaultCommand() || numberOfOkMenuCmds > 0 ||
+                 iCommandList->Count() > 0))
+        {
+            cmd = NULL;
+        }
+    }
+    else if (iChoiceType == EMultiple)
+    {
+        cmd = iChoiceGroupControl->IsCurrentItemSelected() ? iUnmarkCommand : iMarkCommand;
+    }
+
+    // If choice group is empty, MSK command is set to null,
+    // except in popup case "change" command is always shown.
+    if (iChoiceType != EPopup && iChoiceGroupControl->NumberOfElements() == 0)
+    {
+        cmd = NULL;
+    }
+
+    SetBuiltInMSKCommand(cmd);
+#ifndef RD_JAVA_S60_RELEASE_9_2
+    iChoiceGroupControl->ShowInfoPopup();
+#endif // RD_JAVA_S60_RELEASE_9_2
+}
+
+// msk
+TBool CMIDChoiceGroupItem::ProcessCommandL(CMIDCommand* /*aCommand*/)
+{
+    if (iChoiceType == EPopup)
+    {
+        iChoiceGroupControl->DoPopupL();
+    }
+    else // for multiple and exclusive
+    {
+        // toggle selection
+        iChoiceGroupControl->ToggleCurrentItemSelectionL();
+    }
+    return ETrue;
+}
+
+
+// Updates the commands when the form that the item is on becomes the current.
+// After LAF changes: If the form is not the current displayable anymore, closes the popup
+void CMIDChoiceGroupItem::HandleCurrentL(TBool aCurrent)
+{
+    if (!aCurrent && iChoiceGroupControl && iChoiceType == MMIDChoiceGroup::EPopup)
+    {
+        iChoiceGroupControl->ClosePopup();
+    }
+    if (aCurrent)
+    {
+        UpdateCommands();
+    }
+}
+
+
+// Inserts a new element in the choice
+void CMIDChoiceGroupItem::InsertElementL(TInt aIndex, const TDesC& aText, MMIDImage* aImage)
+{
+    ASSERT(iChoiceGroupControl);
+    iChoiceGroupControl->InsertElementL(aIndex, aText, aImage);
+    UpdateCommands();
+}
+
+// Deletes an element from the choice
+void CMIDChoiceGroupItem::DeleteElementL(TInt aIndex)
+{
+    ASSERT(iChoiceGroupControl);
+    iChoiceGroupControl->DeleteElementL(aIndex);
+    UpdateCommands();
+}
+
+// Deletes all elements
+void CMIDChoiceGroupItem::DeleteAllL()
+{
+    ASSERT(iChoiceGroupControl);
+    iChoiceGroupControl->DeleteAllL();
+    UpdateCommands();
+}
+
+// Sets properties of element at <aIndex>
+void CMIDChoiceGroupItem::SetElementL(TInt aIndex, const TDesC& aText, MMIDImage* aImage)
+{
+    ASSERT(iChoiceGroupControl);
+    iChoiceGroupControl->SetElementL(aIndex, aText, aImage);
+}
+
+// Sets selection state of element at <aIndex>
+void CMIDChoiceGroupItem::SelectElementL(TInt aIndex, TBool aSelected)
+{
+    ASSERT(iChoiceGroupControl);
+    iChoiceGroupControl->SelectElementL(aIndex, aSelected);
+}
+
+// Returns selection state of element at <aIndex>
+TBool CMIDChoiceGroupItem::IsSelected(TInt aIndex)
+{
+    ASSERT(iChoiceGroupControl);
+    return iChoiceGroupControl->IsSelected(aIndex);
+}
+
+// Sets element text font
+void CMIDChoiceGroupItem::SetFontL(TInt aIndex, MMIDFont* aFont)
+{
+    ASSERT(iChoiceGroupControl);
+    iChoiceGroupControl->SetFontL(aIndex, aFont);
+}
+
+// Sets element text fit policy
+void CMIDChoiceGroupItem::SetFitPolicyL(TInt aFitPolicy)
+{
+    ASSERT(iChoiceGroupControl);
+    iChoiceGroupControl->SetFitPolicyL(aFitPolicy);
+}
+
+// --- from MMIDItem ---
+
+
+// --- from CCoeControl ---
+
+// Set the containing window
+void CMIDChoiceGroupItem::SetContainerWindowL(const CCoeControl& aContainer)
+{
+    // Set this controls parent
+    CMIDControlItem::SetContainerWindowL(aContainer);
+    SetObserver(iForm);
+}
+
+
+// Count component controls in this compound control
+TInt CMIDChoiceGroupItem::CountComponentControls() const
+{
+    TInt count = 0;
+    CCoeControl* controls[] = { iLabelControl, iChoiceGroupControl };
+    for (TUint ii = 0; ii < sizeof(controls) / sizeof(CCoeControl*); ii++)
+    {
+        if (controls[ii])
+        {
+            count++;
+        }
+    }
+    return count;
+}
+
+
+// Return requested component control
+CCoeControl* CMIDChoiceGroupItem::ComponentControl(TInt aIndex) const
+{
+    CCoeControl* controls[] = { iLabelControl, iChoiceGroupControl};
+
+    for (TUint ii=0; ii < sizeof(controls) / sizeof(CCoeControl*); ii++)
+    {
+        // Index is decremented only if control is not NULL
+        if ((controls[ii]) && (aIndex-- == 0))
+        {
+            return controls[ii];
+        }
+    }
+    return NULL;
+}
+
+
+// Calculate size and layout
+void CMIDChoiceGroupItem::SizeChanged()
+{
+    TRect labelRect;
+    TRect choiceRect;
+
+    CalcChildSizes(Rect(), labelRect, choiceRect);
+
+    if (iLabelControl)
+    {
+        iLabelControl->SetRect(labelRect);
+    }
+
+    if (iChoiceGroupControl)
+    {
+        iChoiceGroupControl->SetRect(choiceRect);
+    }
+
+    CMIDControlItem::SizeChanged();
+}
+
+
+// Calculates and returns the minimum size of this item
+TSize CMIDChoiceGroupItem::MinimumSize()
+{
+    ASSERT(iChoiceGroupControl);
+
+    TInt height = LabelHeight();
+
+    if (height == 0 && iChoiceGroupControl->NumberOfElements() == 0)
+    {
+        return TSize(0, 0);
+    }
+    else
+    {
+        height += iChoiceGroupControl->MinimumSize().iHeight;
+        return TSize(FormClientAreaWidth(), height);
+    }
+}
+
+
+// Offers key events to the choicegroup control.
+TKeyResponse CMIDChoiceGroupItem::OfferKeyEventL(
+    const TKeyEvent& aKeyEvent,
+    TEventCode aType)
+{
+    // For now, just offer key events to choice control
+    TKeyResponse resp = EKeyWasNotConsumed;
+
+    if (iChoiceGroupControl)
+    {
+        resp = iChoiceGroupControl->OfferKeyEventL(aKeyEvent, aType);
+    }
+
+    return resp;
+}
+
+// Responds to focus change.
+// From CCoeControl.
+void CMIDChoiceGroupItem::FocusChanged(TDrawNow aDrawNow)
+{
+    CMIDControlItem::FocusChanged(aDrawNow);
+
+    // update focus state of choice group control regarding to current focus state
+    if (iChoiceGroupControl)
+    {
+        iChoiceGroupControl->SetFocus(IsFocused(), aDrawNow);
+    }
+}
+
+
+#ifdef RD_SCALABLE_UI_V2
+void CMIDChoiceGroupItem::HandlePointerEventL(const TPointerEvent& aPointerEvent)
+{
+#ifdef RD_JAVA_S60_RELEASE_9_2
+    if (!AknLayoutUtils::PenEnabled())
+    {
+        return;
+    }
+    if (aPointerEvent.iType == TPointerEvent::EButton1Down)
+    {
+        iLongTapDetected = EFalse;
+    }
+    iLongTapDetected = iForm->TryDetectLongTapL(aPointerEvent);
+#else
+    if (!AknLayoutUtils::PenEnabled() || iForm->TryDetectLongTapL(aPointerEvent))
+    {
+        return;
+    }
+#endif // RD_JAVA_S60_RELEASE_9_2    
+
+    switch (aPointerEvent.iType)
+    {
+    case TPointerEvent::EDrag:
+    {
+#ifdef RD_JAVA_S60_RELEASE_9_2
+        if (iLongTapDetected)
+        {
+            return;
+        }
+#endif // RD_JAVA_S60_RELEASE_9_2
+
+        if (aPointerEvent.iPosition.iY >= 0 &&
+                aPointerEvent.iPosition.iY < FormRect().Height() &&
+                iChoiceGroupControl->Rect().Contains(aPointerEvent.iPosition))
+        {
+#ifdef RD_JAVA_S60_RELEASE_9_2
+            // Drag events inside ChoiceGroup area are forwarded to the control.
+            iChoiceGroupControl->HandlePointerEventL(aPointerEvent);
+#else
+            if (iForm->PhysicsEnabled())
+            {
+            }
+            else
+            {
+                // Forward drag events directly to the control (i.e. to listbox). This enables
+                // the moving of the highlight inside list box when foucused item is changed
+                // by dragging on the form. Calling CCoeControl::HandlePointerEventL() forwards the
+                // drag events to grabbing component only and setting the grabbing component properly
+                // is not always possible. See CCoeControl implementation.
+                iChoiceGroupControl->HandlePointerEventL(aPointerEvent);
+
+            }
+#endif // RD_JAVA_S60_RELEASE_9_2
+
+        }
+        break;
+    }
+
+    case TPointerEvent::EButton1Up:
+    {
+        if (iChoiceType == MMIDChoiceGroup::EPopup &&
+                !iForm->IsScrolledOnPointerDown() &&
+#ifdef RD_JAVA_S60_RELEASE_9_2
+                !iLongTapDetected &&
+#else
+                // In non-single click UI style, item must be focused
+                // before opening pop-up choicegroup.
+                !iForm->IsFocusChangingWithPen() &&
+#endif // RD_JAVA_S60_RELEASE_9_2                 
+                !iForm->PhysicsScrolling())
+        {
+#ifdef RD_JAVA_ADVANCED_TACTILE_FEEDBACK
+            MTouchFeedback* feedback = MTouchFeedback::Instance();
+            if (feedback)
+            {
+                feedback->InstantFeedback(ETouchFeedbackList);
+            }
+#endif //RD_JAVA_ADVANCED_TACTILE_FEEDBACK
+            iChoiceGroupControl->DoPopupL();
+        }
+#ifdef RD_JAVA_S60_RELEASE_9_2
+        // Forward pointer event except if long tap has been detected,
+        // because we want to keep highlight visible.
+        if (iLongTapDetected)
+        {
+            iPendingUpEvent = aPointerEvent;
+        }
+        else
+        {
+            CMIDControlItem::HandlePointerEventL(aPointerEvent);
+        }
+#else
+        if (iForm->PhysicsEnabled())
+        {
+            if (!iForm->PhysicsScrolling())
+            {
+                CMIDControlItem::HandlePointerEventL(aPointerEvent);
+            }
+        }
+        else
+        {
+            CMIDControlItem::HandlePointerEventL(aPointerEvent);
+        }
+#endif // RD_JAVA_S60_RELEASE_9_2        
+        break;
+    }
+
+    default:
+        CMIDControlItem::HandlePointerEventL(aPointerEvent);
+        break;
+    }
+}
+#endif //RD_SCALABLE_UI_V2
+
+// --- from CMIDControlItem
+
+// Returns a rect that should be partially visible for an Item to have focus
+// (ie the choicegroup control area)
+TRect CMIDChoiceGroupItem::FocusableRect()
+{
+    if (iChoiceGroupControl)
+    {
+        return iChoiceGroupControl->Rect();
+    }
+    else
+    {
+        // Just return the items rect.
+        return Rect();
+    }
+}
+
+void CMIDChoiceGroupItem::RestoreInnerFocus()
+{
+    if (iChoiceGroupControl)
+        iChoiceGroupControl->RestoreFocus();
+}
+
+// --- from MMIDChoiceGroupControlObserver
+
+// Called when the model has changed. Based on the change, will cause
+// just a redraw of the control, or size recalculation
+void CMIDChoiceGroupItem::HandleChoiceGroupControlEventL(
+    CMIDChoiceGroupControl* aControl,
+    TChoiceGroupControlEvent aEvent,
+    TAny* aParam)
+{
+    ASSERT(iChoiceGroupControl);
+
+    // If not from our control, ignore
+    if (aControl != iChoiceGroupControl)
+    {
+        return;
+    }
+
+    switch (aEvent)
+    {
+    case ESizeChanged:
+        break;
+
+    case EScrollRequest:
+        // Make form scroll the requested amount and redraw
+        if (iForm)
+        {
+            iForm->ScrollRelative((TInt) aParam);
+            iForm->UpdatePhysics();
+        }
+        break;
+
+    default:
+        break;
+    }
+}
+
+
+// Need to construct the choice listbox when adding to a form
+// (the listbox very much likes to have a parent window when created)
+void CMIDChoiceGroupItem::ItemAddedToFormL()
+{
+    // Form must've been set before
+    ASSERT(iForm);
+
+    // NOTE: The form calls SetContainerWindow() only after
+    // calling SetForm(). That's why the form and not this is
+    // passed as parent.
+
+    // Create a choice group control here, so that we can
+    // give a parent window to the listbox
+    CreateChoiceGroupControlL(iForm);
+
+    iChoiceGroupControl->EnableListHighlight(EFalse);
+}
+
+
+// Discard the listbox control when removed from a form
+void CMIDChoiceGroupItem::ItemRemovedFromForm()
+{
+    // Get rid of the actual control, but keep the
+    // choicegroup control around, as it holds the model with
+    // all the added elements and can be reattached to a form
+    if (iChoiceGroupControl)
+    {
+        iChoiceGroupControl->DeleteControl();
+    }
+}
+
+void CMIDChoiceGroupItem::NotifyScrollingCompleted()
+{
+    // When this cg becomes focused, show info popup after the form scrolling is completed
+    // and new position has been set to this item. If the note was shown before the new position
+    // is set, the note might be in wrong position (or might be hidden by form, see
+    // CMIDForm::UpdateScrollBar and CMICForm::RawScrollFinalize).
+    if (IsFocused())
+    {
+        iChoiceGroupControl->ShowInfoPopup();
+    }
+}
+
+void CMIDChoiceGroupItem::PostItemStateChangedEventL()
+{
+    ReportEventL(MCoeControlObserver::EEventStateChanged);
+}
+
+#ifdef RD_JAVA_S60_RELEASE_9_2
+void CMIDChoiceGroupItem::PostPendingUpEventL()
+{
+    if (iLongTapDetected)
+    {
+        iChoiceGroupControl->HandlePointerEventL(iPendingUpEvent);
+        iLongTapDetected = EFalse;
+    }
+}
+
+TBool CMIDChoiceGroupItem::LongTapDetected()
+{
+    return iLongTapDetected;
+}
+#endif // RD_JAVA_S60_RELEASE_9_2
+
+void CMIDChoiceGroupItem::PostFocusTransferEvent(TBool aFocus, CMIDForm::TDirection aDirection)
+{
+    if (aFocus)
+    {
+        if (aDirection == CMIDForm::EDown || aDirection == CMIDForm::ERight ||
+                aDirection == CMIDForm::ENone)
+        {
+            iChoiceGroupControl->HiliteFirstElement(ETrue);
+        }
+        else
+        {
+            iChoiceGroupControl->HiliteLastElement(ETrue);
+        }
+        UpdateCommands();
+#ifdef RD_JAVA_S60_RELEASE_9_2
+        if (aDirection != CMIDForm::ENone)
+        {
+            iChoiceGroupControl->ShowInfoPopup();
+        }
+#endif // RD_JAVA_S60_RELEASE_9_2        
+    }
+    else
+    {
+        iChoiceGroupControl->EnableListHighlight(EFalse);
+    }
+}
+
+
+// Return the items preferred height without the label part
+// (the "payload" size)
+TInt CMIDChoiceGroupItem::ItemPreferredHeightWithoutLabel()
+{
+    return iChoiceGroupControl ? iChoiceGroupControl->MinimumSize().iHeight : 0;
+}
+
+
+void CMIDChoiceGroupItem::CreateChoiceGroupControlL(CCoeControl* aParent)
+{
+    // Create an actual choice control
+    if (iChoiceGroupControl)
+    {
+        // Create one
+        TRect labelRect;
+        TRect choiceRect;
+        CalcChildSizes(Rect(), labelRect, choiceRect);
+
+        iChoiceGroupControl->CreateControlL(aParent, choiceRect);
+    }
+}
+
+
+//  Calculates child control sizes
+void CMIDChoiceGroupItem::CalcChildSizes(
+    const TRect& aItemRect,
+    TRect& aLabelRect,
+    TRect& aChoiceRect)
+{
+    aLabelRect.SetRect(aItemRect.iTl, TSize(aItemRect.Width(), LabelHeight()));
+
+    aChoiceRect = aItemRect;
+    aChoiceRect.iTl.iY += aLabelRect.Height();
+}
+
+/** */
+void CMIDChoiceGroupItem::ResolutionChange(TInt aType)
+{
+    if (aType == KEikDynamicLayoutVariantSwitch && iForm)
+    { // dynamic resolution change
+        TRAP_IGNORE(CreateChoiceGroupControlL(iForm));
+        // After the listbox is recreated it shows the focus indication by default.
+        // Clear it if this item is not the one having focus on the form.
+        if (iForm->CurrentItem() != this)
+        {
+            iChoiceGroupControl->EnableListHighlight(EFalse);
+        }
+    }
+
+    // warn choice group control of layout change
+    if (aType == KEikDynamicLayoutVariantSwitch && iChoiceGroupControl)
+    {
+        iChoiceGroupControl->HandleResourceChange(aType);
+    }
+}
+
+void CMIDChoiceGroupItem::ColorChange(TInt /*aType*/)
+{
+    if (iForm)
+    {
+        TRAP_IGNORE(CreateChoiceGroupControlL(iForm));
+        // After the listbox is recreated it shows the focus indication by default.
+        // Clear it if this item is not the one having focus on the form.
+        if (iForm->CurrentItem() != this)
+        {
+            iChoiceGroupControl->EnableListHighlight(EFalse);
+        }
+    }
+}
+
+void CMIDChoiceGroupItem::SetLabelL(const TDesC& aLabel)
+{
+    CMIDControlItem::SetLabelL(aLabel);
+}
+
+void CMIDChoiceGroupItem::SetLayoutL(TLayout aLayout)
+{
+    CMIDControlItem::SetLayoutL(aLayout);
+}
+
+void CMIDChoiceGroupItem::Dispose()
+{
+    delete this;
+}
+
+void CMIDChoiceGroupItem::AddCommandL(MMIDCommand* aCommand)
+{
+    // Add command to item, don't notify form twice
+    CMIDControlItem::AddCommandL(aCommand, EFalse);
+    // UpdateCommands() calls  form notification
+    UpdateCommands();
+}
+
+void CMIDChoiceGroupItem::RemoveCommand(MMIDCommand* aCommand)
+{
+    // Remove command to item, don't notify form twice
+    CMIDControlItem::RemoveCommand(aCommand, EFalse);
+    // UpdateCommands() calls  form notification
+    UpdateCommands();
+}
+
+void CMIDChoiceGroupItem::SetDefaultCommand(MMIDCommand* aCommand)
+{
+    CMIDControlItem::SetDefaultCommand(aCommand);
+}
+
+void CMIDChoiceGroupItem::SetPreferredSizeL(const TSize& aSize)
+{
+    CMIDControlItem::SetPreferredSize(aSize, MinimumSize());
+}
+
+TSize CMIDChoiceGroupItem::PreferredSize() const
+{
+    return ResetPreferredSize();
+}
+
+TSize CMIDChoiceGroupItem::MinimumSize() const
+{
+    // Const cast to make this call the CCoeControl overridden MinimumSize()
+    CCoeControl* control = const_cast<CMIDChoiceGroupItem *>(this);
+    return control->MinimumSize();
+}
+
+void CMIDChoiceGroupItem::SafeDrawNow()
+{
+    if (DrawableWindow())
+    {
+        DrawNow();
+    }
+}
+
+TRect CMIDChoiceGroupItem::FormRect()
+{
+    if (iForm)
+    {
+        return iForm->Rect();
+    }
+    else
+    {
+        return (TRect(0, 0, 0, 0));
+    }
+}
+
+// End of File