2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "custom-layout-impl.h"
21 #include <dali/public-api/actors/actor.h>
22 #include <dali-toolkit/devel-api/controls/control-devel.h>
31 using Dali::Toolkit::MeasuredSize;
33 CustomLayout::CustomLayout()
34 : mBehaviourFlags( 0 )
38 CustomLayoutPtr CustomLayout::New()
40 CustomLayoutPtr layout( new CustomLayout() );
44 void CustomLayout::MeasureChildren( Dali::Toolkit::Internal::LayoutItemPtr childLayout, MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec, LayoutLength resultingWidth, LayoutLength resultingHeight )
46 // Initially use the measure spec of the child's parent
47 auto childWidthMeasureSpec = widthMeasureSpec;
48 auto childHeightMeasureSpec = heightMeasureSpec;
50 if ( true == GetCustomBehaviourFlags( Test::CustomLayout::BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_WIDTH ) )
52 // Use unspecified width measure spec, child can be any width it desires
53 childWidthMeasureSpec = MeasureSpec( widthMeasureSpec.GetSize(), MeasureSpec::Mode::UNSPECIFIED );
56 if ( true == GetCustomBehaviourFlags( Test::CustomLayout::BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_HEIGHT) )
58 // Use unspecified height measure spec, child can be any height it desires
59 childHeightMeasureSpec = MeasureSpec( heightMeasureSpec.GetSize(), MeasureSpec::Mode::UNSPECIFIED );
62 MeasureChild( childLayout, childWidthMeasureSpec, childHeightMeasureSpec );
63 resultingWidth += childLayout->GetMeasuredWidth();
64 resultingHeight = std::max( childLayout->GetMeasuredHeight(), resultingHeight );
67 void CustomLayout::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec )
69 auto accumulatedWidth = 0;
72 // In this layout we will:
73 // Measuring the layout with the children in a horizontal configuration, one after another
74 // Set the required width to be the accumulated width of our children
75 // Set the required height to be the maximum height of any of our children
77 for( unsigned int i=0; i<GetChildCount(); ++i )
79 auto childLayout = GetChildAt( i );
82 MeasureChildren( childLayout, widthMeasureSpec, heightMeasureSpec, accumulatedWidth, maxHeight );
86 // Finally, call this method to set the dimensions we would like
87 SetMeasuredDimensions( MeasuredSize( accumulatedWidth ), MeasuredSize( maxHeight ) );
90 void CustomLayout::OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom )
92 LayoutLength childTop( 0 );
93 LayoutLength childLeft( 0 );
95 // We want to vertically align the children to the middle
96 LayoutLength height = bottom - top;
97 LayoutLength middle = height / 2;
99 auto owner = GetOwner();
100 auto actor = Actor::DownCast(owner);
102 // Horizontally align the children to the left
103 int count = actor.GetChildCount();
104 LayoutLength currentLeft = 0;
106 for( int i = 0; i < count; i++)
108 Dali::Toolkit::Control child = Dali::Toolkit::Control::DownCast( actor.GetChildAt( i ) );
114 Dali::Toolkit::LayoutItem childLayout = Dali::Toolkit::DevelControl::GetLayout( child );
117 Dali::Toolkit::Internal::LayoutItem& childLayoutImpl = GetImplementation( childLayout );
119 LayoutLength childWidth = childLayoutImpl.GetMeasuredWidth();
120 LayoutLength childHeight = childLayoutImpl.GetMeasuredHeight();
122 childTop = middle - childHeight / 2;
123 childLayoutImpl.Layout( currentLeft, childTop, currentLeft + childWidth, childTop + childHeight );
124 currentLeft += childWidth;
129 void CustomLayout::SetCustomBehaviourFlag( int flag )
131 mBehaviourFlags |= flag;
135 bool CustomLayout::GetCustomBehaviourFlags( int flagToCheck )
137 return ( mBehaviourFlags & flagToCheck ) != 0;
140 void CustomLayout::ClearPrivateFlag( int flag )
142 mBehaviourFlags &= ~flag;
146 } // namespace Internal