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 using System.ComponentModel;
19 using Tizen.NUI.BaseComponents;
24 /// [Draft] LayoutGroup class providing container functionality.
26 internal class LayoutGroup : LayoutGroupWrapper
28 public LayoutGroup() : base(new LayoutGroupWrapperImpl())
30 // Initialize delegates of LayoutItem
31 LayoutItemInitialize(layoutGroupWrapperImpl);
33 layoutGroupWrapperImpl.OnMeasure = new LayoutGroupWrapperImpl.OnMeasureDelegate(OnMeasure);
34 layoutGroupWrapperImpl.OnLayout = new LayoutGroupWrapperImpl.OnLayoutDelegate(OnLayout);
35 layoutGroupWrapperImpl.OnSizeChanged = new LayoutGroupWrapperImpl.OnSizeChangedDelegate(OnSizeChanged);
36 layoutGroupWrapperImpl.OnChildAdd = new LayoutGroupWrapperImpl.OnChildAddDelegate(OnChildAdd);
37 layoutGroupWrapperImpl.OnChildRemove = new LayoutGroupWrapperImpl.OnChildRemoveDelegate(OnChildRemove);
38 layoutGroupWrapperImpl.DoInitialize = new LayoutGroupWrapperImpl.DoInitializeDelegate(DoInitialize);
39 layoutGroupWrapperImpl.DoRegisterChildProperties = new LayoutGroupWrapperImpl.DoRegisterChildPropertiesDelegate(DoRegisterChildProperties);
40 layoutGroupWrapperImpl.MeasureChildren = new LayoutGroupWrapperImpl.MeasureChildrenDelegate(MeasureChildren);
41 layoutGroupWrapperImpl.MeasureChild = new LayoutGroupWrapperImpl.MeasureChildDelegate(MeasureChild);
42 layoutGroupWrapperImpl.MeasureChildWithMargins = new LayoutGroupWrapperImpl.MeasureChildWithMarginsDelegate(MeasureChildWithMargins);
46 /// Remove all layout children.<br />
48 public void RemoveAll()
50 layoutGroupWrapperImpl.RemoveAll();
54 /// Get the child layout id of the given child.<br />
56 /// <param name="child">The given Layout child.</param>
57 internal uint GetChildId(LayoutItemWrapperImpl child)
59 return layoutGroupWrapperImpl.GetChildId(child);
63 /// Calculate the right measure spec for this child.
64 /// Does the hard part of MeasureChildren: figuring out the MeasureSpec to
65 /// pass to a particular child. This method figures out the right MeasureSpec
66 /// for one dimension (height or width) of one child view.<br />
68 /// <param name="measureSpec">The requirements for this view.</param>
69 /// <param name="padding">The padding of this view for the current dimension and margins, if applicable.</param>
70 /// <param name="childDimension"> How big the child wants to be in the current dimension.</param>
71 /// <returns>a MeasureSpec for the child.</returns>
72 public static LayoutMeasureSpec GetChildMeasureSpec(LayoutMeasureSpec measureSpec, LayoutLength padding, LayoutLength childDimension)
74 return LayoutGroupWrapperImpl.GetChildMeasureSpec(measureSpec, padding, childDimension);
78 /// Measure the layout and its content to determine the measured width and the measured height.<br />
79 /// If this method is overridden, it is the subclass's responsibility to make
80 /// sure the measured height and width are at least the layout's minimum height
83 /// <param name="widthMeasureSpec">horizontal space requirements as imposed by the parent.</param>
84 /// <param name="heightMeasureSpec">vertical space requirements as imposed by the parent.</param>
85 protected override void OnMeasure(LayoutMeasureSpec widthMeasureSpec, LayoutMeasureSpec heightMeasureSpec)
87 Log.Info("NUI", "OnMeasure\n");
88 LayoutLength childWidth = new LayoutLength( 0 );
89 LayoutLength childHeight = new LayoutLength( 0 );
91 LayoutLength measuredWidth = childWidth;
92 LayoutLength measuredHeight = childHeight;
94 for( uint i = 0; i < ChildCount; ++i )
96 var childLayout = GetChildAt( i );
100 MeasureChild( childLayout, widthMeasureSpec, heightMeasureSpec );
101 childWidth = childLayout.MeasuredWidth;
102 childHeight = childLayout.MeasuredHeight;
103 // Layout takes size of largest width and height dimension of children
104 measuredWidth.Value = System.Math.Max( measuredWidth.Value, childWidth.Value );
105 measuredHeight.Value = System.Math.Max( measuredHeight.Value, childHeight.Value );
109 if( 0 == ChildCount )
111 // Must be a leaf as has no children
112 measuredWidth = GetDefaultSize( SuggestedMinimumWidth, widthMeasureSpec );
113 measuredHeight = GetDefaultSize( SuggestedMinimumHeight, heightMeasureSpec );
116 SetMeasuredDimensions( new MeasuredSize( measuredWidth ),
117 new MeasuredSize( measuredHeight ) );
121 /// Called from Layout() when this layout should assign a size and position to each of its children.<br />
122 /// Derived classes with children should override this method and call Layout() on each of their children.<br />
124 /// <param name="changed">This is a new size or position for this layout.</param>
125 /// <param name="left">Left position, relative to parent.</param>
126 /// <param name="top"> Top position, relative to parent.</param>
127 /// <param name="right">Right position, relative to parent.</param>
128 /// <param name="bottom">Bottom position, relative to parent.</param>
129 protected override void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
131 Log.Info("NUI", "OnLayout\n");
132 for( uint i = 0; i < ChildCount; ++i )
134 var childLayout = GetChildAt( i );
137 View childOwner = childLayout.GetOwner();
139 // Use position if explicitly set to child otherwise will be top left.
140 var childLeft = new LayoutLength( childOwner.Position2D.X );
141 var childTop = new LayoutLength( childOwner.Position2D.Y );
143 View owner = GetOwner();
147 // Margin and Padding only supported when child anchor point is TOP_LEFT.
148 if ( owner.PivotPoint == PivotPoint.TopLeft || ( owner.PositionUsesPivotPoint == false ) )
150 childLeft = childLeft + owner.Padding.Start + childOwner.Margin.Start;
151 childTop = childTop + owner.Padding.Top + childOwner.Margin.Top;
154 childLayout.Layout( childLeft, childTop, childLeft + childLayout.MeasuredWidth, childTop + childLayout.MeasuredHeight );
160 /// Virtual method to inform derived classes when the layout size changed.<br />
162 /// <param name="newSize">The new size of the layout.</param>
163 /// <param name="oldSize">The old size of the layout.</param>
164 protected override void OnSizeChanged(LayoutSize newSize, LayoutSize oldSize)
170 /// Callback when child is added to container.<br />
171 /// Derived classes can use this to set their own child properties on the child layout's owner.<br />
173 /// <param name="child">The Layout child.</param>
174 internal virtual void OnChildAdd(LayoutItemWrapperImpl child)
179 /// Callback when child is removed from container.<br />
181 /// <param name="child">The Layout child.</param>
182 internal virtual void OnChildRemove(LayoutItemWrapperImpl child)
187 /// Second stage initialization method for deriving classes to override.<br />
189 protected virtual void DoInitialize()
194 /// Method for derived classes to implement in order to register child property types with the container.<br />
196 /// <param name="containerType">The fully qualified typename of the container.</param>
197 protected virtual void DoRegisterChildProperties(string containerType)
202 /// Ask all of the children of this view to measure themselves, taking into
203 /// account both the MeasureSpec requirements for this view and its padding.<br />
204 /// The heavy lifting is done in GetChildMeasureSpec.<br />
206 /// <param name="widthMeasureSpec">The width requirements for this view.</param>
207 /// <param name="heightMeasureSpec">The height requirements for this view.</param>
208 protected virtual void MeasureChildren(LayoutMeasureSpec widthMeasureSpec, LayoutMeasureSpec heightMeasureSpec)
210 layoutGroupWrapperImpl.MeasureChildrenNative(widthMeasureSpec, heightMeasureSpec);
214 /// Ask one of the children of this view to measure itself, taking into
215 /// account both the MeasureSpec requirements for this view and its padding.<br />
216 /// The heavy lifting is done in GetChildMeasureSpec.<br />
218 /// <param name="child">The child to measure.</param>
219 /// <param name="parentWidthMeasureSpec">The width requirements for this view.</param>
220 /// <param name="parentHeightMeasureSpec">The height requirements for this view.</param>
221 protected virtual void MeasureChild(LayoutItem child, LayoutMeasureSpec parentWidthMeasureSpec, LayoutMeasureSpec parentHeightMeasureSpec)
223 layoutGroupWrapperImpl.MeasureChildNative(child, parentWidthMeasureSpec, parentHeightMeasureSpec);
227 /// Ask one of the children of this view to measure itself, taking into
228 /// account both the MeasureSpec requirements for this view and its padding.<br />
229 /// and margins. The child must have MarginLayoutParams The heavy lifting is
230 /// done in GetChildMeasureSpec.<br />
232 /// <param name="child">The child to measure.</param>
233 /// <param name="parentWidthMeasureSpec">The width requirements for this view.</param>
234 /// <param name="widthUsed">Extra space that has been used up by the parent horizontally (possibly by other children of the parent).</param>
235 /// <param name="parentHeightMeasureSpec">The height requirements for this view.</param>
236 /// <param name="heightUsed">Extra space that has been used up by the parent vertically (possibly by other children of the parent).</param>
237 protected virtual void MeasureChildWithMargins(LayoutItem child, LayoutMeasureSpec parentWidthMeasureSpec, LayoutLength widthUsed, LayoutMeasureSpec parentHeightMeasureSpec, LayoutLength heightUsed)
239 layoutGroupWrapperImpl.MeasureChildWithMarginsNative(child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed);