[NUI] remove margin, padding calculation for AbsoluteLayout child size (#1668)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Layouting / AbsoluteLayout.cs
1 /* Copyright (c) 2019 Samsung Electronics Co., Ltd.
2  *
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
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
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.
14  *
15  */
16 using Tizen.NUI.BaseComponents;
17
18 namespace Tizen.NUI
19 {
20     /// <summary>
21     /// [Draft] This class implements a absolute layout, allowing explicit positioning of children.
22     ///  Positions are from the top left of the layout and can be set using the View.Position and alike.
23     /// </summary>
24     public class AbsoluteLayout : LayoutGroup
25     {
26         /// <summary>
27         /// [Draft] Constructor
28         /// </summary>
29         /// <since_tizen> 6 </since_tizen>
30         public AbsoluteLayout()
31         {
32         }
33
34         /// <summary>
35         /// Measure the layout and its content to determine the measured width and the measured height.<br />
36         /// </summary>
37         /// <param name="widthMeasureSpec">horizontal space requirements as imposed by the parent.</param>
38         /// <param name="heightMeasureSpec">vertical space requirements as imposed by the parent.</param>
39         /// <since_tizen> 6 </since_tizen>
40         protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
41         {
42             // Ensure layout respects it's given minimum size
43             float maxWidth = SuggestedMinimumWidth.AsDecimal();
44             float maxHeight = SuggestedMinimumHeight.AsDecimal();
45
46             MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK;
47             MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK;
48
49             for (int i = 0; i < LayoutChildren.Count; i++)
50             {
51                 LayoutItem childLayout = LayoutChildren[i];
52                 if (childLayout != null)
53                 {
54                     // Get size of child with no padding, no margin. we won't support margin, padding for AbsolutLayout.
55                     MeasureChildWithoutPadding(childLayout, widthMeasureSpec, heightMeasureSpec);
56
57                     // Determine the width and height needed by the children using their given position and size.
58                     // Children could overlap so find the right most child.
59                     Position2D childPosition = childLayout.Owner.Position2D;
60                     float childRight = childLayout.MeasuredWidth.Size.AsDecimal() + childPosition.X;
61                     float childBottom = childLayout.MeasuredHeight.Size.AsDecimal() + childPosition.Y;
62
63                     if (maxWidth < childRight)
64                         maxWidth = childRight;
65
66                     if (maxHeight < childBottom)
67                         maxHeight = childBottom;
68
69                     if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
70                     {
71                         childWidthState = MeasuredSize.StateType.MeasuredSizeTooSmall;
72                     }
73                     if (childLayout.MeasuredHeight.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
74                     {
75                         childHeightState = MeasuredSize.StateType.MeasuredSizeTooSmall;
76                     }
77                 }
78             }
79
80             SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(maxWidth), widthMeasureSpec, childWidthState),
81                                   ResolveSizeAndState(new LayoutLength(maxHeight), heightMeasureSpec, childHeightState));
82         }
83
84         /// <summary>
85         /// Assign a size and position to each of its children.<br />
86         /// </summary>
87         /// <param name="changed">This is a new size or position for this layout.</param>
88         /// <param name="left">Left position, relative to parent.</param>
89         /// <param name="top"> Top position, relative to parent.</param>
90         /// <param name="right">Right position, relative to parent.</param>
91         /// <param name="bottom">Bottom position, relative to parent.</param>
92         /// <since_tizen> 6 </since_tizen>
93         protected override void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
94         {
95             // Absolute layout positions it's children at their Actor positions.
96             // Children could overlap or spill outside the parent, as is the nature of absolute positions.
97             for (int i = 0; i < LayoutChildren.Count; i++)
98             {
99                 LayoutItem childLayout = LayoutChildren[i];
100                 if ( childLayout != null )
101                 {
102                     LayoutLength childWidth = childLayout.MeasuredWidth.Size;
103                     LayoutLength childHeight = childLayout.MeasuredHeight.Size;
104
105                     Position2D childPosition = childLayout.Owner.Position2D;
106
107                     LayoutLength childLeft = new LayoutLength(childPosition.X);
108                     LayoutLength childTop = new LayoutLength(childPosition.Y);
109
110                     childLayout.Layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
111                 }
112             }
113         }
114
115         private void MeasureChildWithoutPadding(LayoutItem child, MeasureSpecification parentWidthMeasureSpec, MeasureSpecification parentHeightMeasureSpec)
116         {
117             View childOwner = child.Owner;
118
119             MeasureSpecification childWidthMeasureSpec = GetChildMeasureSpecification(
120                         new MeasureSpecification(new LayoutLength(parentWidthMeasureSpec.Size), parentWidthMeasureSpec.Mode),
121                         new LayoutLength(0),
122                         new LayoutLength(childOwner.WidthSpecification));
123
124             MeasureSpecification childHeightMeasureSpec = GetChildMeasureSpecification(
125                         new MeasureSpecification(new LayoutLength(parentHeightMeasureSpec.Size), parentHeightMeasureSpec.Mode),
126                         new LayoutLength(0),
127                         new LayoutLength(childOwner.HeightSpecification));
128
129             child.Measure(childWidthMeasureSpec, childHeightMeasureSpec);
130         }
131     }
132
133 } // namespace