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.
17 #include <dali/public-api/common/stage.h>
18 #include <dali/public-api/actors/layer.h>
19 #include <dali-toolkit/internal/layouting/layout-controller-impl.h>
20 #include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
21 #include <dali-toolkit/public-api/controls/control.h>
22 #include <dali-toolkit/public-api/controls/control-impl.h>
23 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
24 #include <dali-toolkit/internal/layouting/layout-controller-debug.h>
28 #if defined(DEBUG_ENABLED)
29 static Debug::Filter* gLogFilter = Debug::Filter::New( Debug::Concise, false, "LOG_LAYOUT" );
39 LayoutController::LayoutController()
40 : mLayoutRequested(false)
44 LayoutController::~LayoutController()
48 void LayoutController::Initialize()
52 void LayoutController::RequestLayout( LayoutBase& layoutBase )
54 DALI_LOG_INFO( gLogFilter, Debug::Concise, "LayoutController::RequestLayout\n" );
55 mLayoutRequested = true;
57 // Go up the tree and mark all parents to relayout
58 LayoutParent* layoutParent = layoutBase.GetParent();
61 LayoutGroup& layoutGroup = static_cast< LayoutGroup& >( *layoutParent );
62 if( ! layoutGroup.IsLayoutRequested() )
64 layoutGroup.RequestLayout();
69 void LayoutController::Process()
71 // Perform the full process.
73 if( mLayoutRequested )
75 mLayoutRequested = false;
77 // If window size has changed, expect stage to have already been updated
78 Stage stage = Stage::GetCurrent();
79 auto stageWidth = stage.GetSize().width;
80 auto stageHeight = stage.GetSize().height;
82 auto widthSpec = MeasureSpec( stageWidth, MeasureSpec::Mode::EXACTLY );
83 auto heightSpec = MeasureSpec( stageHeight, MeasureSpec::Mode::EXACTLY );
85 // Test how to perform a measure on each control.
86 MeasureHierarchy( stage.GetRootLayer(), widthSpec, heightSpec );
88 LAYOUT_DEBUG_MEASURE_STATES( stage.GetRootLayer() );
89 PerformLayout( stage.GetRootLayer(), 0, 0, stageWidth, stageHeight );
91 LAYOUT_DEBUG_AFTER_LAYOUT( stage.GetRootLayer() );
95 void LayoutController::MeasureHierarchy( Actor root, MeasureSpec widthSpec, MeasureSpec heightSpec )
97 // Does this actor have a layout?
98 // Yes - measure the layout. It will call this method again for each of it's children.
99 // No - recurse through actor children.
101 // If in a leaf actor with no layout, it's natural size is bubbled back up.
103 // What happens if nothing in the tree has a layout?
105 Toolkit::Control control = Toolkit::Control::DownCast( root );
108 Internal::Control& controlImpl = GetImplementation( control );
109 Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl );
110 LayoutBasePtr layout = controlDataImpl.GetLayout();
114 layout->Measure( widthSpec, heightSpec );
119 // Depth first descent through actor children
120 for( unsigned int i = 0, count = root.GetChildCount(); i < count; ++i )
122 Actor child = root.GetChildAt( i );
123 MeasureHierarchy( child, widthSpec, heightSpec );
128 void LayoutController::PerformLayout( Actor root, int left, int top, int right, int bottom )
130 Toolkit::Control control = Toolkit::Control::DownCast( root );
133 Internal::Control& controlImpl = GetImplementation( control );
134 Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl );
135 LayoutBasePtr layout = controlDataImpl.GetLayout();
139 layout->Layout( left, top, right, bottom );
144 // Depth first descent through actor children
145 for( unsigned int i = 0, count = root.GetChildCount(); i < count; ++i )
147 Actor child = root.GetChildAt( i );
148 PerformLayout( child, left, top, right, bottom );
154 } // namespace Internal
155 } // namespace Toolkit