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 bool styleApplied = false;
49 /// Creates a new instance of AlertDialog.
51 /// <since_tizen> 9 </since_tizen>
52 public AlertDialog() : base()
58 /// Creates a new instance of AlertDialog.
60 /// <param name="style">Creates AlertDialog by special style defined in UX.</param>
61 /// <since_tizen> 9 </since_tizen>
62 public AlertDialog(string style) : base(style)
68 /// Creates a new instance of AlertDialog.
70 /// <param name="alertDialogStyle">Creates AlertDialog by style customized by user.</param>
71 /// <since_tizen> 9 </since_tizen>
72 public AlertDialog(AlertDialogStyle alertDialogStyle) : base(alertDialogStyle)
78 [EditorBrowsable(EditorBrowsableState.Never)]
79 protected override void Dispose(DisposeTypes type)
86 if (type == DisposeTypes.Explicit)
88 if (titleContent != null)
90 Utility.Dispose(titleContent);
95 Utility.Dispose(content);
98 if (actionContent != null)
100 Utility.Dispose(actionContent);
103 // FIXME: Now AlertDialog.Padding Top and Bottom increases AlertDialog size incorrectly.
104 // Until the bug is fixed, padding view is added after action content.
105 if (defaultActionContentPadding != null)
107 Utility.Dispose(defaultActionContentPadding);
115 /// Applies style to AlertDialog.
117 /// <param name="viewStyle">The style to apply.</param>
118 /// <since_tizen> 9 </since_tizen>
119 public override void ApplyStyle(ViewStyle viewStyle)
121 styleApplied = false;
123 base.ApplyStyle(viewStyle);
125 var alertDialogStyle = viewStyle as AlertDialogStyle;
127 if (alertDialogStyle == null)
132 // Apply Title style.
133 if ((alertDialogStyle.TitleTextLabel != null) && (DefaultTitleContent is TextLabel))
135 ((TextLabel)DefaultTitleContent)?.ApplyStyle(alertDialogStyle.TitleTextLabel);
138 // Apply Message style.
139 if ((alertDialogStyle.MessageTextLabel != null) && (DefaultContent is TextLabel))
141 ((TextLabel)DefaultContent)?.ApplyStyle(alertDialogStyle.MessageTextLabel);
144 // Apply ActionContent style.
145 if (alertDialogStyle.ActionContent != null)
147 DefaultActionContent?.ApplyStyle(alertDialogStyle.ActionContent);
152 // Calculate dialog position and children's positions based on padding sizes.
157 /// Title text of AlertDialog.
158 /// Title text is set to TitleContent's Text if TitleContent is TextLabel.
159 /// If TitleContent's Text is set manually by user, then it is not guaranteed that TitleContent's Text is the same with Title text.
161 /// <since_tizen> 9 </since_tizen>
177 if (TitleContent is TextLabel textLabel)
179 textLabel.Text = title;
185 /// Title content of AlertDialog.
186 /// TitleContent is added as a child of AlertDialog automatically.
187 /// Title text is set to TitleContent's Text if TitleContent is TextLabel.
188 /// If TitleContent's Text is set manually by user, then it is not guaranteed that TitleContent's Text is the same with Title text.
190 /// <since_tizen> 9 </since_tizen>
191 public View TitleContent
199 if (titleContent == value)
204 if (titleContent != null)
206 Remove(titleContent);
209 titleContent = value;
210 if (titleContent == null)
215 if (titleContent is TextLabel textLabel)
217 textLabel.Text = Title;
225 /// Message text of AlertDialog.
226 /// Message text is set to Content's Text if Content is TextLabel.
227 /// If Content's Text is set manually by user, then it is not guaranteed that Content's Text is the same with Message text.
229 /// <since_tizen> 9 </since_tizen>
230 public string Message
238 if (message == value)
245 if (Content is TextLabel textLabel)
247 textLabel.Text = message;
253 /// Content of AlertDialog.
254 /// Content is added as a child of AlertDialog automatically.
255 /// Message text is set to Content's Text if Content is TextLabel.
256 /// If Content's Text is set manually by user, then it is not guaranteed that Content's Text is the same with Message text.
258 /// <since_tizen> 9 </since_tizen>
267 if (content == value)
283 if (content is TextLabel textLabel)
285 textLabel.Text = message;
293 /// Action views of AlertDialog.
294 /// Action views are added as children of ActionContent.
295 /// When Actions are set, previous Actions are removed from ActionContent.
297 /// <since_tizen> 9 </since_tizen>
298 public IEnumerable<View> Actions
302 return actionContentViews;
306 if (ActionContent == null)
308 actionContentViews = value;
312 if (actionContentViews != null)
314 foreach (var oldAction in actionContentViews)
316 if (ActionContent.Children?.Contains(oldAction) == true)
318 ActionContent.Children.Remove(oldAction);
323 actionContentViews = value;
325 if (actionContentViews == null)
330 foreach (var action in actionContentViews)
332 ActionContent.Add(action);
338 /// Action content of AlertDialog.
339 /// ActionContent is added as a child of AlertDialog automatically.
340 /// Actions are added as children of ActionContent.
342 /// <since_tizen> 9 </since_tizen>
343 public View ActionContent
347 return actionContent;
351 if (actionContent == value)
356 var oldActionContent = actionContent;
357 actionContent = value;
359 // Add views first before remove previous action content
360 // not to cause Garbage Collector collects views.
361 if ((actionContent != null) && (Actions != null))
363 foreach (var action in Actions)
365 actionContent.Add(action);
369 if (oldActionContent != null)
371 Remove(oldActionContent);
374 if (actionContent == null)
384 /// AccessibilityGetName.
386 [EditorBrowsable(EditorBrowsableState.Never)]
387 protected override string AccessibilityGetName()
389 if (!String.IsNullOrEmpty(Title))
400 /// Initialize AT-SPI object.
402 [EditorBrowsable(EditorBrowsableState.Never)]
403 public override void OnInitialize()
406 SetAccessibilityConstructor(Role.Dialog);
407 AppendAccessibilityAttribute("sub-role", "Alert");
408 Show(); // calls AddPopup()
412 /// Informs AT-SPI bridge about the set of AT-SPI states associated with this object.
414 [EditorBrowsable(EditorBrowsableState.Never)]
415 protected override AccessibilityStates AccessibilityCalculateStates()
417 var states = base.AccessibilityCalculateStates();
418 FlagSetter(ref states, AccessibilityStates.Modal, true);
424 /// Default title content of AlertDialog.
425 /// If Title is set, then default title content is automatically displayed.
427 [EditorBrowsable(EditorBrowsableState.Never)]
428 protected View DefaultTitleContent
432 if (defaultTitleContent == null)
434 defaultTitleContent = CreateDefaultTitleContent();
437 return defaultTitleContent;
442 /// Default content of AlertDialog.
443 /// If Message is set, then default content is automatically displayed.
445 [EditorBrowsable(EditorBrowsableState.Never)]
446 protected View DefaultContent
450 if (defaultContent == null)
452 defaultContent = CreateDefaultContent();
455 return defaultContent;
460 /// Default action content of AlertDialog.
461 /// If Actions are set, then default action content is automatically displayed.
463 [EditorBrowsable(EditorBrowsableState.Never)]
464 protected View DefaultActionContent
468 if (defaultActionContent == null)
470 defaultActionContent = CreateDefaultActionContent();
473 // FIXME: Now AlertDialog.Padding Top and Bottom increases AlertDialog size incorrectly.
474 // Until the bug is fixed, padding view is added after action content.
475 if (defaultActionContentPadding == null)
477 defaultActionContentPadding = CreateDefaultActionContentPadding();
480 return defaultActionContent;
484 private void Initialize()
486 Layout = new LinearLayout()
488 LinearOrientation = LinearLayout.Orientation.Vertical,
489 LinearAlignment = LinearLayout.Alignment.CenterHorizontal,
492 this.Relayout += OnRelayout;
494 TitleContent = DefaultTitleContent;
496 Content = DefaultContent;
498 ActionContent = DefaultActionContent;
501 private void ResetContent()
503 //To keep the order of TitleContent, Content and ActionContent,
504 //the existing contents are removed and added again.
505 if (titleContent != null)
507 Remove(titleContent);
515 if (actionContent != null)
517 Remove(actionContent);
520 if (titleContent != null)
530 if (actionContent != null)
534 // FIXME: Now AlertDialog.Padding Top and Bottom increases AlertDialog size incorrectly.
535 // Until the bug is fixed, padding view is added after action content.
536 if (actionContent == defaultActionContent)
538 if (defaultActionContentPadding != null)
540 Add(defaultActionContentPadding);
546 private TextLabel CreateDefaultTitleContent()
548 return new TextLabel();
551 private TextLabel CreateDefaultContent()
553 return new TextLabel();
556 private View CreateDefaultActionContent()
560 Layout = new LinearLayout()
562 LinearOrientation = LinearLayout.Orientation.Horizontal,
563 LinearAlignment = LinearLayout.Alignment.Center,
564 // FIXME: This CellPadding value should be written in AlertDialogStyle.
565 // However, if this is called in other place, then flicking issue happens.
566 CellPadding = new Size2D(80, 0),
571 // FIXME: Now AlertDialog.Padding Top and Bottom increases AlertDialog size incorrectly.
572 // Until the bug is fixed, padding view is added after action content.
573 private View CreateDefaultActionContentPadding()
575 var layout = Layout as LinearLayout;
577 if ((layout == null) || (defaultActionContent == null))
582 View paddingView = null;
584 using (Size2D size = new Size2D(defaultActionContent.Size2D.Width, defaultActionContent.Size2D.Height))
586 if (layout.LinearOrientation == LinearLayout.Orientation.Horizontal)
595 paddingView = new View()
597 Size2D = new Size2D(size.Width, size.Height),
604 private void OnRelayout(object sender, EventArgs e)
606 // Calculate dialog position and children's positions based on padding sizes.
610 // Calculate dialog position and children's positions based on padding sizes.
611 private void CalculatePosition()
613 if (styleApplied == false)
619 var parent = GetParent();
622 if ((parent != null) && (parent is View))
624 parentSize = ((View)parent).Size;
628 parentSize = NUIApplication.GetDefaultWindow().Size;
631 Position2D = new Position2D((parentSize.Width - size.Width) / 2, (parentSize.Height - size.Height) / 2);