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>
31 #if defined(DEBUG_ENABLED)
32 static Debug::Filter* gLogFilter = Debug::Filter::New( Debug::Concise, false, "LOG_LAYOUT" );
44 LayoutController::LayoutController()
45 : mLayoutRequested(false)
49 LayoutController::~LayoutController()
53 void LayoutController::Initialize()
57 void LayoutController::RequestLayout( LayoutItem& LayoutItem )
59 DALI_LOG_INFO( gLogFilter, Debug::Concise, "LayoutController::RequestLayout\n" );
60 mLayoutRequested = true;
62 // Go up the tree and mark all parents to relayout
63 LayoutParent* layoutParent = LayoutItem.GetParent();
66 LayoutGroup& layoutGroup = static_cast< LayoutGroup& >( *layoutParent );
67 if( ! layoutGroup.IsLayoutRequested() )
69 layoutGroup.RequestLayout();
74 void LayoutController::Process()
76 // Perform the full process.
78 if( mLayoutRequested )
80 mLayoutRequested = false;
82 // If window size has changed, expect stage to have already been updated
83 Stage stage = Stage::GetCurrent();
84 auto stageWidth = stage.GetSize().width;
85 auto stageHeight = stage.GetSize().height;
87 auto widthSpec = MeasureSpec( stageWidth, MeasureSpec::Mode::EXACTLY );
88 auto heightSpec = MeasureSpec( stageHeight, MeasureSpec::Mode::EXACTLY );
90 // Test how to perform a measure on each control.
91 MeasureHierarchy( stage.GetRootLayer(), widthSpec, heightSpec );
93 LAYOUT_DEBUG_MEASURE_STATES( stage.GetRootLayer() );
94 PerformLayout( stage.GetRootLayer(), 0, 0, stageWidth, stageHeight );
96 LAYOUT_DEBUG_AFTER_LAYOUT( stage.GetRootLayer() );
100 void LayoutController::MeasureHierarchy( Actor root, MeasureSpec widthSpec, MeasureSpec heightSpec )
102 // Does this actor have a layout?
103 // Yes - measure the layout. It will call this method again for each of it's children.
104 // No - recurse through actor children.
106 // If in a leaf actor with no layout, it's natural size is bubbled back up.
108 // What happens if nothing in the tree has a layout?
110 Toolkit::Control control = Toolkit::Control::DownCast( root );
113 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::Measuring leaf\n" );
114 Internal::Control& controlImpl = GetImplementation( control );
116 Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl );
117 LayoutItemPtr layout = controlDataImpl.GetLayout();
121 layout->Measure( widthSpec, heightSpec );
126 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::Measuring (%u) children\n", root.GetChildCount() );
127 // Depth first descent through actor children
128 for( unsigned int i = 0, count = root.GetChildCount(); i < count; ++i )
130 Actor child = root.GetChildAt( i );
131 MeasureHierarchy( child, widthSpec, heightSpec );
136 void LayoutController::PerformLayout( Actor root, int left, int top, int right, int bottom )
138 Toolkit::Control control = Toolkit::Control::DownCast( root );
141 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::PerformLayout on leaf\n" );
142 Internal::Control& controlImpl = GetImplementation( control );
143 Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl );
144 LayoutItemPtr layout = controlDataImpl.GetLayout();
148 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::PerformLayout on layout\n" );
149 layout->Layout( left, top, right, bottom );
154 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::PerformLayout (%u) children\n", root.GetChildCount() );
155 // Depth first descent through actor children
156 for( unsigned int i = 0, count = root.GetChildCount(); i < count; ++i )
158 Actor child = root.GetChildAt( i );
159 PerformLayout( child, left, top, right, bottom );
165 } // namespace Internal
166 } // namespace Toolkit