2 * Copyright (c) 2018 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.
18 using System.Collections.Generic;
19 using System.Collections.ObjectModel;
20 using System.Collections.Specialized;
21 using System.ComponentModel;
23 using System.Threading;
24 using System.Threading.Tasks;
25 using Tizen.NUI.Binding.Internals;
26 using Tizen.NUI.Binding;
31 /// A BaseHandle that occupies the entire screen.
33 // [RenderWith(typeof(_PageRenderer))]
34 [EditorBrowsable(EditorBrowsableState.Never)]
35 public class Page : BaseHandle, IPageController, IElementConfiguration<Page>
40 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
41 [EditorBrowsable(EditorBrowsableState.Never)]
42 public const string BusySetSignalName = "NUI.BusySet";
47 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
48 [EditorBrowsable(EditorBrowsableState.Never)]
49 public const string AlertSignalName = "NUI.SendAlert";
54 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
55 [EditorBrowsable(EditorBrowsableState.Never)]
56 public const string ActionSheetSignalName = "NUI.ShowActionSheet";
58 internal static readonly BindableProperty IgnoresContainerAreaProperty = BindableProperty.Create("IgnoresContainerArea", typeof(bool), typeof(Page), false);
61 /// Identifies the IsBusy property.
63 internal static readonly BindableProperty IsBusyProperty = BindableProperty.Create("IsBusy", typeof(bool), typeof(Page), false, propertyChanged: (bo, o, n) => ((Page)bo).OnPageBusyChanged());
65 Rectangle _containerArea;
69 ReadOnlyCollection<Element> _logicalChildren;
72 /// Creates a new Page element with default values.
74 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
75 [EditorBrowsable(EditorBrowsableState.Never)]
78 // ToolbarItems = toolbarItems;
79 InternalChildren.CollectionChanged += InternalChildrenOnCollectionChanged;
83 /// Marks the Page as busy. This will cause the platform specific global activity indicator to show a busy state.
85 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
86 [EditorBrowsable(EditorBrowsableState.Never)]
89 get { return (bool)GetValue(IsBusyProperty); }
90 set { SetValue(IsBusyProperty, value); }
96 [EditorBrowsable(EditorBrowsableState.Never)]
97 public Rectangle ContainerArea
99 get { return _containerArea; }
102 if (_containerArea == value)
105 _containerArea = value;
111 /// For internal use.
113 [EditorBrowsable(EditorBrowsableState.Never)]
114 public bool IgnoresContainerArea
116 get { return (bool)GetValue(IgnoresContainerAreaProperty); }
117 set { SetValue(IgnoresContainerAreaProperty, value); }
121 /// For internal use.
123 [EditorBrowsable(EditorBrowsableState.Never)]
124 public ObservableCollection<Element> InternalChildren { get; } = new ObservableCollection<Element>();
126 internal override ReadOnlyCollection<Element> LogicalChildrenInternal =>
127 _logicalChildren ?? (_logicalChildren = new ReadOnlyCollection<Element>(InternalChildren));
130 /// ndicates that the Page is about to appear.
132 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
133 [EditorBrowsable(EditorBrowsableState.Never)]
134 public event EventHandler Appearing;
137 /// Indicates that the Page is about to cease displaying.
139 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
140 [EditorBrowsable(EditorBrowsableState.Never)]
141 public event EventHandler Disappearing;
144 /// Displays a native platform action sheet, allowing the application user to choose from several buttons.
146 /// <param name="title">Title of the displayed action sheet. Must not be null.</param>
147 /// <param name="cancel">Text to be displayed in the 'Cancel' button. Can be null to hide the cancel action.</param>
148 /// <param name="destruction">Text to be displayed in the 'Destruct' button. Can be null to hide the destructive option.</param>
149 /// <param name="buttons">Text labels for additional buttons. Must not be null.</param>
150 /// <returns>An awaitable Task that displays an action sheet and returns the Text of the button pressed by the user.</returns>
151 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
152 [EditorBrowsable(EditorBrowsableState.Never)]
153 public Task<string> DisplayActionSheet(string title, string cancel, string destruction, params string[] buttons)
155 var args = new ActionSheetArguments(title, cancel, destruction, buttons);
156 MessagingCenter.Send(this, ActionSheetSignalName, args);
157 return args.Result.Task;
161 /// Presents an alert dialog to the application user with a single cancel button.
163 /// <param name="title">The title of the alert dialog.</param>
164 /// <param name="message">The body text of the alert dialog.</param>
165 /// <param name="cancel">Text to be displayed on the 'Cancel' button.</param>
166 /// <returns></returns>
167 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
168 [EditorBrowsable(EditorBrowsableState.Never)]
169 public Task DisplayAlert(string title, string message, string cancel)
171 return DisplayAlert(title, message, null, cancel);
175 /// resents an alert dialog to the application user with an accept and a cancel button.
177 /// <param name="title">The title of the alert dialog.</param>
178 /// <param name="message">The body text of the alert dialog.</param>
179 /// <param name="accept">Text to be displayed on the 'Accept' button.</param>
180 /// <param name="cancel">Text to be displayed on the 'Cancel' button.</param>
181 /// <returns></returns>
182 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
183 [EditorBrowsable(EditorBrowsableState.Never)]
184 public Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
186 if (string.IsNullOrEmpty(cancel))
187 throw new ArgumentNullException("cancel");
189 var args = new AlertArguments(title, message, accept, cancel);
190 MessagingCenter.Send(this, AlertSignalName, args);
191 return args.Result.Task;
195 /// Forces the Page to perform a layout pass.
197 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
198 [EditorBrowsable(EditorBrowsableState.Never)]
199 public void ForceLayout()
204 /// Calls OnBackButtonPressed().
206 /// <returns></returns>
207 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
208 [EditorBrowsable(EditorBrowsableState.Never)]
209 public bool SendBackButtonPressed()
211 return OnBackButtonPressed();
215 /// When overridden, allows application developers to customize behavior immediately prior to the Page becoming visible.
217 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
218 [EditorBrowsable(EditorBrowsableState.Never)]
219 protected virtual void OnAppearing()
224 /// Application developers can override this method to provide behavior when the back button is pressed.
226 /// <returns>true if consumed</returns>
227 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
228 [EditorBrowsable(EditorBrowsableState.Never)]
229 protected virtual bool OnBackButtonPressed()
231 var application = RealParent as Application;
233 var canceled = false;
234 EventHandler handler = (sender, args) => { canceled = true; };
240 /// Invoked whenever the binding context of the Page changes. Override this method to add class handling for this event.
242 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
243 [EditorBrowsable(EditorBrowsableState.Never)]
244 protected override void OnBindingContextChanged()
246 base.OnBindingContextChanged();
250 /// Indicates that the preferred size of a child Element has changed.
252 /// <param name="sender">The object that raised the event.</param>
253 /// <param name="e">The event arguments.</param>
254 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
255 [EditorBrowsable(EditorBrowsableState.Never)]
256 protected virtual void OnChildMeasureInvalidated(object sender, EventArgs e)
258 InvalidationTrigger trigger = (e as InvalidationEventArgs)?.Trigger ?? InvalidationTrigger.Undefined;
259 OnChildMeasureInvalidated((BaseHandle)sender, trigger);
263 /// When overridden, allows the application developer to customize behavior as the Page disappears.
265 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
266 [EditorBrowsable(EditorBrowsableState.Never)]
267 protected virtual void OnDisappearing()
272 /// Called when the Page's Parent property has changed.
274 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
275 [EditorBrowsable(EditorBrowsableState.Never)]
276 protected override void OnParentSet()
281 internal virtual void OnChildMeasureInvalidated(BaseHandle child, InvalidationTrigger trigger)
283 var container = this as IPageContainer<Page>;
284 if (container != null)
286 Page page = container.CurrentPage;
294 for (var i = 0; i < LogicalChildren.Count; i++)
296 var v = LogicalChildren[i] as BaseHandle;
306 /// For intarnal use.
308 [EditorBrowsable(EditorBrowsableState.Never)]
309 public void SendAppearing()
317 MessagingCenter.Send(this, BusySetSignalName, true);
320 Appearing?.Invoke(this, EventArgs.Empty);
322 var pageContainer = this as IPageContainer<Page>;
323 pageContainer?.CurrentPage?.SendAppearing();
327 /// For intarnal use.
329 [EditorBrowsable(EditorBrowsableState.Never)]
330 public void SendDisappearing()
335 _hasAppeared = false;
338 MessagingCenter.Send(this, BusySetSignalName, false);
340 var pageContainer = this as IPageContainer<Page>;
341 pageContainer?.CurrentPage?.SendDisappearing();
344 Disappearing?.Invoke(this, EventArgs.Empty);
347 Application FindApplication(Element element)
352 return (element.Parent is Application app) ? app : FindApplication(element.Parent);
355 void InternalChildrenOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
357 if (e.OldItems != null)
359 foreach (BaseHandle item in e.OldItems.OfType<BaseHandle>())
361 OnInternalRemoved(item);
365 if (e.NewItems != null)
367 foreach (BaseHandle item in e.NewItems.OfType<BaseHandle>())
369 OnInternalAdded(item);
374 private void OnInternalAdded(BaseHandle view)
379 private void OnInternalRemoved(BaseHandle view)
381 OnChildRemoved(view);
384 void OnPageBusyChanged()
389 MessagingCenter.Send(this, BusySetSignalName, IsBusy);
392 void OnToolbarItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
396 if (args.Action != NotifyCollectionChangedAction.Add)
398 if (args.NewItems != null)
400 foreach (IElement item in args.NewItems)
406 bool ShouldLayoutChildren()
408 if (!LogicalChildren.Any())
413 var container = this as IPageContainer<Page>;
414 if (container?.CurrentPage != null)
420 for (var i = 0; i < LogicalChildren.Count; i++)
422 var v = LogicalChildren[i] as BaseHandle;