/* * Copyright(c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ using System.ComponentModel; using Tizen.NUI.BaseComponents; namespace Tizen.NUI.Components { /// /// The ContentPage class is a class which is a formatted full screen page. /// ContentPage contains title app bar and content. /// /// 9 public partial class ContentPage : Page { private AppBar appBar = null; private View content = null; private void Initialize() { Layout = new ContentPageLayout(); // ContentPage matches to parent by default. WidthSpecification = LayoutParamPolicies.MatchParent; HeightSpecification = LayoutParamPolicies.MatchParent; } /// /// Creates a new instance of a ContentPage. /// /// 9 public ContentPage() : base() { Initialize(); } /// /// Creates a new instance of a ContentPage with style. /// /// A style applied to the newly created ContentPage. [EditorBrowsable(EditorBrowsableState.Never)] public ContentPage(ControlStyle style) : base(style) { Initialize(); } /// /// Dispose ContentPage and all children on it. /// /// Dispose type. [EditorBrowsable(EditorBrowsableState.Never)] protected override void Dispose(DisposeTypes type) { if (disposed) { return; } if (type == DisposeTypes.Explicit) { if (appBar != null) { Utility.Dispose(appBar); } if (content != null) { Utility.Dispose(content); } } base.Dispose(type); } /// [EditorBrowsable(EditorBrowsableState.Never)] public override void OnInitialize() { base.OnInitialize(); AccessibilityRole = Role.PageTab; } /// /// AppBar of ContentPage. /// AppBar is added as a child of ContentPage automatically. /// AppBar is positioned at the top of the Page. /// /// 9 public AppBar AppBar { get { return GetValue(AppBarProperty) as AppBar; } set { SetValue(AppBarProperty, value); NotifyPropertyChanged(); } } private AppBar InternalAppBar { get { return appBar; } set { if (appBar == value) { return; } if (appBar != null) { Remove(appBar); } appBar = value; if (appBar == null) { return; } Add(appBar); } } /// /// Content of ContentPage. /// Content is added as a child of ContentPage automatically. /// Content is positioned below AppBar. /// Content is resized to fill the full screen except AppBar. /// /// 9 public View Content { get { return GetValue(ContentProperty) as View; } set { SetValue(ContentProperty, value); NotifyPropertyChanged(); } } /// /// for the case of ContentPage, it sets key focus on AppBar's NavigationContent /// protected internal override void RestoreKeyFocus() { if (FocusManager.Instance.IsDefaultAlgorithmEnabled()) { if (LastFocusedView) { FocusManager.Instance.SetCurrentFocusView(LastFocusedView); } else { if (AppBar != null) { FocusManager.Instance.SetCurrentFocusView(AppBar.PassFocusableViewInsideIfNeeded()); } else { FocusManager.Instance.ClearFocus(); } } } } private View InternalContent { get { return content; } set { if (content == value) { return; } if (content != null) { Remove(content); } content = value; if (content == null) { return; } Add(content); } } private class ContentPageLayout : AbsoluteLayout { protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec) { float maxWidth = SuggestedMinimumWidth.AsDecimal(); float maxHeight = SuggestedMinimumHeight.AsDecimal(); MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK; MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK; var appBar = (Owner as ContentPage)?.AppBar; var content = (Owner as ContentPage)?.Content; bool measureAppBarLayout = false; if ((appBar != null) && (appBar.Layout != null) && (LayoutChildren.Contains(appBar.Layout)) && appBar.Layout.SetPositionByLayout) { MeasureChildWithoutPadding(appBar.Layout, widthMeasureSpec, heightMeasureSpec); measureAppBarLayout = true; } foreach (var childLayout in LayoutChildren) { if (!childLayout.SetPositionByLayout) { continue; } if ((content != null) && (content == childLayout.Owner) && (content.HeightSpecification == LayoutParamPolicies.MatchParent) && measureAppBarLayout) { var contentSizeH = heightMeasureSpec.Size.AsDecimal() - Padding.Top - Padding.Bottom - content.Margin.Top - content.Margin.Bottom - (appBar?.Layout.MeasuredHeight.Size.AsDecimal() ?? 0); MeasureSpecification contentHeightSpec = new MeasureSpecification(new LayoutLength(contentSizeH), MeasureSpecification.ModeType.Exactly); MeasureChildWithoutPadding(childLayout, widthMeasureSpec, contentHeightSpec); } else if (!measureAppBarLayout || (appBar != childLayout.Owner)) // if childLayout is not appBar.Layout { MeasureChildWithoutPadding(childLayout, widthMeasureSpec, heightMeasureSpec); } float childRight = childLayout.MeasuredWidth.Size.AsDecimal() + childLayout.Owner.PositionX; float childBottom = childLayout.MeasuredHeight.Size.AsDecimal() + childLayout.Owner.PositionY; if (maxWidth < childRight) maxWidth = childRight; if (maxHeight < childBottom) maxHeight = childBottom; if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childWidthState = MeasuredSize.StateType.MeasuredSizeTooSmall; } if (childLayout.MeasuredHeight.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childHeightState = MeasuredSize.StateType.MeasuredSizeTooSmall; } } SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(maxWidth), widthMeasureSpec, childWidthState), ResolveSizeAndState(new LayoutLength(maxHeight), heightMeasureSpec, childHeightState)); } protected override void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom) { foreach (var childLayout in LayoutChildren) { if (!childLayout.SetPositionByLayout) { continue; } LayoutLength childWidth = childLayout.MeasuredWidth.Size; LayoutLength childHeight = childLayout.MeasuredHeight.Size; LayoutLength childLeft = new LayoutLength(childLayout.Owner.PositionX); LayoutLength childTop = new LayoutLength(childLayout.Owner.PositionY); var appBar = (Owner as ContentPage)?.AppBar; var content = (Owner as ContentPage)?.Content; if ((content != null) && (content == childLayout.Owner)) { childTop = new LayoutLength(Padding.Top + content.Margin.Top + (appBar?.Layout.MeasuredHeight.Size.AsDecimal() ?? 0)); childLayout.Layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight, false); } else { childLayout.Layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight, true); } } } } } }