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.
18 using System.ComponentModel;
19 using Tizen.NUI.BaseComponents;
20 using Tizen.NUI.Binding;
25 /// [Draft] This class implements a grid layout
27 public partial class GridLayout : LayoutGroup
32 [EditorBrowsable(EditorBrowsableState.Never)]
33 public static readonly BindableProperty ColumnProperty = BindableProperty.CreateAttached("Column", typeof(int), typeof(GridLayout), CellUndefined, validateValue: (bindable, value) => (int)value >= 0, propertyChanged: OnChildPropertyChanged);
36 /// ColumnSpanProperty
38 [EditorBrowsable(EditorBrowsableState.Never)]
39 public static readonly BindableProperty ColumnSpanProperty = BindableProperty.CreateAttached("ColumnSpan", typeof(int), typeof(GridLayout), 1, validateValue: (bindable, value) => (int)value >= 1, propertyChanged: OnChildPropertyChanged);
44 [EditorBrowsable(EditorBrowsableState.Never)]
45 public static readonly BindableProperty RowProperty = BindableProperty.CreateAttached("Row", typeof(int), typeof(GridLayout), CellUndefined, validateValue: (bindable, value) => (int)value >= 0, propertyChanged: OnChildPropertyChanged);
50 [EditorBrowsable(EditorBrowsableState.Never)]
51 public static readonly BindableProperty RowSpanProperty = BindableProperty.CreateAttached("RowSpan", typeof(int), typeof(GridLayout), 1, validateValue: (bindable, value) => (int)value >= 1, propertyChanged: OnChildPropertyChanged);
54 /// HorizontalStretchProperty
56 [EditorBrowsable(EditorBrowsableState.Never)]
57 public static readonly BindableProperty HorizontalStretchProperty = BindableProperty.CreateAttached("HorizontalStretch", typeof(StretchFlags), typeof(GridLayout), StretchFlags.Fill, propertyChanged: OnChildPropertyChanged);
60 /// VerticalStretchProperty
62 [EditorBrowsable(EditorBrowsableState.Never)]
63 public static readonly BindableProperty VerticalStretchProperty = BindableProperty.CreateAttached("VerticalStretch", typeof(StretchFlags), typeof(GridLayout), StretchFlags.Fill, propertyChanged: OnChildPropertyChanged);
66 /// HorizontalAlignmentProperty
68 [EditorBrowsable(EditorBrowsableState.Never)]
69 public static readonly BindableProperty HorizontalAlignmentProperty = BindableProperty.CreateAttached("HorizontalAlignment", typeof(Alignment), typeof(GridLayout), Alignment.Start, propertyChanged: OnChildPropertyChanged);
72 /// VerticalAlignmentProperty
74 [EditorBrowsable(EditorBrowsableState.Never)]
75 public static readonly BindableProperty VerticalAlignmentProperty = BindableProperty.CreateAttached("VerticalAlignment", typeof(Alignment), typeof(GridLayout), Alignment.Start, propertyChanged: OnChildPropertyChanged);
77 private const int CellUndefined = int.MinValue;
78 private Orientation gridOrientation = Orientation.Vertical;
79 private int columns = 1;
81 private float columnSpacing = 0;
82 private float rowSpacing = 0;
85 /// [Draft] Enumeration for the direction in which the content is laid out
87 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
88 [EditorBrowsable(EditorBrowsableState.Never)]
89 public enum Orientation
102 /// Get the column index.
104 [EditorBrowsable(EditorBrowsableState.Never)]
105 public static int GetColumn(View view)
107 return (int)view.GetValue(ColumnProperty);
111 /// Get the column span.
113 [EditorBrowsable(EditorBrowsableState.Never)]
114 public static int GetColumnSpan(View view)
116 return (int)view.GetValue(ColumnSpanProperty);
120 /// Get the row index.
122 [EditorBrowsable(EditorBrowsableState.Never)]
123 public static int GetRow(View view)
125 return (int)view.GetValue(RowProperty);
129 /// Get the row span.
131 [EditorBrowsable(EditorBrowsableState.Never)]
132 public static int GetRowSpan(View view)
134 return (int)view.GetValue(RowSpanProperty);
138 /// Get the value how child is resized within its horizontal space. <see cref="StretchFlags.Fill"/> by default.
140 [EditorBrowsable(EditorBrowsableState.Never)]
141 public static StretchFlags GetHorizontalStretch(View view)
143 return (StretchFlags)view.GetValue(HorizontalStretchProperty);
147 /// Get the value how child is resized within its vertical space. <see cref="StretchFlags.Fill"/> by default.
149 [EditorBrowsable(EditorBrowsableState.Never)]
150 public static StretchFlags GetVerticalStretch(View view)
152 return (StretchFlags)view.GetValue(VerticalStretchProperty);
156 /// Get the horizontal alignment of this child.
158 [EditorBrowsable(EditorBrowsableState.Never)]
159 public static Alignment GetHorizontalAlignment(View view)
161 return (Alignment)view.GetValue(HorizontalAlignmentProperty);
165 /// Get the vertical alignment of this child.
167 [EditorBrowsable(EditorBrowsableState.Never)]
168 public static Alignment GetVerticalAlignment(View view)
170 return (Alignment)view.GetValue(VerticalAlignmentProperty);
174 /// Set the column index.
176 [EditorBrowsable(EditorBrowsableState.Never)]
177 public static void SetColumn(View view, int value)
179 SetChildValue(view, ColumnProperty, value);
183 /// Set the column span.
185 [EditorBrowsable(EditorBrowsableState.Never)]
186 public static void SetColumnSpan(View view, int value)
188 SetChildValue(view, ColumnSpanProperty, value);
192 /// Set the row index.
194 [EditorBrowsable(EditorBrowsableState.Never)]
195 public static void SetRow(View view, int value)
197 SetChildValue(view, RowProperty, value);
201 /// Set the row span.
203 [EditorBrowsable(EditorBrowsableState.Never)]
204 public static void SetRowSpan(View view, int value)
206 SetChildValue(view, RowSpanProperty, value);
210 /// Set the value how child is resized within its horizontal space. <see cref="StretchFlags.Fill"/> by default.
212 [EditorBrowsable(EditorBrowsableState.Never)]
213 public static void SetHorizontalStretch(View view, StretchFlags value)
215 SetChildValue(view, HorizontalStretchProperty, value);
219 /// Set the value how child is resized within its vertical space. <see cref="StretchFlags.Fill"/> by default.
221 [EditorBrowsable(EditorBrowsableState.Never)]
222 public static void SetVerticalStretch(View view, StretchFlags value)
224 SetChildValue(view, VerticalStretchProperty, value);
228 /// Set the horizontal alignment of this child inside the cells.
230 [EditorBrowsable(EditorBrowsableState.Never)]
231 public static void SetHorizontalAlignment(View view, Alignment value)
233 SetChildValue(view, HorizontalAlignmentProperty, value);
237 /// Set the vertical alignment of this child inside the cells.
239 [EditorBrowsable(EditorBrowsableState.Never)]
240 public static void SetVerticalAlignment(View view, Alignment value)
242 SetChildValue(view, VerticalAlignmentProperty, value);
246 /// [Draft] The Distance between Column
248 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
249 [EditorBrowsable(EditorBrowsableState.Never)]
250 public float ColumnSpacing
252 get => columnSpacing;
255 if (columnSpacing == value) return;
256 if (columnSpacing < 0) columnSpacing = 0;
257 columnSpacing = value;
264 /// [Draft] The Distance between Rows
266 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
267 [EditorBrowsable(EditorBrowsableState.Never)]
268 public float RowSpacing
273 if (rowSpacing == value) return;
274 if (rowSpacing < 0) rowSpacing = 0;
282 /// [Draft] Get/Set the orientation in the layout
284 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
285 [EditorBrowsable(EditorBrowsableState.Never)]
286 public Orientation GridOrientation
288 get => gridOrientation;
291 if (gridOrientation == value) return;
292 gridOrientation = value;
298 /// [draft] GridLayout Constructor/>
300 /// <returns> New Grid object.</returns>
301 /// <since_tizen> 6 </since_tizen>
307 /// [Draft] Get/Set the number of columns in the GridLayout should have.
309 /// <since_tizen> 6 </since_tizen>
315 if (value == columns) return;
317 if (value < 1) value = 1;
324 /// [draft ]Get/Set the number of rows in the grid
326 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
327 [EditorBrowsable(EditorBrowsableState.Never)]
333 if (value == rows) return;
335 if (value < 1) value = 1;
342 /// Measure the layout and its content to determine the measured width and the measured height.<br />
344 /// <param name="widthMeasureSpec">horizontal space requirements as imposed by the parent.</param>
345 /// <param name="heightMeasureSpec">vertical space requirements as imposed by the parent.</param>
346 /// <since_tizen> 6 </since_tizen>
347 protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
351 var widthMode = widthMeasureSpec.Mode;
352 var heightMode = heightMeasureSpec.Mode;
354 InitChildren(widthMeasureSpec, heightMeasureSpec);
356 if (widthMode == MeasureSpecification.ModeType.Exactly)
357 widthSize = (int)widthMeasureSpec.Size.AsRoundedValue();
359 widthSize = (int)(hLocations[maxColumnConut] - hLocations[0] - columnSpacing);
361 if (heightMode == MeasureSpecification.ModeType.Exactly)
362 heightSize = (int)heightMeasureSpec.Size.AsRoundedValue();
364 heightSize = (int)(vLocations[maxRowCount] - vLocations[0] - rowSpacing);
366 LayoutLength widthLength = new LayoutLength(widthSize + Padding.Start + Padding.End);
367 LayoutLength heightLenght = new LayoutLength(heightSize + Padding.Top + Padding.Bottom);
369 MeasuredSize widthMeasuredSize = ResolveSizeAndState(widthLength, widthMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);
370 MeasuredSize heightMeasuredSize = ResolveSizeAndState(heightLenght, heightMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);
372 SetMeasuredDimensions(widthMeasuredSize, heightMeasuredSize);
376 /// Assign a size and position to each of its children.<br />
378 /// <param name="changed">This is a new size or position for this layout.</param>
379 /// <param name="left">Left position, relative to parent.</param>
380 /// <param name="top"> Top position, relative to parent.</param>
381 /// <param name="right">Right position, relative to parent.</param>
382 /// <param name="bottom">Bottom position, relative to parent.</param>
383 /// <since_tizen> 6 </since_tizen>
384 protected override void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
386 InitChildrenWithExpand(MeasuredWidth.Size - Padding.Start - Padding.End, MeasuredHeight.Size - Padding.Top - Padding.Bottom);
388 for (int i = 0; i < gridChildren.Length; i++)
390 GridChild child = gridChildren[i];
391 View view = child.LayoutItem?.Owner;
393 if (view == null) continue;
395 Alignment halign = GetHorizontalAlignment(view);
396 Alignment valign = GetVerticalAlignment(view);
398 int column = child.Column.Start;
399 int row = child.Row.Start;
400 int columnEnd = child.Column.End;
401 int rowEnd = child.Row.End;
402 float l = hLocations[column] + Padding.Start;
403 float t = vLocations[row] + Padding.Top;
404 float width = hLocations[columnEnd] - hLocations[column] - ColumnSpacing;
405 float height = vLocations[rowEnd] - vLocations[row] - RowSpacing;
407 if (!child.Column.Stretch.HasFlag(StretchFlags.Fill))
409 l += (width - child.LayoutItem.MeasuredWidth.Size.AsDecimal()) * halign.ToFloat();
410 width = child.LayoutItem.MeasuredWidth.Size.AsDecimal();
413 if (!child.Row.Stretch.HasFlag(StretchFlags.Fill))
415 t += (height - child.LayoutItem.MeasuredHeight.Size.AsDecimal()) * valign.ToFloat();
416 height = child.LayoutItem.MeasuredHeight.Size.AsDecimal();
419 child.LayoutItem.Layout(new LayoutLength(l), new LayoutLength(t), new LayoutLength(l + width), new LayoutLength(t + height));
424 /// The value how child is resized within its space.
426 [EditorBrowsable(EditorBrowsableState.Never)]
428 public enum StretchFlags
431 /// Respect mesured size of the child.
433 [EditorBrowsable(EditorBrowsableState.Never)]
436 /// Resize to completely fill the space.
438 [EditorBrowsable(EditorBrowsableState.Never)]
441 /// Expand to share available space in GridLayout.
443 [EditorBrowsable(EditorBrowsableState.Never)]
446 /// Expand to share available space in GridLayout and fill the space.
448 [EditorBrowsable(EditorBrowsableState.Never)]
449 ExpandAndFill = Fill + Expand,
453 /// The alignment of the grid layout child.
455 [EditorBrowsable(EditorBrowsableState.Never)]
456 public enum Alignment
459 /// At the start of the container.
461 [EditorBrowsable(EditorBrowsableState.Never)]
464 /// At the center of the container
466 [EditorBrowsable(EditorBrowsableState.Never)]
469 /// At the end of the container.
471 [EditorBrowsable(EditorBrowsableState.Never)]
476 // Extension Method of GridLayout.Alignment.
477 internal static class AlignmentExtension
479 public static float ToFloat(this GridLayout.Alignment align)
481 return 0.5f * (float)align;