diff -r 4ea6f81c838a -r 0e9bb658ef58 widgetmodel/alfwidgetmodel/src/alflayoutmanagerimpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgetmodel/alfwidgetmodel/src/alflayoutmanagerimpl.cpp Wed Sep 01 12:23:18 2010 +0100 @@ -0,0 +1,460 @@ +/* +* Copyright (c) 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: layoutmanager implementation class with focus handling in 1D (next/previous) +* +*/ + + +#include +#include "alf/ialfattributeowner.h" +#include "alf/alfattribute.h" +#include +#include +#include "alf/alfwidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "alflayoutmanagerimpl.h" + + + +namespace Alf + { + +//ifdef to prevent compiler warning: className not used. +#ifdef ALF_DEBUG_EXCEPTIONS +static const char* const className = "AlfLayoutManagerImpl"; +#endif + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// layoutmanagerimpl constructor +// --------------------------------------------------------------------------- +// +AlfLayoutManagerImpl::AlfLayoutManagerImpl( + TAlfLayoutType aLayoutType) + { + mLayoutType = aLayoutType; + } + +// --------------------------------------------------------------------------- +// creates the layout used by the layoutmanager. +// --------------------------------------------------------------------------- +// +AlfLayoutManagerImpl::~AlfLayoutManagerImpl() + { + if (mLayout.get()) + { + CAlfLayout* layout = mLayout.release(); + layout->RemoveAndDestroyAllD(); + } + } + +// --------------------------------------------------------------------------- +// creates the layout used by the layoutmanager. +// --------------------------------------------------------------------------- +// +void AlfLayoutManagerImpl::createLayout(CAlfWidgetControl& aOwner, + CAlfLayout* aParentLayout, int aLayoutIndex) + { + + //check parameter validity. + if (aParentLayout && + (aLayoutIndex < 0 ||aLayoutIndex > aParentLayout->Count())) + { + ALF_THROW(AlfException, EInvalidArrayIndex, className); + } + + //create layout + CAlfLayout* layout = 0; + TRAPD(err, layout = aOwner.AppendLayoutL(mLayoutType, aParentLayout)); + + if(!layout || err != KErrNone) + { + ALF_THROW(AlfVisualException, ECanNotCreateVisual, className); + } + + //reorder, if needed. + if (aParentLayout && aLayoutIndex != aParentLayout->Count() - 1) + { + aParentLayout->Reorder(*layout, aLayoutIndex); + } + + mLayout.reset(layout); + } + +// --------------------------------------------------------------------------- +// returns the layout used by the layoutmanager. +// --------------------------------------------------------------------------- +// +CAlfLayout& AlfLayoutManagerImpl::getLayout() const + { + checkLayout(); + return *mLayout.get(); + } + +// --------------------------------------------------------------------------- +// updates the main layout +// --------------------------------------------------------------------------- +// +void AlfLayoutManagerImpl::updateMainLayout() + { + checkLayout(); + + const IAlfLayoutPreferences* layoutPrefs = + getLayoutPreferences(getControl(*mLayout.get())); + if (layoutPrefs) + { + TAlfXYMetric prefSize; + if (layoutPrefs->getPreferredSize(prefSize)) + { + TAlfRealPoint p(prefSize.iX.iMagnitude, + prefSize.iY.iMagnitude); + mLayout->SetSize(p); + } + } + } + +// --------------------------------------------------------------------------- +// notifies the layout manager, that the control's has been +// removed from the layout. +// --------------------------------------------------------------------------- +// +void AlfLayoutManagerImpl::childRemoved(CAlfWidgetControl* /*aControl*/) + { + checkLayout(); + mLayout->UpdateChildrenLayout(); + } + +// --------------------------------------------------------------------------- +// returns the owner control of the layoutmanager. +// --------------------------------------------------------------------------- +// +CAlfWidgetControl& AlfLayoutManagerImpl::owner() const + { + checkLayout(); + CAlfWidgetControl* widgetControl = 0; + + /* The owner is always a AlfWidgetControl. + So a static_cast is safe. see AlfLayoutManagerImpl::createLayout() */ + widgetControl = static_cast( + &mLayout->Owner()); + + return *widgetControl; + } + +// --------------------------------------------------------------------------- +// from IAlfLayoutPreferences +// Returns the minimum area that this layout manager can occupy by observing +// the minimum sizes of the child UI elements in the layout +// --------------------------------------------------------------------------- +// +bool AlfLayoutManagerImpl::getMinimumSize( TAlfXYMetric& /*aMinSize*/ ) const + { + return false; + } + +// --------------------------------------------------------------------------- +// from IAlfLayoutPreferences +// Returns the maximum area that this layout manager can occupy by observing +// the maximum sizes of the child UI elements in the layout +// --------------------------------------------------------------------------- +// +bool AlfLayoutManagerImpl::getMaximumSize( TAlfXYMetric& /*aMaxSize*/ ) const + { + return false; + } + +// --------------------------------------------------------------------------- +// Combines and returns the preferred sizes of all child UI elements according +// to the layouting rules. +// --------------------------------------------------------------------------- +// +bool AlfLayoutManagerImpl::getPreferredSize(TAlfXYMetric& /*aPreferredSize*/) const + { + return false; + } + +// --------------------------------------------------------------------------- +// from IAlfLayoutPreferences +// At the moment doesn't do anything since preferred size is being queried +// from the child UI elements added to this layout manager. +// --------------------------------------------------------------------------- +// +void AlfLayoutManagerImpl::setPreferredSize( const TAlfXYMetric& /*aPreferredSize*/ ) + { + + } + +// --------------------------------------------------------------------------- +// From class IAlfInterfaceBase. +// Getter for interfaces provided by the element. +// --------------------------------------------------------------------------- +// +IAlfInterfaceBase* AlfLayoutManagerImpl::makeInterface(const IfId& aType) + { + UString param(aType.mImplementationId); + if (param == IAlfLayoutPreferences::type().mImplementationId) + { + return static_cast(this); + } + + return 0; + } + +// --------------------------------------------------------------------------- +// gets control at aIndex position in the layout. +// --------------------------------------------------------------------------- +// +CAlfWidgetControl* AlfLayoutManagerImpl::getControl(int aIndex) const + { + CAlfWidgetControl* control = 0; + CAlfLayout* layout = mLayout.get(); + if (layout) + { + CAlfVisual& visual = layout->Visual(aIndex); + control = getControl(visual); + } + return control; + } + +// --------------------------------------------------------------------------- +// returns the control, which owns the visual +// --------------------------------------------------------------------------- +// +void AlfLayoutManagerImpl::doUpdateChildLayout(CAlfWidgetControl* aControl) + { + const IAlfLayoutPreferences* layoutPrefs = + getLayoutPreferences(aControl); + + if (layoutPrefs) + { + TAlfXYMetric prefSize; + if (layoutPrefs->getPreferredSize(prefSize)) + { + CAlfVisual* v = findRootVisual(aControl); + if (v) + { + v->SetSize(TAlfRealPoint(prefSize.iX.iMagnitude, + prefSize.iY.iMagnitude)); + } + } + } + } + +// --------------------------------------------------------------------------- +// returns the size of the widget. +// --------------------------------------------------------------------------- +// +bool AlfLayoutManagerImpl::controlRect(CAlfWidgetControl& aControl, + TAlfRealRect& aRect) + { + CAlfVisual* v = findRootVisual(&aControl); + if (v != 0) + { + TAlfRealPoint size(v->Size().Target()); + TAlfRealPoint pos(v->Pos().Target()); + aRect.iTl = pos; + aRect.iBr.iX = pos.iX + size.iX; + aRect.iBr.iY = pos.iY + size.iY; + return true; + } + + return false; + } + +// --------------------------------------------------------------------------- +// set the size and position to the widget. +// --------------------------------------------------------------------------- +// +void AlfLayoutManagerImpl::setWidgetRect(IAlfWidget& aWidget, const TAlfRealRect &aRect) + { + const UString widthName(layoutattributes::KWidth); + const UString heightName(layoutattributes::KHeight); + const UString posX(layoutattributes::KPositionX); + const UString posY(layoutattributes::KPositionY); + + IAlfAttributeOwner* attrOwner = + IAlfInterfaceBase::makeInterface(&aWidget); + if (attrOwner) + { + auto_ptr w( + new (EMM) AlfAttributeValueType(aRect.Width())); + auto_ptr h( + new (EMM) AlfAttributeValueType(aRect.Height())); + auto_ptr x( + new (EMM) AlfAttributeValueType(aRect.iTl.iX)); + auto_ptr y( + new (EMM) AlfAttributeValueType(aRect.iTl.iY)); + attrOwner->setAttribute(heightName, h.get()); + attrOwner->setAttribute(widthName, w.get()); + attrOwner->setAttribute(posX, x.get()); + attrOwner->setAttribute(posY, y.get()); + + h.release(); + w.release(); + x.release(); + y.release(); + } + } + +// --------------------------------------------------------------------------- +// set the position for the widget. +// --------------------------------------------------------------------------- +// +void AlfLayoutManagerImpl::setWidgetPosition(IAlfWidget& aWidget, + const TAlfRealPoint &aPos) + { + const UString posX(layoutattributes::KPositionX); + const UString posY(layoutattributes::KPositionY); + + IAlfAttributeOwner* attrOwner = + IAlfInterfaceBase::makeInterface(&aWidget); + if (attrOwner) + { + auto_ptr x( + new (EMM) AlfAttributeValueType(aPos.iX)); + auto_ptr y( + new (EMM) AlfAttributeValueType(aPos.iY)); + attrOwner->setAttribute(posX, x.get()); + attrOwner->setAttribute(posY, y.get()); + x.release(); + y.release(); + } + } + +// --------------------------------------------------------------------------- +// set the size for the widget. +// --------------------------------------------------------------------------- +// +void AlfLayoutManagerImpl::setWidgetSize(IAlfWidget& aWidget, const TAlfRealPoint &aSize) + { + const UString widthName(layoutattributes::KWidth); + const UString heightName(layoutattributes::KHeight); + IAlfAttributeOwner* attrOwner = + IAlfInterfaceBase::makeInterface(&aWidget); + if (attrOwner) + { + auto_ptr w( + new (EMM) AlfAttributeValueType(aSize.iX)); + auto_ptr h( + new (EMM) AlfAttributeValueType(aSize.iY)); + attrOwner->setAttribute(heightName, h.get()); + attrOwner->setAttribute(widthName, w.get()); + h.release(); + w.release(); + } + } + +// --------------------------------------------------------------------------- +// updates widget size and position properties for all the children +// to correct sizes and positions of the root visuals. +// --------------------------------------------------------------------------- +// +void AlfLayoutManagerImpl::updateAllWidgetRects() + { + const int childCount = mLayout->Count(); + TAlfRealRect rect; + for (int i = 0; i < childCount; i++) + { + CAlfWidgetControl* control = getControl(i); + controlRect(*control, rect); //returns the real rect(of the root visual) + AlfWidget* widget = control->widget(); + if(widget) + { + const char* name = widget->widgetName(); + IAlfWidget* ownerwidget = AlfWidgetEnvExtension::widgetFactory(control->Env()).findWidget(name); + if (ownerwidget) + { + setWidgetRect(*ownerwidget, rect); //sets the rect using widget properties. + } + } + } + + } + +// --------------------------------------------------------------------------- +// returns the child visual count +// --------------------------------------------------------------------------- +// +int AlfLayoutManagerImpl::count() const + { + return getLayout().Count(); + } + +// --------------------------------------------------------------------------- +// returns the control, which owns the visual +// --------------------------------------------------------------------------- +// +CAlfWidgetControl* AlfLayoutManagerImpl::getControl(CAlfVisual& aVisual) const + { + CAlfWidgetControl* temp = 0; + temp = dynamic_cast(&aVisual.Owner()); + return temp; + } + +// --------------------------------------------------------------------------- +// returns the control, which owns the visual +// --------------------------------------------------------------------------- +// +const IAlfLayoutPreferences* AlfLayoutManagerImpl::getLayoutPreferences( + CAlfWidgetControl* aControl) const + { + IAlfLayoutPreferences* layoutPrefs = 0; + if (aControl) + { + layoutPrefs = + CAlfWidgetControl::makeInterface(aControl); + } + + return layoutPrefs; + } + +// --------------------------------------------------------------------------- +// finds the root visual for a control. +// --------------------------------------------------------------------------- +// +CAlfVisual* AlfLayoutManagerImpl::findRootVisual(CAlfWidgetControl* aControl) const + { + CAlfVisual* root = 0; + if (aControl->VisualCount() > 0) + { + //take first visual, + //go up in layout hierarchy until the control is not owner anymore. + for (root = &aControl->Visual(0); + root && root->Layout() && &root->Layout()->Owner() == aControl; + root = root->Layout()){} + } + return root; + } + +// --------------------------------------------------------------------------- +// throws an exception, if layout is not created. +// --------------------------------------------------------------------------- +// +void AlfLayoutManagerImpl::checkLayout() const + { + if (!mLayout.get()) + { + ALF_THROW(AlfVisualException, EInvalidVisual, className); + } + } + + } // Alf