Encapsulation and harmonizing operators for LayoutLength
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / custom-layout-impl.cpp
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 // CLASS HEADER
18 #include "custom-layout-impl.h"
19
20 // EXTERNAL INCLUDES
21 #include <dali/public-api/actors/actor.h>
22 #include <dali-toolkit/devel-api/controls/control-devel.h>
23
24 namespace Test
25 {
26
27 namespace Internal
28 {
29
30 using Dali::Actor;
31 using Dali::Toolkit::MeasuredSize;
32
33 CustomLayout::CustomLayout()
34 : mBehaviourFlags( 0 )
35 {
36 }
37
38 CustomLayoutPtr CustomLayout::New()
39 {
40   CustomLayoutPtr layout( new CustomLayout() );
41   return layout;
42 }
43
44 void CustomLayout::MeasureChildren( Dali::Toolkit::Internal::LayoutItemPtr childLayout, MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec, LayoutLength resultingWidth, LayoutLength resultingHeight )
45 {
46   // Initially use the measure spec of the child's parent
47   auto childWidthMeasureSpec = widthMeasureSpec;
48   auto childHeightMeasureSpec = heightMeasureSpec;
49
50   if ( true == GetCustomBehaviourFlags( Test::CustomLayout::BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_WIDTH ) )
51   {
52     // Use unspecified width measure spec, child can be any width it desires
53     childWidthMeasureSpec = MeasureSpec( widthMeasureSpec.GetSize(), MeasureSpec::Mode::UNSPECIFIED );
54   }
55
56   if ( true == GetCustomBehaviourFlags( Test::CustomLayout::BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_HEIGHT) )
57   {
58     // Use unspecified height measure spec, child can be any height it desires
59     childHeightMeasureSpec = MeasureSpec( heightMeasureSpec.GetSize(), MeasureSpec::Mode::UNSPECIFIED );
60   }
61
62   MeasureChild( childLayout, childWidthMeasureSpec, childHeightMeasureSpec );
63   resultingWidth += childLayout->GetMeasuredWidth();
64   resultingHeight = std::max( childLayout->GetMeasuredHeight(), resultingHeight );
65 }
66
67 void CustomLayout::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec )
68 {
69   auto accumulatedWidth = 0;
70   auto maxHeight = 0;
71
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
76
77   for( unsigned int i=0; i<GetChildCount(); ++i )
78   {
79     auto childLayout = GetChildAt( i );
80     if( childLayout )
81     {
82         MeasureChildren( childLayout, widthMeasureSpec, heightMeasureSpec, accumulatedWidth, maxHeight );
83     }
84   }
85
86   // Finally, call this method to set the dimensions we would like
87   SetMeasuredDimensions( MeasuredSize( accumulatedWidth ), MeasuredSize( maxHeight ) );
88 }
89
90 void CustomLayout::OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom )
91 {
92   LayoutLength childTop( 0 );
93   LayoutLength childLeft( 0 );
94
95   // We want to vertically align the children to the middle
96   LayoutLength height = bottom - top;
97   LayoutLength middle = height / 2;
98
99   auto owner = GetOwner();
100   auto actor = Actor::DownCast(owner);
101
102   // Horizontally align the children to the left
103   int count = actor.GetChildCount();
104   LayoutLength currentLeft = 0;
105
106   for( int i = 0; i < count; i++)
107   {
108     Dali::Toolkit::Control child = Dali::Toolkit::Control::DownCast( actor.GetChildAt( i ) );
109     if( !child )
110     {
111       continue;
112     }
113
114     Dali::Toolkit::LayoutItem childLayout = Dali::Toolkit::DevelControl::GetLayout( child );
115     if( childLayout )
116     {
117       Dali::Toolkit::Internal::LayoutItem& childLayoutImpl = GetImplementation( childLayout );
118
119       LayoutLength childWidth = childLayoutImpl.GetMeasuredWidth();
120       LayoutLength childHeight = childLayoutImpl.GetMeasuredHeight();
121
122       childTop = middle - childHeight / 2;
123       childLayoutImpl.Layout( currentLeft, childTop, currentLeft + childWidth, childTop + childHeight );
124       currentLeft += childWidth;
125     }
126   }
127 }
128
129 void CustomLayout::SetCustomBehaviourFlag( int flag )
130 {
131   mBehaviourFlags |= flag;
132   RequestLayout();
133 }
134
135 bool CustomLayout::GetCustomBehaviourFlags( int flagToCheck )
136 {
137   return ( mBehaviourFlags & flagToCheck ) != 0;
138 }
139
140 void CustomLayout::ClearPrivateFlag( int flag )
141 {
142     mBehaviourFlags &= ~flag;
143     RequestLayout();
144 }
145
146 } // namespace Internal
147
148 } // namespace Test