widgetmodel/alfwidgetmodel/src/alflayoutmanagerimpl.cpp
branchRCL_3
changeset 19 4ea6f81c838a
parent 17 514d98f21c43
child 20 0e9bb658ef58
equal deleted inserted replaced
17:514d98f21c43 19:4ea6f81c838a
     1 /*
       
     2 * Copyright (c) 2007 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:  layoutmanager implementation class with focus handling in 1D (next/previous)
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <alf/ialfwidgetcontrol.h>
       
    20 #include "alf/ialfattributeowner.h"
       
    21 #include "alf/alfattribute.h"
       
    22 #include <alf/alfvisual.h>
       
    23 #include <alf/alfenv.h>
       
    24 #include "alf/alfwidget.h"
       
    25 #include <alf/alfvisualfactory.h>
       
    26 #include <alf/alfexceptions.h>
       
    27 #include <alf/ialflayoutpreferences.h>
       
    28 #include <alf/alfwidgetenvextension.h>
       
    29 #include <alf/ialfwidgetfactory.h>
       
    30 #include <osn/osnnew.h>
       
    31 #include <libc/assert.h>
       
    32 #include <alf/attrproperty.h>
       
    33 #include "alflayoutmanagerimpl.h"
       
    34 
       
    35 
       
    36 
       
    37 namespace Alf
       
    38     {
       
    39 
       
    40 //ifdef to prevent compiler warning: className not used.
       
    41 #ifdef ALF_DEBUG_EXCEPTIONS
       
    42 static const char* const className = "AlfLayoutManagerImpl";
       
    43 #endif
       
    44 
       
    45 // ======== MEMBER FUNCTIONS ========
       
    46     
       
    47 // ---------------------------------------------------------------------------
       
    48 // layoutmanagerimpl constructor
       
    49 // ---------------------------------------------------------------------------
       
    50 //    
       
    51 AlfLayoutManagerImpl::AlfLayoutManagerImpl(
       
    52     TAlfLayoutType aLayoutType)
       
    53     {
       
    54     mLayoutType = aLayoutType;
       
    55     }
       
    56     
       
    57 // ---------------------------------------------------------------------------
       
    58 // creates the layout used by the layoutmanager.
       
    59 // ---------------------------------------------------------------------------
       
    60 //    
       
    61 AlfLayoutManagerImpl::~AlfLayoutManagerImpl()
       
    62     {
       
    63     if (mLayout.get())
       
    64         {
       
    65         CAlfLayout* layout = mLayout.release();
       
    66         layout->RemoveAndDestroyAllD();
       
    67         }
       
    68     }
       
    69     
       
    70 // ---------------------------------------------------------------------------
       
    71 // creates the layout used by the layoutmanager.
       
    72 // ---------------------------------------------------------------------------
       
    73 //    
       
    74 void AlfLayoutManagerImpl::createLayout(CAlfWidgetControl& aOwner, 
       
    75     CAlfLayout* aParentLayout, int aLayoutIndex)
       
    76     {
       
    77             
       
    78     //check parameter validity.
       
    79     if (aParentLayout && 
       
    80         (aLayoutIndex < 0 ||aLayoutIndex > aParentLayout->Count()))
       
    81         {
       
    82         ALF_THROW(AlfException, EInvalidArrayIndex, className);
       
    83         }
       
    84         
       
    85     //create layout
       
    86     CAlfLayout* layout = 0;
       
    87     TRAPD(err, layout = aOwner.AppendLayoutL(mLayoutType, aParentLayout));
       
    88         
       
    89 	if(!layout || err != KErrNone)
       
    90 	    {
       
    91 	    ALF_THROW(AlfVisualException, ECanNotCreateVisual, className);
       
    92 	    }
       
    93 
       
    94     //reorder, if needed.
       
    95     if (aParentLayout && aLayoutIndex != aParentLayout->Count() - 1)
       
    96         {
       
    97         aParentLayout->Reorder(*layout, aLayoutIndex);
       
    98         }
       
    99         
       
   100     mLayout.reset(layout);
       
   101     }
       
   102     
       
   103 // ---------------------------------------------------------------------------
       
   104 // returns the layout used by the layoutmanager.
       
   105 // ---------------------------------------------------------------------------
       
   106 //    
       
   107 CAlfLayout& AlfLayoutManagerImpl::getLayout() const
       
   108     {
       
   109     checkLayout();
       
   110     return *mLayout.get();
       
   111     }
       
   112     
       
   113 // ---------------------------------------------------------------------------
       
   114 // updates the main layout
       
   115 // ---------------------------------------------------------------------------
       
   116 //
       
   117 void AlfLayoutManagerImpl::updateMainLayout()
       
   118     {
       
   119     checkLayout();
       
   120     
       
   121     const IAlfLayoutPreferences* layoutPrefs = 
       
   122         getLayoutPreferences(getControl(*mLayout.get()));
       
   123     if (layoutPrefs)
       
   124         {
       
   125         TAlfXYMetric prefSize;
       
   126         if (layoutPrefs->getPreferredSize(prefSize))
       
   127             {
       
   128             TAlfRealPoint p(prefSize.iX.iMagnitude, 
       
   129                             prefSize.iY.iMagnitude);
       
   130             mLayout->SetSize(p);
       
   131             }
       
   132         }
       
   133     }
       
   134     
       
   135 // ---------------------------------------------------------------------------
       
   136 // notifies the layout manager, that the control's has been
       
   137 // removed from the layout.
       
   138 // ---------------------------------------------------------------------------
       
   139 //
       
   140 void AlfLayoutManagerImpl::childRemoved(CAlfWidgetControl* /*aControl*/)
       
   141     {
       
   142     checkLayout();
       
   143     mLayout->UpdateChildrenLayout();
       
   144     }
       
   145     
       
   146 // ---------------------------------------------------------------------------
       
   147 // returns the owner control of the layoutmanager.
       
   148 // ---------------------------------------------------------------------------
       
   149 //
       
   150 CAlfWidgetControl& AlfLayoutManagerImpl::owner() const
       
   151     {
       
   152     checkLayout();
       
   153     CAlfWidgetControl* widgetControl = 0;
       
   154     
       
   155     /* The owner is always a AlfWidgetControl.
       
   156        So a static_cast is safe. see AlfLayoutManagerImpl::createLayout() */ 
       
   157     widgetControl = static_cast<CAlfWidgetControl*>(
       
   158                                      &mLayout->Owner());
       
   159    
       
   160     return *widgetControl;
       
   161     }
       
   162 
       
   163 // ---------------------------------------------------------------------------
       
   164 // from IAlfLayoutPreferences
       
   165 // Returns the minimum area that this layout manager can occupy by observing
       
   166 // the minimum sizes of the child UI elements in the layout
       
   167 // ---------------------------------------------------------------------------
       
   168 //
       
   169 bool AlfLayoutManagerImpl::getMinimumSize( TAlfXYMetric& /*aMinSize*/ ) const
       
   170 	{
       
   171 	return false;
       
   172 	}
       
   173 
       
   174 // ---------------------------------------------------------------------------
       
   175 // from IAlfLayoutPreferences
       
   176 // Returns the maximum area that this layout manager can occupy by observing
       
   177 // the maximum sizes of the child UI elements in the layout
       
   178 // ---------------------------------------------------------------------------
       
   179 //
       
   180 bool AlfLayoutManagerImpl::getMaximumSize( TAlfXYMetric& /*aMaxSize*/ ) const
       
   181 	{
       
   182 	return false;
       
   183 	}
       
   184 
       
   185 // ---------------------------------------------------------------------------
       
   186 // Combines and returns the preferred sizes of all child UI elements according
       
   187 // to the layouting rules.
       
   188 // ---------------------------------------------------------------------------
       
   189 //
       
   190 bool AlfLayoutManagerImpl::getPreferredSize(TAlfXYMetric& /*aPreferredSize*/) const
       
   191 	{
       
   192 	return false;
       
   193 	}
       
   194  
       
   195 // ---------------------------------------------------------------------------
       
   196 // from IAlfLayoutPreferences
       
   197 // At the moment doesn't do anything since preferred size is being queried
       
   198 // from the child UI elements added to this layout manager.
       
   199 // ---------------------------------------------------------------------------
       
   200 //
       
   201 void AlfLayoutManagerImpl::setPreferredSize( const TAlfXYMetric& /*aPreferredSize*/ )
       
   202 	{
       
   203 	
       
   204 	}
       
   205 
       
   206 // ---------------------------------------------------------------------------
       
   207 // From class IAlfInterfaceBase.
       
   208 // Getter for interfaces provided by the element.
       
   209 // ---------------------------------------------------------------------------
       
   210 //
       
   211 IAlfInterfaceBase* AlfLayoutManagerImpl::makeInterface(const IfId& aType)
       
   212     {
       
   213     UString param(aType.mImplementationId);
       
   214     if (param == IAlfLayoutPreferences::type().mImplementationId)
       
   215         {
       
   216         return static_cast<IAlfLayoutPreferences*>(this);
       
   217         }      
       
   218     
       
   219     return 0;
       
   220     }
       
   221 
       
   222 // ---------------------------------------------------------------------------
       
   223 // gets control at aIndex position in the layout.
       
   224 // ---------------------------------------------------------------------------
       
   225 //    
       
   226 CAlfWidgetControl* AlfLayoutManagerImpl::getControl(int aIndex) const
       
   227     {
       
   228     CAlfWidgetControl* control = 0;
       
   229     CAlfLayout* layout = mLayout.get();
       
   230     if (layout)
       
   231         {
       
   232         CAlfVisual& visual = layout->Visual(aIndex);
       
   233         control = getControl(visual);
       
   234         }
       
   235     return control;
       
   236     }
       
   237     
       
   238 // ---------------------------------------------------------------------------
       
   239 // returns the control, which owns the visual
       
   240 // ---------------------------------------------------------------------------
       
   241 //     
       
   242 void AlfLayoutManagerImpl::doUpdateChildLayout(CAlfWidgetControl* aControl)
       
   243     {
       
   244     const IAlfLayoutPreferences* layoutPrefs = 
       
   245         getLayoutPreferences(aControl);
       
   246         
       
   247     if (layoutPrefs)
       
   248         {
       
   249         TAlfXYMetric prefSize;
       
   250         if (layoutPrefs->getPreferredSize(prefSize))
       
   251             {
       
   252             CAlfVisual* v = findRootVisual(aControl);
       
   253             if (v)
       
   254                 {
       
   255                 v->SetSize(TAlfRealPoint(prefSize.iX.iMagnitude,
       
   256                 prefSize.iY.iMagnitude));
       
   257                 }
       
   258             }
       
   259         }
       
   260     }
       
   261 
       
   262 // ---------------------------------------------------------------------------
       
   263 // returns the size of the widget.
       
   264 // ---------------------------------------------------------------------------
       
   265 //
       
   266 bool AlfLayoutManagerImpl::controlRect(CAlfWidgetControl& aControl, 
       
   267     TAlfRealRect& aRect)
       
   268     {
       
   269     CAlfVisual* v = findRootVisual(&aControl);
       
   270     if (v != 0)
       
   271         {
       
   272         TAlfRealPoint size(v->Size().Target());
       
   273         TAlfRealPoint pos(v->Pos().Target());
       
   274         aRect.iTl = pos;
       
   275         aRect.iBr.iX = pos.iX + size.iX;
       
   276         aRect.iBr.iY = pos.iY + size.iY;
       
   277         return true;
       
   278         }
       
   279         
       
   280     return false;
       
   281     }
       
   282     
       
   283 // ---------------------------------------------------------------------------
       
   284 // set the size and position to the widget.
       
   285 // ---------------------------------------------------------------------------
       
   286 //
       
   287 void AlfLayoutManagerImpl::setWidgetRect(IAlfWidget& aWidget, const TAlfRealRect &aRect)
       
   288     {
       
   289     const UString widthName(layoutattributes::KWidth);
       
   290     const UString heightName(layoutattributes::KHeight);
       
   291     const UString posX(layoutattributes::KPositionX);
       
   292     const UString posY(layoutattributes::KPositionY);
       
   293     
       
   294     IAlfAttributeOwner* attrOwner = 
       
   295         IAlfInterfaceBase::makeInterface<IAlfAttributeOwner>(&aWidget);
       
   296     if (attrOwner)
       
   297         {
       
   298     	auto_ptr<AlfAttributeValueType> w(
       
   299     	    new (EMM) AlfAttributeValueType(aRect.Width()));
       
   300     	auto_ptr<AlfAttributeValueType> h(
       
   301     	    new (EMM) AlfAttributeValueType(aRect.Height()));
       
   302     	auto_ptr<AlfAttributeValueType> x(
       
   303     	    new (EMM) AlfAttributeValueType(aRect.iTl.iX));
       
   304     	auto_ptr<AlfAttributeValueType> y(
       
   305     	    new (EMM) AlfAttributeValueType(aRect.iTl.iY));
       
   306     	attrOwner->setAttribute(heightName, h.get());
       
   307     	attrOwner->setAttribute(widthName, w.get());
       
   308     	attrOwner->setAttribute(posX, x.get());
       
   309     	attrOwner->setAttribute(posY, y.get());
       
   310     	
       
   311     	h.release();
       
   312     	w.release();
       
   313     	x.release();
       
   314     	y.release();
       
   315         }
       
   316     }  
       
   317     
       
   318 // ---------------------------------------------------------------------------
       
   319 // set the position for the widget.
       
   320 // ---------------------------------------------------------------------------
       
   321 //
       
   322 void AlfLayoutManagerImpl::setWidgetPosition(IAlfWidget& aWidget, 
       
   323     const TAlfRealPoint &aPos)
       
   324     {
       
   325     const UString posX(layoutattributes::KPositionX);
       
   326     const UString posY(layoutattributes::KPositionY);
       
   327     
       
   328     IAlfAttributeOwner* attrOwner = 
       
   329         IAlfInterfaceBase::makeInterface<IAlfAttributeOwner>(&aWidget);
       
   330     if (attrOwner)
       
   331         {
       
   332     	auto_ptr<AlfAttributeValueType> x(
       
   333     	    new (EMM) AlfAttributeValueType(aPos.iX));
       
   334     	auto_ptr<AlfAttributeValueType> y(
       
   335     	    new (EMM) AlfAttributeValueType(aPos.iY));
       
   336     	attrOwner->setAttribute(posX, x.get());
       
   337     	attrOwner->setAttribute(posY, y.get());
       
   338     	x.release();
       
   339     	y.release();
       
   340         }
       
   341     }
       
   342     
       
   343 // ---------------------------------------------------------------------------
       
   344 // set the size for the widget.
       
   345 // ---------------------------------------------------------------------------
       
   346 //
       
   347 void AlfLayoutManagerImpl::setWidgetSize(IAlfWidget& aWidget, const TAlfRealPoint &aSize)
       
   348     {
       
   349     const UString widthName(layoutattributes::KWidth);
       
   350     const UString heightName(layoutattributes::KHeight);
       
   351     IAlfAttributeOwner* attrOwner = 
       
   352         IAlfInterfaceBase::makeInterface<IAlfAttributeOwner>(&aWidget);
       
   353     if (attrOwner)
       
   354         {
       
   355     	auto_ptr<AlfAttributeValueType> w(
       
   356     	    new (EMM) AlfAttributeValueType(aSize.iX));
       
   357     	auto_ptr<AlfAttributeValueType> h(
       
   358     	    new (EMM) AlfAttributeValueType(aSize.iY));
       
   359     	attrOwner->setAttribute(heightName, h.get());
       
   360     	attrOwner->setAttribute(widthName, w.get());
       
   361     	h.release();
       
   362     	w.release();
       
   363         }
       
   364     }
       
   365     
       
   366 // ---------------------------------------------------------------------------
       
   367 // updates widget size and position properties for all the children
       
   368 // to correct sizes and positions of the root visuals.
       
   369 // ---------------------------------------------------------------------------
       
   370 //    
       
   371 void AlfLayoutManagerImpl::updateAllWidgetRects()
       
   372     {
       
   373     const int childCount = mLayout->Count();
       
   374     TAlfRealRect rect;
       
   375     for (int i = 0; i < childCount; i++)
       
   376         {
       
   377         CAlfWidgetControl* control = getControl(i);
       
   378         controlRect(*control, rect); //returns the real rect(of the root visual)
       
   379         AlfWidget* widget = control->widget();
       
   380         if(widget)
       
   381             {
       
   382             const char* name = widget->widgetName(); 
       
   383             IAlfWidget* ownerwidget = AlfWidgetEnvExtension::widgetFactory(control->Env()).findWidget(name); 
       
   384             if (ownerwidget)
       
   385                 {
       
   386                 setWidgetRect(*ownerwidget, rect); //sets the rect using widget properties.
       
   387                 }
       
   388             }
       
   389         }
       
   390     
       
   391     }
       
   392     
       
   393 // ---------------------------------------------------------------------------
       
   394 // returns the child visual count
       
   395 // ---------------------------------------------------------------------------
       
   396 //
       
   397 int AlfLayoutManagerImpl::count() const
       
   398     {
       
   399     return getLayout().Count();
       
   400     }    
       
   401 
       
   402 // ---------------------------------------------------------------------------
       
   403 // returns the control, which owns the visual
       
   404 // ---------------------------------------------------------------------------
       
   405 //      
       
   406 CAlfWidgetControl* AlfLayoutManagerImpl::getControl(CAlfVisual& aVisual) const
       
   407     {
       
   408     CAlfWidgetControl* temp = 0;
       
   409     temp = dynamic_cast<CAlfWidgetControl*>(&aVisual.Owner());
       
   410     return temp;
       
   411     }
       
   412     
       
   413 // ---------------------------------------------------------------------------
       
   414 // returns the control, which owns the visual
       
   415 // ---------------------------------------------------------------------------
       
   416 //      
       
   417 const IAlfLayoutPreferences* AlfLayoutManagerImpl::getLayoutPreferences(
       
   418     CAlfWidgetControl* aControl) const
       
   419     {
       
   420     IAlfLayoutPreferences* layoutPrefs = 0;
       
   421     if (aControl)
       
   422         {
       
   423         layoutPrefs = 
       
   424             CAlfWidgetControl::makeInterface<IAlfLayoutPreferences>(aControl);
       
   425         }
       
   426         
       
   427     return layoutPrefs;
       
   428     }
       
   429    
       
   430 // ---------------------------------------------------------------------------
       
   431 // finds the root visual for a control.
       
   432 // ---------------------------------------------------------------------------
       
   433 //    
       
   434 CAlfVisual* AlfLayoutManagerImpl::findRootVisual(CAlfWidgetControl* aControl) const
       
   435     {
       
   436     CAlfVisual* root = 0;
       
   437     if (aControl->VisualCount() > 0)
       
   438         {
       
   439         //take first visual, 
       
   440         //go up in layout hierarchy until the control is not owner anymore.
       
   441         for (root = &aControl->Visual(0); 
       
   442              root && root->Layout() && &root->Layout()->Owner() == aControl;
       
   443              root = root->Layout()){}
       
   444         }
       
   445     return root;
       
   446     }
       
   447 
       
   448 // ---------------------------------------------------------------------------
       
   449 // throws an exception, if layout is not created.
       
   450 // ---------------------------------------------------------------------------
       
   451 //    
       
   452 void AlfLayoutManagerImpl::checkLayout() const
       
   453     {
       
   454     if (!mLayout.get())
       
   455         {
       
   456         ALF_THROW(AlfVisualException, EInvalidVisual, className);
       
   457         }
       
   458     }
       
   459 
       
   460  } // Alf