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.
19 using System.ComponentModel;
20 using System.Collections.Generic;
21 using Tizen.NUI.BaseComponents;
23 namespace Tizen.NUI.Components
26 /// AlertDialog class shows a dialog with title, message and action buttons.
28 /// <since_tizen> 9 </since_tizen>
29 public class AlertDialog : Control
31 private string title = null;
32 private string message = null;
34 private View titleContent = null;
35 private View content = null;
36 private View actionContent = null;
37 private IEnumerable<View> actionContentViews = null;
39 private View defaultTitleContent = null;
40 private View defaultContent = null;
41 private View defaultActionContent = null;
42 // FIXME: Now AlertDialog.Padding Top and Bottom increases AlertDialog size incorrectly.
43 // Until the bug is fixed, padding view is added after action content.
44 private View defaultActionContentPadding = null;
46 private AlertDialogStyle alertDialogStyle => ViewStyle as AlertDialogStyle;
48 private bool styleApplied = false;
51 /// Creates a new instance of AlertDialog.
53 /// <since_tizen> 9 </since_tizen>
54 public AlertDialog() : base()
60 /// Creates a new instance of AlertDialog.
62 /// <param name="style">Creates AlertDialog by special style defined in UX.</param>
63 /// <since_tizen> 9 </since_tizen>
64 public AlertDialog(string style) : base(style)
70 /// Creates a new instance of AlertDialog.
72 /// <param name="alertDialogStyle">Creates AlertDialog by style customized by user.</param>
73 /// <since_tizen> 9 </since_tizen>
74 public AlertDialog(AlertDialogStyle alertDialogStyle) : base(alertDialogStyle)
80 [EditorBrowsable(EditorBrowsableState.Never)]
81 protected override void Dispose(DisposeTypes type)
88 if (type == DisposeTypes.Explicit)
90 if (titleContent != null)
92 Utility.Dispose(titleContent);
97 Utility.Dispose(content);
100 if (actionContent != null)
102 Utility.Dispose(actionContent);
105 // FIXME: Now AlertDialog.Padding Top and Bottom increases AlertDialog size incorrectly.
106 // Until the bug is fixed, padding view is added after action content.
107 if (defaultActionContentPadding != null)
109 Utility.Dispose(defaultActionContentPadding);
117 /// Applies style to AlertDialog.
119 /// <param name="viewStyle">The style to apply.</param>
120 /// <since_tizen> 9 </since_tizen>
121 public override void ApplyStyle(ViewStyle viewStyle)
123 styleApplied = false;
125 base.ApplyStyle(viewStyle);
127 // Apply Title style.
128 if ((alertDialogStyle?.TitleTextLabel != null) && (DefaultTitleContent is TextLabel))
130 ((TextLabel)DefaultTitleContent)?.ApplyStyle(alertDialogStyle.TitleTextLabel);
133 // Apply Message style.
134 if ((alertDialogStyle?.MessageTextLabel != null) && (DefaultContent is TextLabel))
136 ((TextLabel)DefaultContent)?.ApplyStyle(alertDialogStyle.MessageTextLabel);
139 // Apply ActionContent style.
140 if (alertDialogStyle?.ActionContent != null)
142 DefaultActionContent?.ApplyStyle(alertDialogStyle.ActionContent);
147 // Calculate dialog position and children's positions based on padding sizes.
152 /// Title text of AlertDialog.
153 /// Title text is set to TitleContent's Text if TitleContent is TextLabel.
154 /// If TitleContent's Text is set manually by user, then it is not guaranteed that TitleContent's Text is the same with Title text.
156 /// <since_tizen> 9 </since_tizen>
172 if (TitleContent is TextLabel textLabel)
174 textLabel.Text = title;
180 /// Title content of AlertDialog.
181 /// TitleContent is added as a child of AlertDialog automatically.
182 /// Title text is set to TitleContent's Text if TitleContent is TextLabel.
183 /// If TitleContent's Text is set manually by user, then it is not guaranteed that TitleContent's Text is the same with Title text.
185 /// <since_tizen> 9 </since_tizen>
186 public View TitleContent
194 if (titleContent == value)
199 if (titleContent != null)
201 Remove(titleContent);
204 titleContent = value;
205 if (titleContent == null)
210 if (titleContent is TextLabel textLabel)
212 textLabel.Text = Title;
220 /// Message text of AlertDialog.
221 /// Message text is set to Content's Text if Content is TextLabel.
222 /// If Content's Text is set manually by user, then it is not guaranteed that Content's Text is the same with Message text.
224 /// <since_tizen> 9 </since_tizen>
225 public string Message
233 if (message == value)
240 if (Content is TextLabel textLabel)
242 textLabel.Text = message;
248 /// Content of AlertDialog.
249 /// Content is added as a child of AlertDialog automatically.
250 /// Message text is set to Content's Text if Content is TextLabel.
251 /// If Content's Text is set manually by user, then it is not guaranteed that Content's Text is the same with Message text.
253 /// <since_tizen> 9 </since_tizen>
262 if (content == value)
278 if (content is TextLabel textLabel)
280 textLabel.Text = message;
288 /// Action views of AlertDialog.
289 /// Action views are added as children of ActionContent.
290 /// When Actions are set, previous Actions are removed from ActionContent.
292 /// <since_tizen> 9 </since_tizen>
293 public IEnumerable<View> Actions
297 return actionContentViews;
301 if (ActionContent == null)
303 actionContentViews = value;
307 if (actionContentViews != null)
309 foreach (var oldAction in actionContentViews)
311 if (ActionContent.Children?.Contains(oldAction) == true)
313 ActionContent.Children.Remove(oldAction);
318 actionContentViews = value;
320 if (actionContentViews == null)
325 foreach (var action in actionContentViews)
327 ActionContent.Add(action);
333 /// Action content of AlertDialog.
334 /// ActionContent is added as a child of AlertDialog automatically.
335 /// Actions are added as children of ActionContent.
337 /// <since_tizen> 9 </since_tizen>
338 public View ActionContent
342 return actionContent;
346 if (actionContent == value)
351 var oldActionContent = actionContent;
352 actionContent = value;
354 // Add views first before remove previous action content
355 // not to cause Garbage Collector collects views.
356 if ((actionContent != null) && (Actions != null))
358 foreach (var action in Actions)
360 actionContent.Add(action);
364 if (oldActionContent != null)
366 Remove(oldActionContent);
369 if (actionContent == null)
379 /// AccessibilityGetName.
381 [EditorBrowsable(EditorBrowsableState.Never)]
382 protected override string AccessibilityGetName()
384 if (!String.IsNullOrEmpty(Title))
395 /// Initialize AT-SPI object.
397 [EditorBrowsable(EditorBrowsableState.Never)]
398 public override void OnInitialize()
401 SetAccessibilityConstructor(Role.Dialog);
402 AppendAccessibilityAttribute("sub-role", "Alert");
403 Show(); // calls AddPopup()
407 /// Informs AT-SPI bridge about the set of AT-SPI states associated with this object.
409 [EditorBrowsable(EditorBrowsableState.Never)]
410 protected override AccessibilityStates AccessibilityCalculateStates()
412 var states = base.AccessibilityCalculateStates();
413 FlagSetter(ref states, AccessibilityStates.Modal, true);
419 /// Default title content of AlertDialog.
420 /// If Title is set, then default title content is automatically displayed.
422 [EditorBrowsable(EditorBrowsableState.Never)]
423 protected View DefaultTitleContent
427 if (defaultTitleContent == null)
429 defaultTitleContent = CreateDefaultTitleContent();
432 return defaultTitleContent;
437 /// Default content of AlertDialog.
438 /// If Message is set, then default content is automatically displayed.
440 [EditorBrowsable(EditorBrowsableState.Never)]
441 protected View DefaultContent
445 if (defaultContent == null)
447 defaultContent = CreateDefaultContent();
450 return defaultContent;
455 /// Default action content of AlertDialog.
456 /// If Actions are set, then default action content is automatically displayed.
458 [EditorBrowsable(EditorBrowsableState.Never)]
459 protected View DefaultActionContent
463 if (defaultActionContent == null)
465 defaultActionContent = CreateDefaultActionContent();
468 // FIXME: Now AlertDialog.Padding Top and Bottom increases AlertDialog size incorrectly.
469 // Until the bug is fixed, padding view is added after action content.
470 if (defaultActionContentPadding == null)
472 defaultActionContentPadding = CreateDefaultActionContentPadding();
475 return defaultActionContent;
479 private void Initialize()
481 Layout = new LinearLayout()
483 LinearOrientation = LinearLayout.Orientation.Vertical,
486 this.Relayout += OnRelayout;
488 TitleContent = DefaultTitleContent;
490 Content = DefaultContent;
492 ActionContent = DefaultActionContent;
495 private void ResetContent()
497 //To keep the order of TitleContent, Content and ActionContent,
498 //the existing contents are removed and added again.
499 if (titleContent != null)
501 Remove(titleContent);
509 if (actionContent != null)
511 Remove(actionContent);
514 if (titleContent != null)
524 if (actionContent != null)
528 // FIXME: Now AlertDialog.Padding Top and Bottom increases AlertDialog size incorrectly.
529 // Until the bug is fixed, padding view is added after action content.
530 if (actionContent == defaultActionContent)
532 if (defaultActionContentPadding != null)
534 Add(defaultActionContentPadding);
540 private TextLabel CreateDefaultTitleContent()
542 return new TextLabel();
545 private TextLabel CreateDefaultContent()
547 return new TextLabel();
550 private View CreateDefaultActionContent()
554 Layout = new LinearLayout()
556 LinearOrientation = LinearLayout.Orientation.Horizontal,
561 // FIXME: Now AlertDialog.Padding Top and Bottom increases AlertDialog size incorrectly.
562 // Until the bug is fixed, padding view is added after action content.
563 private View CreateDefaultActionContentPadding()
565 var layout = Layout as LinearLayout;
567 if ((layout == null) || (defaultActionContent == null))
572 View paddingView = null;
574 using (Size2D size = new Size2D(defaultActionContent.Size2D.Width, defaultActionContent.Size2D.Height))
576 if (layout.LinearOrientation == LinearLayout.Orientation.Horizontal)
585 paddingView = new View()
587 Size2D = new Size2D(size.Width, size.Height),
594 private void OnRelayout(object sender, EventArgs e)
596 // Calculate dialog position and children's positions based on padding sizes.
600 // Calculate dialog position and children's positions based on padding sizes.
601 private void CalculatePosition()
603 if (styleApplied == false)
608 CalculateActionsCellPadding();
611 var parent = GetParent();
614 if ((parent != null) && (parent is View))
616 parentSize = ((View)parent).Size;
620 parentSize = NUIApplication.GetDefaultWindow().Size;
623 Position2D = new Position2D((parentSize.Width - size.Width) / 2, (parentSize.Height - size.Height) / 2);
626 // Calculate CellPadding among Actions if ActionContent is LinearLayout.
627 private void CalculateActionsCellPadding()
629 if ((ActionContent != DefaultActionContent) || (ActionContent.Layout is LinearLayout == false))
640 var layout = ActionContent.Layout as LinearLayout;
643 if (layout.LinearOrientation == LinearLayout.Orientation.Horizontal)
645 int actionsWidth = 0;
647 foreach (var action in Actions)
649 actionsWidth += ((View)action).Size2D.Width + ((((View)action).Margin?.Start + ((View)action).Margin?.End) ?? 0);
655 actionsWidth += (Padding?.Start + Padding?.End) ?? 0;
656 var cellPaddingWidth = (size.Width - actionsWidth) / (count - 1);
657 layout.CellPadding = new Size2D(cellPaddingWidth , 0);
662 int actionsHeight = 0;
664 foreach (var action in Actions)
666 actionsHeight += ((View)action).Size2D.Height + ((((View)action).Margin?.Top + ((View)action).Margin?.Bottom) ?? 0);
672 actionsHeight += (Padding?.Top + Padding?.Bottom) ?? 0;
673 var cellPaddingHeight = (size.Height - actionsHeight) / (count - 1);
674 layout.CellPadding = new Size2D(0, cellPaddingHeight);