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 internal 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 public AbsoluteLayout()
49 protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
51 float totalHeight = 0.0f;
52 float totalWidth = 0.0f;
54 HeightAndWidthState childState = new HeightAndWidthState(MeasuredSize.StateType.MeasuredSizeOK,
55 MeasuredSize.StateType.MeasuredSizeOK);
57 float minPositionX = 0.0f;
58 float minPositionY = 0.0f;
59 float maxPositionX = 0.0f;
60 float maxPositionY = 0.0f;
63 foreach( LayoutItem childLayout in _children )
65 if (childLayout != null)
68 MeasureChild( childLayout, widthMeasureSpec, heightMeasureSpec );
69 float childWidth = childLayout.MeasuredWidth.Size.AsDecimal();
70 float childHeight = childLayout.MeasuredHeight.Size.AsDecimal();
72 // Determine the width and height needed by the children using their given position and size.
73 // Children could overlap so find the left most and right most child.
74 Position2D childPosition = childLayout.Owner.Position2D;
75 float childLeft = childPosition.X;
76 float childTop = childPosition.Y;
78 minPositionX = Math.Min( minPositionX, childLeft );
79 maxPositionX = Math.Max( maxPositionX, childLeft + childWidth );
80 // Children could overlap so find the highest and lowest child.
81 minPositionY = Math.Min( minPositionY, childTop );
82 maxPositionY = Math.Max( maxPositionY, childTop + childHeight );
84 // Store current width and height needed to contain all children.
85 totalWidth = maxPositionX - minPositionX;
86 totalHeight = maxPositionY - minPositionY;
88 if (childLayout.MeasuredWidthAndState.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
90 childState.widthState = MeasuredSize.StateType.MeasuredSizeTooSmall;
92 if (childLayout.MeasuredWidthAndState.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
94 childState.heightState = MeasuredSize.StateType.MeasuredSizeTooSmall;
100 MeasuredSize widthSizeAndState = ResolveSizeAndState(new LayoutLength(totalWidth), widthMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);
101 MeasuredSize heightSizeAndState = ResolveSizeAndState(new LayoutLength(totalHeight), heightMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);
102 totalWidth = widthSizeAndState.Size.AsDecimal();
103 totalHeight = heightSizeAndState.Size.AsDecimal();
105 // Ensure layout respects it's given minimum size
106 totalWidth = Math.Max( totalWidth, SuggestedMinimumWidth.AsDecimal() );
107 totalHeight = Math.Max( totalHeight, SuggestedMinimumHeight.AsDecimal() );
109 widthSizeAndState.State = childState.widthState;
110 heightSizeAndState.State = childState.heightState;
112 SetMeasuredDimensions( ResolveSizeAndState( new LayoutLength(totalWidth), widthMeasureSpec, childState.widthState ),
113 ResolveSizeAndState( new LayoutLength(totalHeight), heightMeasureSpec, childState.heightState ) );
116 protected override void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
118 // Absolute layout positions it's children at their Actor positions.
119 // Children could overlap or spill outside the parent, as is the nature of absolute positions.
120 foreach( LayoutItem childLayout in _children )
122 if( childLayout != null )
124 LayoutLength childWidth = childLayout.MeasuredWidth.Size;
125 LayoutLength childHeight = childLayout.MeasuredHeight.Size;
127 Position2D childPosition = childLayout.Owner.Position2D;
129 LayoutLength childLeft = new LayoutLength(childPosition.X);
130 LayoutLength childTop = new LayoutLength(childPosition.Y);
132 childLayout.Layout( childLeft, childTop, childLeft + childWidth, childTop + childHeight );