2 * Copyright(c) 2019 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 Tizen.NUI.BaseComponents;
20 using Tizen.NUI.Binding;
21 using System.ComponentModel;
23 namespace Tizen.NUI.Components
26 /// Popup is one kind of common component, it can be used as popup window.
27 /// User can handle Popup button count, head title and content area.
29 /// <since_tizen> 6 </since_tizen>
30 public class Popup : Control
32 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
33 [EditorBrowsable(EditorBrowsableState.Never)]
34 public static readonly BindableProperty ButtonCountProperty = BindableProperty.Create("ButtonCount", typeof(int), typeof(Popup), 0, propertyChanged: (bindable, oldValue, newValue) =>
36 var instance = (Popup)bindable;
37 if ((int)newValue != instance.buttonCount)
39 instance.buttonCount = (int)newValue;
40 instance.UpdateButton();
43 defaultValueCreator: (bindable) =>
45 var instance = (Popup)bindable;
46 return instance.buttonCount;
49 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
50 [EditorBrowsable(EditorBrowsableState.Never)]
51 public static readonly BindableProperty ShadowOffsetProperty = BindableProperty.Create("ShadowOffset", typeof(Vector4), typeof(Popup), new Vector4(0, 0, 0, 0), propertyChanged: (bindable, oldValue, newValue) =>
53 var instance = (Popup)bindable;
56 if (null != instance.Style)
58 instance.Style.ShadowOffset = (Vector4)newValue;
59 instance.UpdateShadow();
63 defaultValueCreator: (bindable) =>
65 var instance = (Popup)bindable;
66 return instance.Style.ShadowOffset;
69 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
70 [EditorBrowsable(EditorBrowsableState.Never)]
71 public static readonly BindableProperty ButtonHeightProperty = BindableProperty.Create("ButtonHeight", typeof(int), typeof(Popup), default(int), propertyChanged: (bindable, oldValue, newValue) =>
73 var instance = (Popup)bindable;
76 if (null != instance.Style?.Buttons?.Size)
78 instance.Style.Buttons.Size.Height = (int)newValue;
79 instance.UpdateButton();
83 defaultValueCreator: (bindable) =>
85 var instance = (Popup)bindable;
86 return instance.Style.Buttons?.Size?.Height ?? 0;
89 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
90 [EditorBrowsable(EditorBrowsableState.Never)]
91 public static readonly BindableProperty ButtonTextPointSizeProperty = BindableProperty.Create("ButtonTextPointSize", typeof(float), typeof(Popup), default(float), propertyChanged: (bindable, oldValue, newValue) =>
93 var instance = (Popup)bindable;
96 if (null != instance.Style?.Buttons?.Text)
98 instance.Style.Buttons.Text.PointSize = (float)newValue;
99 instance.UpdateButton();
103 defaultValueCreator: (bindable) =>
105 var instance = (Popup)bindable;
106 return instance.Style.Buttons?.Text?.PointSize?.All ?? 0;
109 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
110 [EditorBrowsable(EditorBrowsableState.Never)]
111 public static readonly BindableProperty ButtonFontFamilyProperty = BindableProperty.Create("ButtonFontFamily", typeof(string), typeof(Popup), string.Empty, propertyChanged: (bindable, oldValue, newValue) =>
113 var instance = (Popup)bindable;
114 if (newValue != null)
116 if (null != instance.Style?.Buttons?.Text)
118 instance.Style.Buttons.Text.FontFamily = (string)newValue;
119 instance.UpdateButton();
123 defaultValueCreator: (bindable) =>
125 var instance = (Popup)bindable;
126 return instance.Style.Buttons?.Text?.FontFamily;
129 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
130 [EditorBrowsable(EditorBrowsableState.Never)]
131 public static readonly BindableProperty ButtonTextColorProperty = BindableProperty.Create("ButtonTextColor", typeof(Color), typeof(Popup), Color.Transparent, propertyChanged: (bindable, oldValue, newValue) =>
133 var instance = (Popup)bindable;
134 if (newValue != null)
136 if (null != instance.Style?.Buttons?.Text)
138 instance.Style.Buttons.Text.TextColor = (Color)newValue;
142 defaultValueCreator: (bindable) =>
144 var instance = (Popup)bindable;
145 return instance.Style.Buttons?.Text?.TextColor?.All;
148 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
149 [EditorBrowsable(EditorBrowsableState.Never)]
150 public static readonly BindableProperty ButtonOverLayBackgroundColorSelectorProperty = BindableProperty.Create("ButtonOverLayBackgroundColorSelector", typeof(Selector<Color>), typeof(Popup), new Selector<Color>(), propertyChanged: (bindable, oldValue, newValue) =>
152 var instance = (Popup)bindable;
153 if (newValue != null)
155 if (null != instance.Style?.Buttons?.Overlay)
157 Selector<Color> color = (Selector<Color>)newValue;
158 if (null == instance.Style.Buttons.Overlay.BackgroundColor)
160 instance.Style.Buttons.Overlay.BackgroundColor = new Selector<Color>();
162 instance.Style.Buttons.Overlay.BackgroundColor.Clone(color);
163 instance.UpdateButton();
167 defaultValueCreator: (bindable) =>
169 var instance = (Popup)bindable;
170 return instance.Style.Buttons?.Overlay?.BackgroundColor;
173 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
174 [EditorBrowsable(EditorBrowsableState.Never)]
175 public static readonly BindableProperty ButtonTextAlignmentProperty = BindableProperty.Create("ButtonTextAlignment", typeof(HorizontalAlignment), typeof(Popup), new HorizontalAlignment(), propertyChanged: (bindable, oldValue, newValue) =>
177 var instance = (Popup)bindable;
178 if (newValue != null)
180 if (null != instance.Style?.Buttons?.Text)
182 instance.Style.Buttons.Text.HorizontalAlignment = (HorizontalAlignment)newValue;
183 instance.UpdateButton();
187 defaultValueCreator: (bindable) =>
189 var instance = (Popup)bindable;
190 return instance.Style.Buttons?.Text?.HorizontalAlignment ?? HorizontalAlignment.Center;
193 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
194 [EditorBrowsable(EditorBrowsableState.Never)]
195 public static readonly BindableProperty ButtonBackgroundProperty = BindableProperty.Create("ButtonBackground", typeof(string), typeof(Popup), string.Empty, propertyChanged: (bindable, oldValue, newValue) =>
197 var instance = (Popup)bindable;
198 if (newValue != null)
200 if (null != instance.Style?.Buttons?.Background)
202 instance.Style.Buttons.Background.ResourceUrl = (string)newValue;
203 instance.UpdateButton();
207 defaultValueCreator: (bindable) =>
209 var instance = (Popup)bindable;
210 return instance.Style.Buttons?.Background?.ResourceUrl?.All;
213 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
214 [EditorBrowsable(EditorBrowsableState.Never)]
215 public static readonly BindableProperty ButtonBackgroundBorderProperty = BindableProperty.Create("ButtonBackgroundBorder", typeof(Rectangle), typeof(Popup), new Rectangle(0, 0, 0, 0), propertyChanged: (bindable, oldValue, newValue) =>
217 var instance = (Popup)bindable;
218 if (newValue != null)
220 if (null != instance.Style?.Buttons?.Background)
222 instance.Style.Buttons.Background.Border = (Rectangle)newValue;
223 instance.UpdateButton();
227 defaultValueCreator: (bindable) =>
229 var instance = (Popup)bindable;
230 return instance.Style.Buttons?.Background?.Border?.All;
233 private TextLabel titleText;
234 private List<Button> buttonList;
235 private List<string> buttonTextList = new List<string>();
237 private int buttonCount = 0;
240 /// Creates a new instance of a Popup.
242 /// <since_tizen> 6 </since_tizen>
243 public Popup() : base()
249 /// Creates a new instance of a Popup with style.
251 /// <param name="style">Create Popup by special style defined in UX.</param>
252 /// <since_tizen> 6 </since_tizen>
253 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
254 [EditorBrowsable(EditorBrowsableState.Never)]
255 public Popup(string style) : base(style)
261 /// Creates a new instance of a Popup with attributes.
263 /// <param name="attributes">Create Popup by attributes customized by user.</param>
264 /// <since_tizen> 6 </since_tizen>
265 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
266 [EditorBrowsable(EditorBrowsableState.Never)]
267 public Popup(PopupStyle attributes) : base(attributes)
273 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
275 /// <since_tizen> 6 </since_tizen>
276 public event EventHandler<ButtonClickEventArgs> PopupButtonClickEvent;
278 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
279 [EditorBrowsable(EditorBrowsableState.Never)]
280 public new PopupStyle Style => ViewStyle as PopupStyle;
283 /// Title text string in Popup.
285 /// <since_tizen> 6 </since_tizen>
286 public string TitleText
290 return Style?.Title?.Text?.All;
294 if (null != Style?.Title)
296 Style.Title.Text = value;
302 /// Title text point size in Popup.
304 /// <since_tizen> 6 </since_tizen>
305 public float TitlePointSize
309 return Style?.Title?.PointSize?.All ?? 0;
313 if (null != Style?.Title)
315 Style.Title.PointSize = value;
321 /// Title text color in Popup.
323 /// <since_tizen> 6 </since_tizen>
324 public Color TitleTextColor
328 return Style?.Title?.TextColor?.All;
332 if (null != Style?.Title)
334 Style.Title.TextColor = value;
340 /// Title text horizontal alignment in Popup.
342 /// <since_tizen> 6 </since_tizen>
343 public HorizontalAlignment TitleTextHorizontalAlignment
347 return Style?.Title?.HorizontalAlignment ?? HorizontalAlignment.Center;
351 Style.Title.HorizontalAlignment = value;
356 /// Title text's position in Popup.
358 /// <since_tizen> 6 </since_tizen>
359 public Position TitleTextPosition
363 return Style?.Title?.Position ?? new Position(0, 0, 0);
367 Style.Title.Position = value;
372 /// Title text's height in Popup.
374 /// <since_tizen> 6 </since_tizen>
375 public int TitleHeight
379 return (int)(Style?.Title?.Size?.Height ?? 0);
383 Style.Title.Size.Height = value;
388 /// Content view in Popup, only can be gotten.
390 /// <since_tizen> 6 </since_tizen>
391 public View ContentView
398 /// Button count in Popup.
400 /// <since_tizen> 6 </since_tizen>
401 public int ButtonCount
405 return (int)GetValue(ButtonCountProperty);
409 SetValue(ButtonCountProperty, value);
414 /// Shadow offset in Popup, including left, right, up and bottom offset.
416 /// <since_tizen> 6 </since_tizen>
417 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
418 [EditorBrowsable(EditorBrowsableState.Never)]
419 public Vector4 ShadowOffset
423 return (Vector4)GetValue(ShadowOffsetProperty);
427 SetValue(ShadowOffsetProperty, value);
432 /// Button height in Popup.
434 /// <since_tizen> 6 </since_tizen>
435 public int ButtonHeight
439 return (int)GetValue(ButtonHeightProperty);
443 SetValue(ButtonHeightProperty, value);
448 /// Button text point size in Popup.
450 /// <since_tizen> 6 </since_tizen>
451 public float ButtonTextPointSize
455 return (float)GetValue(ButtonTextPointSizeProperty);
459 SetValue(ButtonTextPointSizeProperty, value);
464 /// Button text font family in Popup.
466 /// <since_tizen> 6 </since_tizen>
467 public string ButtonFontFamily
471 return (string)GetValue(ButtonFontFamilyProperty);
475 SetValue(ButtonFontFamilyProperty, value);
480 /// Button text color in Popup.
482 /// <since_tizen> 6 </since_tizen>
483 public Color ButtonTextColor
487 return (Color)GetValue(ButtonTextColorProperty);
491 SetValue(ButtonTextColorProperty, value);
496 /// Button overlay background color selector in Popup.
498 /// <since_tizen> 6 </since_tizen>
499 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
500 [EditorBrowsable(EditorBrowsableState.Never)]
501 public Selector<Color> ButtonOverLayBackgroundColorSelector
505 return (Selector<Color>)GetValue(ButtonOverLayBackgroundColorSelectorProperty);
509 SetValue(ButtonOverLayBackgroundColorSelectorProperty, value);
514 /// Button text horizontal alignment in Popup.
516 /// <since_tizen> 6 </since_tizen>
517 public HorizontalAlignment ButtonTextAlignment
521 return (HorizontalAlignment)GetValue(ButtonTextAlignmentProperty);
525 SetValue(ButtonTextAlignmentProperty, value);
530 /// Button background image's resource url in Popup.
532 /// <since_tizen> 6 </since_tizen>
533 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
534 [EditorBrowsable(EditorBrowsableState.Never)]
535 public string ButtonBackgroundImageURL
539 return (string)GetValue(ButtonBackgroundProperty);
543 SetValue(ButtonBackgroundProperty, value);
548 /// Button background image's border in Popup.
550 /// <since_tizen> 6 </since_tizen>
551 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
552 [EditorBrowsable(EditorBrowsableState.Never)]
553 public Rectangle ButtonBackgroundImageBorder
558 return (Rectangle)GetValue(ButtonBackgroundBorderProperty);
562 SetValue(ButtonBackgroundBorderProperty, value);
566 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
567 [EditorBrowsable(EditorBrowsableState.Never)]
568 public new Size2D Size2D
582 /// Set button text by index.
584 /// <param name="index">Button index.</param>
585 /// <param name="text">Button text string.</param>
586 /// <since_tizen> 6 </since_tizen>
587 public void SetButtonText(int index, string text)
589 if(index < 0 && index >= buttonCount)
593 if(buttonTextList.Count < index + 1)
595 for (int i = buttonTextList.Count; i < index + 1; i++)
597 buttonTextList.Add("");
600 buttonTextList[index] = text;
605 /// Dispose Popup and all children on it.
607 /// <param name="type">Dispose type.</param>
608 /// <since_tizen> 6 </since_tizen>
609 protected override void Dispose(DisposeTypes type)
616 if (type == DisposeTypes.Explicit)
618 if (titleText != null)
624 if (ContentView != null)
627 ContentView.Dispose();
630 if (buttonList != null)
632 foreach(Button btn in buttonList)
644 /// Focus gained callback.
646 /// <since_tizen> 6 </since_tizen>
647 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
648 [EditorBrowsable(EditorBrowsableState.Never)]
649 public override void OnFocusGained()
651 base.OnFocusGained();
655 /// Focus lost callback.
657 /// <since_tizen> 6 </since_tizen>
658 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
659 [EditorBrowsable(EditorBrowsableState.Never)]
660 public override void OnFocusLost()
665 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
666 [EditorBrowsable(EditorBrowsableState.Never)]
667 public override void ApplyStyle(ViewStyle viewStyle)
669 base.ApplyStyle(viewStyle);
671 PopupStyle popupStyle = viewStyle as PopupStyle;
673 if (null != popupStyle)
675 if (null == titleText)
677 titleText = new TextLabel();
681 titleText.ApplyStyle(Style.Title);
686 /// Get Popup attribues.
688 /// <since_tizen> 6 </since_tizen>
689 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
690 [EditorBrowsable(EditorBrowsableState.Never)]
691 protected override ViewStyle GetViewStyle()
693 return new PopupStyle();
697 /// Theme change callback when theme is changed, this callback will be trigger.
699 /// <since_tizen> 6 </since_tizen>
700 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
701 [EditorBrowsable(EditorBrowsableState.Never)]
702 protected override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
704 PopupStyle tempAttributes = StyleManager.Instance.GetAttributes(style) as PopupStyle;
705 if (tempAttributes != null)
707 Style.CopyFrom(tempAttributes);
712 private void Initialize()
714 LeaveRequired = true;
717 ContentView = new View()
719 ParentOrigin = Tizen.NUI.ParentOrigin.TopLeft,
720 PivotPoint = Tizen.NUI.PivotPoint.TopLeft,
721 PositionUsesPivotPoint = true
724 ContentView.RaiseToTop();
727 if (null == titleText)
729 titleText = new TextLabel();
733 buttonList = new List<Button>();
736 private void UpdateButton()
738 if (buttonCount <= 0) return;
739 if (null == buttonTextList || buttonTextList.Count != buttonCount) return;
741 if (null != buttonList)
743 foreach (Button btn in buttonList)
747 btn.ClickEvent -= ButtonClickEvent;
755 int sizeWidth = Size2D?.Width ?? 0;
756 int buttonWidth = sizeWidth / buttonCount;
757 int buttonHeight = (int)(Style?.Buttons?.Size?.Height ?? 0);
758 for (int i = 0; i < buttonCount; i++)
760 Button btn = new Button(Style?.Buttons);
761 btn.Size2D = new Size2D(buttonWidth, buttonHeight);
762 btn.Style.Text.Text = buttonTextList[i];
763 btn.ClickEvent += ButtonClickEvent;
770 if (null != buttonList && buttonList.Count > 0)
772 if (LayoutDirection == ViewLayoutDirectionType.RTL)
774 for (int i = buttonList.Count - 1; i >= 0; i--)
776 buttonList[i].PositionX = pos;
777 pos += buttonList[i].Size2D.Width;
782 for (int i = 0; i < buttonList.Count; i++)
784 buttonList[i].PositionX = pos;
785 pos += buttonList[i].Size2D.Width;
793 private void ButtonClickEvent(object sender, Button.ClickEventArgs e)
795 if (PopupButtonClickEvent != null && buttonList != null)
797 Button button = sender as Button;
798 for (int i = 0; i < buttonList.Count; i++)
800 if(button == buttonList[i])
802 ButtonClickEventArgs args = new ButtonClickEventArgs();
803 args.ButtonIndex = i;
804 PopupButtonClickEvent(this, args);
809 private void UpdateShadow()
811 if (Style.ShadowOffset == null) return;
814 if (Style.Shadow != null)
816 w = (int)(Size2D.Width + Style.ShadowOffset.W + Style.ShadowOffset.X);
817 h = (int)(Size2D.Height + Style.ShadowOffset.Y + Style.ShadowOffset.Z);
819 shadowImage.Size2D = new Size2D(w, h);
823 private void UpdateTitle()
832 if (Style.Title != null)
834 if (titleText.Text != null && titleText.Text != "")
836 Style.Title.Text = new Selector<string> { All = titleText.Text };
837 w = (int)(Size2D.Width - titleText.PositionX * 2);
839 if (Style.Title.Size != null)
841 titleH = (int)titleText.Size.Height;
843 titleText.Size2D = new Size2D(w, titleH);
847 titleText.Size2D = new Size2D(0, 0);
851 if (titleText != null)
853 if (LayoutDirection == ViewLayoutDirectionType.RTL)
855 if (Style.Title != null)
857 Style.Title.HorizontalAlignment = HorizontalAlignment.End;
859 titleText.HorizontalAlignment = HorizontalAlignment.End;
861 else if (LayoutDirection == ViewLayoutDirectionType.LTR)
863 if (Style.Title != null)
865 Style.Title.HorizontalAlignment = HorizontalAlignment.Begin;
867 titleText.HorizontalAlignment = HorizontalAlignment.Begin;
874 private void UpdateContentView()
879 if (Style.Title.Size != null)
881 titleH = (int)titleText.Size.Height;
883 if (Style.Title.Position != null)
885 titleX = (int)Style.Title.Position.X;
886 titleY = (int)Style.Title.Position.Y;
888 int buttonH = (int)Style.Buttons.Size.Height;
890 ContentView.Size2D = new Size2D(Size2D.Width - titleX * 2, Size2D.Height - titleY - titleH - buttonH);
891 ContentView.Position2D = new Position2D(titleX, titleY + titleH);
892 ContentView.RaiseToTop();
896 /// ButtonClickEventArgs is a class to record button click event arguments which will sent to user.
898 /// <since_tizen> 6 </since_tizen>
899 public class ButtonClickEventArgs : EventArgs
901 /// <summary> Button index which is clicked in Popup </summary>
902 /// <since_tizen> 6 </since_tizen>
903 public int ButtonIndex;