2 * Copyright(c) 2021 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.
17 using System.ComponentModel;
18 using Tizen.NUI.BaseComponents;
20 namespace Tizen.NUI.Components
23 /// The ContentPage class is a class which is a formatted full screen page.
24 /// ContentPage contains title app bar and content.
26 /// <since_tizen> 9 </since_tizen>
27 public partial class ContentPage : Page
29 private AppBar appBar = null;
30 private View content = null;
33 /// Creates a new instance of a ContentPage.
35 /// <since_tizen> 9 </since_tizen>
36 public ContentPage() : base()
38 Layout = new ContentPageLayout();
40 // ContentPage matches to parent by default.
41 WidthSpecification = LayoutParamPolicies.MatchParent;
42 HeightSpecification = LayoutParamPolicies.MatchParent;
46 /// Dispose ContentPage and all children on it.
48 /// <param name="type">Dispose type.</param>
49 [EditorBrowsable(EditorBrowsableState.Never)]
50 protected override void Dispose(DisposeTypes type)
57 if (type == DisposeTypes.Explicit)
61 Utility.Dispose(appBar);
66 Utility.Dispose(content);
74 [EditorBrowsable(EditorBrowsableState.Never)]
75 public override void OnInitialize()
79 AccessibilityRole = Role.PageTab;
83 /// AppBar of ContentPage.
84 /// AppBar is added as a child of ContentPage automatically.
85 /// AppBar is positioned at the top of the Page.
87 /// <since_tizen> 9 </since_tizen>
92 return GetValue(AppBarProperty) as AppBar;
96 SetValue(AppBarProperty, value);
97 NotifyPropertyChanged();
100 private AppBar InternalAppBar
129 /// Content of ContentPage.
130 /// Content is added as a child of ContentPage automatically.
131 /// Content is positioned below AppBar.
132 /// Content is resized to fill the full screen except AppBar.
134 /// <since_tizen> 9 </since_tizen>
139 return GetValue(ContentProperty) as View;
143 SetValue(ContentProperty, value);
144 NotifyPropertyChanged();
149 /// for the case of ContentPage, it sets key focus on AppBar's NavigationContent
151 protected internal override void RestoreKeyFocus()
153 if (FocusManager.Instance.IsDefaultAlgorithmEnabled())
157 FocusManager.Instance.SetCurrentFocusView(LastFocusedView);
163 FocusManager.Instance.SetCurrentFocusView(AppBar.PassFocusableViewInsideIfNeeded());
167 FocusManager.Instance.ClearFocus();
173 private View InternalContent
181 if (content == value)
201 private class ContentPageLayout : AbsoluteLayout
203 protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
205 float maxWidth = SuggestedMinimumWidth.AsDecimal();
206 float maxHeight = SuggestedMinimumHeight.AsDecimal();
208 MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK;
209 MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK;
211 var appBar = (Owner as ContentPage)?.AppBar;
212 var content = (Owner as ContentPage)?.Content;
214 bool measureAppBarLayout = false;
216 if ((appBar != null) && (appBar.Layout != null) && (LayoutChildren.Contains(appBar.Layout)) && appBar.Layout.SetPositionByLayout)
218 MeasureChildWithoutPadding(appBar.Layout, widthMeasureSpec, heightMeasureSpec);
219 measureAppBarLayout = true;
222 foreach (var childLayout in LayoutChildren)
224 if (!childLayout.SetPositionByLayout)
229 if ((content != null) && (content == childLayout.Owner) && (content.HeightSpecification == LayoutParamPolicies.MatchParent) && measureAppBarLayout)
231 var contentSizeH = heightMeasureSpec.Size.AsDecimal() - Padding.Top - Padding.Bottom - content.Margin.Top - content.Margin.Bottom - (appBar?.Layout.MeasuredHeight.Size.AsDecimal() ?? 0);
232 MeasureSpecification contentHeightSpec = new MeasureSpecification(new LayoutLength(contentSizeH), MeasureSpecification.ModeType.Exactly);
233 MeasureChildWithoutPadding(childLayout, widthMeasureSpec, contentHeightSpec);
235 else if (!measureAppBarLayout || (appBar != childLayout.Owner)) // if childLayout is not appBar.Layout
237 MeasureChildWithoutPadding(childLayout, widthMeasureSpec, heightMeasureSpec);
240 float childRight = childLayout.MeasuredWidth.Size.AsDecimal() + childLayout.Owner.PositionX;
241 float childBottom = childLayout.MeasuredHeight.Size.AsDecimal() + childLayout.Owner.PositionY;
243 if (maxWidth < childRight)
244 maxWidth = childRight;
246 if (maxHeight < childBottom)
247 maxHeight = childBottom;
249 if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
251 childWidthState = MeasuredSize.StateType.MeasuredSizeTooSmall;
253 if (childLayout.MeasuredHeight.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
255 childHeightState = MeasuredSize.StateType.MeasuredSizeTooSmall;
259 SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(maxWidth), widthMeasureSpec, childWidthState),
260 ResolveSizeAndState(new LayoutLength(maxHeight), heightMeasureSpec, childHeightState));
263 protected override void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
265 foreach (var childLayout in LayoutChildren)
267 if (!childLayout.SetPositionByLayout)
272 LayoutLength childWidth = childLayout.MeasuredWidth.Size;
273 LayoutLength childHeight = childLayout.MeasuredHeight.Size;
275 LayoutLength childLeft = new LayoutLength(childLayout.Owner.PositionX);
276 LayoutLength childTop = new LayoutLength(childLayout.Owner.PositionY);
278 var appBar = (Owner as ContentPage)?.AppBar;
279 var content = (Owner as ContentPage)?.Content;
281 if ((content != null) && (content == childLayout.Owner))
283 childTop = new LayoutLength(Padding.Top + content.Margin.Top + (appBar?.Layout.MeasuredHeight.Size.AsDecimal() ?? 0));
284 childLayout.Layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight, false);
288 childLayout.Layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight, true);