1 /* Copyright (c) 2019 Samsung Electronics Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
17 using Tizen.NUI.BaseComponents;
22 /// [Draft] This class implements a absolute layout, allowing explicit positioning of children.
23 /// Positions are from the top left of the layout and can be set using the Actor::Property::POSITION and alike.
25 public class AbsoluteLayout : LayoutGroup
28 /// Struct to store Measured states of height and width.
30 private struct HeightAndWidthState
32 public MeasuredSize.StateType widthState;
33 public MeasuredSize.StateType heightState;
35 public HeightAndWidthState( MeasuredSize.StateType width, MeasuredSize.StateType height)
43 /// [Draft] Constructor
45 /// <since_tizen> 6 </since_tizen>
46 public AbsoluteLayout()
51 /// Measure the layout and its content to determine the measured width and the measured height.<br />
53 /// <param name="widthMeasureSpec">horizontal space requirements as imposed by the parent.</param>
54 /// <param name="heightMeasureSpec">vertical space requirements as imposed by the parent.</param>
55 /// <since_tizen> 6 </since_tizen>
56 protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
58 float totalHeight = 0.0f;
59 float totalWidth = 0.0f;
61 HeightAndWidthState childState = new HeightAndWidthState(MeasuredSize.StateType.MeasuredSizeOK,
62 MeasuredSize.StateType.MeasuredSizeOK);
64 float minPositionX = 0.0f;
65 float minPositionY = 0.0f;
66 float maxPositionX = 0.0f;
67 float maxPositionY = 0.0f;
70 foreach( LayoutItem childLayout in LayoutChildren )
72 if (childLayout != null)
75 MeasureChild( childLayout, widthMeasureSpec, heightMeasureSpec );
76 float childWidth = childLayout.MeasuredWidth.Size.AsDecimal();
77 float childHeight = childLayout.MeasuredHeight.Size.AsDecimal();
79 // Determine the width and height needed by the children using their given position and size.
80 // Children could overlap so find the left most and right most child.
81 Position2D childPosition = childLayout.Owner.Position2D;
82 float childLeft = childPosition.X;
83 float childTop = childPosition.Y;
85 minPositionX = Math.Min( minPositionX, childLeft );
86 maxPositionX = Math.Max( maxPositionX, childLeft + childWidth );
87 // Children could overlap so find the highest and lowest child.
88 minPositionY = Math.Min( minPositionY, childTop );
89 maxPositionY = Math.Max( maxPositionY, childTop + childHeight );
91 // Store current width and height needed to contain all children.
92 totalWidth = maxPositionX - minPositionX;
93 totalHeight = maxPositionY - minPositionY;
95 if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
97 childState.widthState = MeasuredSize.StateType.MeasuredSizeTooSmall;
99 if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
101 childState.heightState = MeasuredSize.StateType.MeasuredSizeTooSmall;
107 MeasuredSize widthSizeAndState = ResolveSizeAndState(new LayoutLength(totalWidth), widthMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);
108 MeasuredSize heightSizeAndState = ResolveSizeAndState(new LayoutLength(totalHeight), heightMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);
109 totalWidth = widthSizeAndState.Size.AsDecimal();
110 totalHeight = heightSizeAndState.Size.AsDecimal();
112 // Ensure layout respects it's given minimum size
113 totalWidth = Math.Max( totalWidth, SuggestedMinimumWidth.AsDecimal() );
114 totalHeight = Math.Max( totalHeight, SuggestedMinimumHeight.AsDecimal() );
116 widthSizeAndState.State = childState.widthState;
117 heightSizeAndState.State = childState.heightState;
119 SetMeasuredDimensions( ResolveSizeAndState( new LayoutLength(totalWidth), widthMeasureSpec, childState.widthState ),
120 ResolveSizeAndState( new LayoutLength(totalHeight), heightMeasureSpec, childState.heightState ) );
124 /// Assign a size and position to each of its children.<br />
126 /// <param name="changed">This is a new size or position for this layout.</param>
127 /// <param name="left">Left position, relative to parent.</param>
128 /// <param name="top"> Top position, relative to parent.</param>
129 /// <param name="right">Right position, relative to parent.</param>
130 /// <param name="bottom">Bottom position, relative to parent.</param>
131 /// <since_tizen> 6 </since_tizen>
132 protected override void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
134 // Absolute layout positions it's children at their Actor positions.
135 // Children could overlap or spill outside the parent, as is the nature of absolute positions.
136 foreach( LayoutItem childLayout in LayoutChildren )
138 if( childLayout != null )
140 LayoutLength childWidth = childLayout.MeasuredWidth.Size;
141 LayoutLength childHeight = childLayout.MeasuredHeight.Size;
143 Position2D childPosition = childLayout.Owner.Position2D;
145 LayoutLength childLeft = new LayoutLength(childPosition.X);
146 LayoutLength childTop = new LayoutLength(childPosition.Y);
148 childLayout.Layout( childLeft, childTop, childLeft + childWidth, childTop + childHeight );