Add Dialog 33/118033/13
authorSeunghyun Choi <sh4682.choi@samsung.com>
Wed, 8 Mar 2017 10:13:34 +0000 (19:13 +0900)
committerSeunghyun Choi <sh4682.choi@samsung.com>
Thu, 23 Mar 2017 04:33:44 +0000 (13:33 +0900)
 - This is RFC 22.

Change-Id: I666cc946c90ecd25c3985870006825871f4f22a6
Signed-off-by: Seunghyun Choi <sh4682.choi@samsung.com>
Tizen.Xamarin.Forms.Extension.Renderer/DialogImplementation.cs [new file with mode: 0644]
Tizen.Xamarin.Forms.Extension.Renderer/Tizen.Xamarin.Forms.Extension.Renderer.csproj
Tizen.Xamarin.Forms.Extension/Dialog.cs [new file with mode: 0644]
Tizen.Xamarin.Forms.Extension/IDialog.cs [new file with mode: 0644]
Tizen.Xamarin.Forms.Extension/Tizen.Xamarin.Forms.Extension.csproj

diff --git a/Tizen.Xamarin.Forms.Extension.Renderer/DialogImplementation.cs b/Tizen.Xamarin.Forms.Extension.Renderer/DialogImplementation.cs
new file mode 100644 (file)
index 0000000..36f60f7
--- /dev/null
@@ -0,0 +1,378 @@
+using System;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using Xamarin.Forms;
+using Xamarin.Forms.Platform.Tizen;
+using TForms = Xamarin.Forms.Platform.Tizen.Forms;
+using EPopup = ElmSharp.Popup;
+using Tizen.Xamarin.Forms.Extension.Renderer;
+
+[assembly: Dependency(typeof(DialogImplementation))]
+
+namespace Tizen.Xamarin.Forms.Extension.Renderer
+{
+    class DialogImplementation : IDialog, INotifyPropertyChanged, IDisposable
+    {
+        EPopup _control;
+        View _content;
+        Button _positive;
+        Button _neutral;
+        Button _negative;
+        string _title;
+        string _subtitle;
+
+        bool _isDisposed = false;
+
+        bool _isNullable = false;
+        ElmSharp.Button _nativePositive;
+        ElmSharp.Button _nativeNeutral;
+        ElmSharp.Button _nativeNegative;
+        ElmSharp.EvasObject _nativeContent;
+
+        public event EventHandler Dismissed;
+
+        public event EventHandler OutsideClicked;
+
+        public event EventHandler Shown;
+
+        public event EventHandler BackButtonPressed;
+
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        public DialogImplementation()
+        {
+            _control = new EPopup(TForms.Context.MainWindow);
+
+            _control.ShowAnimationFinished += ShowAnimationFinishedHandler;
+            _control.Dismissed += DismissedHandler;
+            _control.OutsideClicked += OutsideClickedHandler;
+            _control.KeyUp += BackButtonPressedHandler;
+
+            PropertyChanged += PropertyChangedHandler;
+        }
+
+        ~DialogImplementation()
+        {
+            Dispose(false);
+        }
+
+        public View Content
+        {
+            get
+            {
+                return _content;
+            }
+            set
+            {
+                _content = value;
+                OnPropertyChanged();
+            }
+        }
+
+        public Button Positive
+        {
+            get
+            {
+                return _positive;
+            }
+            set
+            {
+                _positive = value;
+                OnPropertyChanged();
+            }
+        }
+
+        public Button Neutral
+        {
+            get
+            {
+                return _neutral;
+            }
+            set
+            {
+                _neutral = value;
+                OnPropertyChanged();
+            }
+        }
+
+        public Button Negative
+        {
+            get
+            {
+                return _negative;
+            }
+            set
+            {
+                _negative = value;
+                OnPropertyChanged();
+            }
+        }
+
+        public string Title
+        {
+            get
+            {
+                return _title;
+            }
+            set
+            {
+                _title = value;
+                OnPropertyChanged();
+            }
+        }
+
+        public string Subtitle
+        {
+            get
+            {
+                return _subtitle;
+            }
+            set
+            {
+                _subtitle = value;
+                OnPropertyChanged();
+            }
+        }
+
+        public void Show()
+        {
+            _control.Show();
+        }
+
+        public void Hide()
+        {
+            _control.Hide();
+        }
+
+        public void Dismiss()
+        {
+            _control.Dismiss();
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (_isDisposed)
+                return;
+
+            if (disposing)
+            {
+                PropertyChanged -= PropertyChangedHandler;
+
+                if (_nativePositive != null)
+                {
+                    _nativePositive.Unrealize();
+                    _nativePositive = null;
+                }
+                if (_nativeNeutral != null)
+                {
+                    _nativeNeutral.Unrealize();
+                    _nativeNeutral = null;
+                }
+                if (_nativeNegative != null)
+                {
+                    _nativeNegative.Unrealize();
+                    _nativeNegative = null;
+                }
+                if (_nativeContent != null)
+                {
+                    _nativeContent.Unrealize();
+                    _nativeContent = null;
+                }
+
+                if (_control != null)
+                {
+                    _control.ShowAnimationFinished -= ShowAnimationFinishedHandler;
+                    _control.Dismissed -= DismissedHandler;
+                    _control.OutsideClicked -= OutsideClickedHandler;
+                    _control.KeyUp -= BackButtonPressedHandler;
+
+                    _control.Unrealize();
+                    _control = null;
+                }
+            }
+
+            _isDisposed = true;
+        }
+
+        void ShowAnimationFinishedHandler(object sender, EventArgs e)
+        {
+            Shown?.Invoke(this, EventArgs.Empty);
+            GrabBackkey();
+        }
+
+        void DismissedHandler(object sender, EventArgs e)
+        {
+            Dismissed?.Invoke(this, EventArgs.Empty);
+            UngrabBackKey();
+        }
+
+        void OutsideClickedHandler(object sender, EventArgs e)
+        {
+            OutsideClicked?.Invoke(this, EventArgs.Empty);
+        }
+
+        void BackButtonPressedHandler(object sender, ElmSharp.EvasKeyEventArgs e)
+        {
+            if (e.KeyName == ElmSharp.EvasKeyEventArgs.PlatformBackButtonName)
+            {
+                BackButtonPressed?.Invoke(this, EventArgs.Empty);
+            }
+        }
+
+        void PropertyChangedHandler(object sender, PropertyChangedEventArgs e)
+        {
+            if (e.PropertyName == Dialog.ContentProperty.PropertyName)
+            {
+                UpdateContent();
+            }
+            else if (e.PropertyName == Dialog.PositiveProperty.PropertyName)
+            {
+                UpdatePositive();
+            }
+            else if (e.PropertyName == Dialog.NeutralProperty.PropertyName)
+            {
+                UpdateNeutral();
+            }
+            else if (e.PropertyName == Dialog.NegativeProperty.PropertyName)
+            {
+                UpdateNegative();
+            }
+            else if (e.PropertyName == Dialog.TitleProperty.PropertyName)
+            {
+                UpdateTitle();
+            }
+            else if (e.PropertyName == Dialog.SubtitleProperty.PropertyName)
+            {
+                UpdateSubtitle();
+            }
+        }
+
+        void OnPropertyChanged([CallerMemberName] string propertyName = null)
+        {
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+        }
+
+        void UpdateContent()
+        {
+            _isNullable = _nativeContent != null ? true : false;
+
+            _nativeContent?.Hide();
+
+            View contentView = null;
+
+            if (Content.GetType() == typeof(ScrollView))
+            {
+                contentView = new StackLayout
+                {
+                    Children =
+                    {
+                        Content
+                    }
+                };
+            }
+            else
+            {
+                contentView = Content;
+            }
+
+            if (contentView != null)
+            {
+                contentView.Parent = Application.Current.MainPage;
+                _nativeContent = Platform.GetOrCreateRenderer(contentView).NativeView;
+
+                var sizeRequest = contentView.Measure(TForms.Context.MainWindow.ScreenSize.Width, TForms.Context.MainWindow.ScreenSize.Height).Request.ToPixel();
+
+                _nativeContent.MinimumHeight = sizeRequest.Height;
+            }
+            else
+            {
+                _nativeContent = null;
+            }
+
+            _control.SetPartContent("default", _nativeContent, _isNullable);
+        }
+
+        void UpdatePositive()
+        {
+            _isNullable = _nativePositive != null ? true : false;
+
+            _nativePositive?.Hide();
+
+            if (Positive != null)
+            {
+                _nativePositive = (ElmSharp.Button)Platform.GetOrCreateRenderer(Positive).NativeView;
+                _nativePositive.Style = "bottom";
+            }
+            else
+            {
+                _nativePositive = null;
+            }
+
+            _control.SetPartContent("button1", _nativePositive, _isNullable);
+        }
+
+        void UpdateNeutral()
+        {
+            _isNullable = _nativeNeutral != null ? true : false;
+
+            _nativeNeutral?.Hide();
+
+            if (Neutral != null)
+            {
+                _nativeNeutral = (ElmSharp.Button)Platform.GetOrCreateRenderer(Neutral).NativeView;
+                _nativeNeutral.Style = "bottom";
+            }
+            else
+            {
+                _nativeNeutral = null;
+            }
+
+            _control.SetPartContent("button2", _nativeNeutral, _isNullable);
+        }
+
+        void UpdateNegative()
+        {
+            _isNullable = _nativeNegative != null ? true : false;
+
+            _nativeNegative?.Hide();
+
+            if (Negative != null)
+            {
+                _nativeNegative = (ElmSharp.Button)Platform.GetOrCreateRenderer(Negative).NativeView;
+                _nativeNegative.Style = "bottom";
+            }
+            else
+            {
+                _nativeNegative = null;
+            }
+
+            _control.SetPartContent("button3", _nativeNegative, _isNullable);
+        }
+
+        void UpdateTitle()
+        {
+            _control.SetPartText("title,text", Title);
+        }
+
+        void UpdateSubtitle()
+        {
+            _control.SetPartText("subtitle,text", Subtitle);
+        }
+
+        void GrabBackkey()
+        {
+            _control.KeyGrab(ElmSharp.EvasKeyEventArgs.PlatformBackButtonName, true);
+        }
+
+        void UngrabBackKey()
+        {
+            _control.KeyUngrab(ElmSharp.EvasKeyEventArgs.PlatformBackButtonName);
+        }
+    }
+}
\ No newline at end of file
index 6fb1056..51d1927 100755 (executable)
@@ -45,6 +45,7 @@
     <Compile Include="Cells\GridViewTypeCellRenderer.cs" />\r
     <Compile Include="Cells\MultilineCellRenderer.cs" />\r
     <Compile Include="Cells\TypeCellRenderer.cs" />\r
+    <Compile Include="DialogImplementation.cs" />\r
     <Compile Include="LongTapGestureHandler.cs" />\r
     <Compile Include="FloatingButtonImplementation.cs" />\r
     <Compile Include="DateTimeViewRenderer.cs" />\r
@@ -83,4 +84,4 @@
     <_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory)</_FullFrameworkReferenceAssemblyPaths>\r
     <AutoUnifyAssemblyReferences>true</AutoUnifyAssemblyReferences>\r
   </PropertyGroup>\r
-</Project>
+</Project>\r
diff --git a/Tizen.Xamarin.Forms.Extension/Dialog.cs b/Tizen.Xamarin.Forms.Extension/Dialog.cs
new file mode 100644 (file)
index 0000000..ddf8bbe
--- /dev/null
@@ -0,0 +1,181 @@
+using System;
+using Xamarin.Forms;
+
+namespace Tizen.Xamarin.Forms.Extension
+{
+    /// <summary>
+    /// The dialog widget displays its content with a particular direction.
+    /// </summary>
+    /// <example>
+    /// <code>
+    /// var dialog = new Dialog();
+    /// dialog.Direction = DialogDirection.Bottom;
+    /// dialog.Title = "Dialog"
+    ///
+    /// var positive = new Button()
+    /// {
+    ///     Text = "OK"
+    /// }
+    /// var negative = new Button()
+    /// {
+    ///     Text = "Cancel"
+    /// }
+    /// negative.Clicked += (s,e)=>
+    /// {
+    ///     dialog.Dismiss();
+    /// }
+    ///
+    /// dialog.Positive = positive;
+    /// dialog.Negative = negative;
+    ///
+    /// var label = new Label()
+    /// {
+    ///     Text = "New Dialog"
+    /// }
+    ///
+    /// dialog.Content = label;
+    ///
+    /// dialog.Show();
+    ///
+    /// </code>
+    /// </example>
+    public class Dialog : BindableObject
+    {
+        public static readonly BindableProperty ContentProperty = BindableProperty.Create(nameof(Content), typeof(View), typeof(Dialog), null);
+
+        public static readonly BindableProperty PositiveProperty = BindableProperty.Create(nameof(Positive), typeof(Button), typeof(Dialog), null);
+
+        public static readonly BindableProperty NeutralProperty = BindableProperty.Create(nameof(Neutral), typeof(Button), typeof(Dialog), null);
+
+        public static readonly BindableProperty NegativeProperty = BindableProperty.Create(nameof(Negative), typeof(Button), typeof(Dialog), null);
+
+        public static readonly BindableProperty TitleProperty = BindableProperty.Create(nameof(Title), typeof(string), typeof(Dialog), null);
+
+        public static readonly BindableProperty SubtitleProperty = BindableProperty.Create(nameof(Subtitle), typeof(string), typeof(Dialog), null);
+
+        IDialog _dialog = null;
+
+        public event EventHandler Dismissed;
+
+        public event EventHandler OutsideClicked;
+
+        public event EventHandler Shown;
+
+        public event EventHandler BackButtonPressed;
+
+        public Dialog()
+        {
+            _dialog = DependencyService.Get<IDialog>(DependencyFetchTarget.NewInstance);
+            if (_dialog == null)
+            {
+                throw new Exception("Object reference not set to an instance of a Dialog.");
+            }
+
+            _dialog.Dismissed += (s, e) =>
+            {
+                Dismissed?.Invoke(this, EventArgs.Empty);
+            };
+
+            _dialog.OutsideClicked += (s, e) =>
+            {
+                OutsideClicked?.Invoke(this, EventArgs.Empty);
+            };
+
+            _dialog.Shown += (s, e) =>
+            {
+                Shown?.Invoke(this, EventArgs.Empty);
+            };
+
+            _dialog.BackButtonPressed += (s, e) =>
+            {
+                BackButtonPressed?.Invoke(this, EventArgs.Empty);
+            };
+
+            SetBinding(ContentProperty, new Binding(nameof(Content), mode: BindingMode.TwoWay, source: _dialog));
+            SetBinding(PositiveProperty, new Binding(nameof(Positive), mode: BindingMode.TwoWay, source: _dialog));
+            SetBinding(NeutralProperty, new Binding(nameof(Neutral), mode: BindingMode.TwoWay, source: _dialog));
+            SetBinding(NegativeProperty, new Binding(nameof(Negative), mode: BindingMode.TwoWay, source: _dialog));
+            SetBinding(TitleProperty, new Binding(nameof(Title), mode: BindingMode.TwoWay, source: _dialog));
+            SetBinding(SubtitleProperty, new Binding(nameof(Subtitle), mode: BindingMode.TwoWay, source: _dialog));
+        }
+
+        /// <summary>
+        /// Gets or sets content view of the Dialog.
+        /// </summary>
+        public View Content
+        {
+            get { return (View)GetValue(ContentProperty); }
+            set { SetValue(ContentProperty, value); }
+        }
+
+        /// <summary>
+        /// Gets or sets positive button of the Dialog.
+        /// </summary>
+        public Button Positive
+        {
+            get { return (Button)GetValue(PositiveProperty); }
+            set { SetValue(PositiveProperty, value); }
+        }
+
+        /// <summary>
+        /// Gets or sets neutral button of the Dialog.
+        /// </summary>
+        public Button Neutral
+        {
+            get { return (Button)GetValue(NeutralProperty); }
+            set { SetValue(NeutralProperty, value); }
+        }
+
+        /// <summary>
+        /// Gets or sets negative button of the Dialog.
+        /// </summary>
+        public Button Negative
+        {
+            get { return (Button)GetValue(NegativeProperty); }
+            set { SetValue(NegativeProperty, value); }
+        }
+
+        /// <summary>
+        /// Gets or sets title of the Dialog.
+        /// </summary>
+        public string Title
+        {
+            get { return (string)GetValue(TitleProperty); }
+            set { SetValue(TitleProperty, value); }
+        }
+
+        /// <summary>
+        /// Gets or sets subtitle of the Dialog.
+        /// When Title property value is null, subtitle does not displayed.
+        /// </summary>
+        public string Subtitle
+        {
+            get { return (string)GetValue(SubtitleProperty); }
+            set { SetValue(SubtitleProperty, value); }
+        }
+
+        /// <summary>
+        /// Shows the Dialog.
+        /// </summary>
+        public void Show()
+        {
+            _dialog.Show();
+        }
+
+        /// <summary>
+        /// Hides the Dialog.
+        /// </summary>
+        public void Hide()
+        {
+            _dialog.Hide();
+        }
+
+        /// <summary>
+        /// Dismisses the Dialog.
+        /// </summary>
+        public void Dismiss()
+        {
+            _dialog.Dismiss();
+        }
+    }
+}
\ No newline at end of file
diff --git a/Tizen.Xamarin.Forms.Extension/IDialog.cs b/Tizen.Xamarin.Forms.Extension/IDialog.cs
new file mode 100644 (file)
index 0000000..f450550
--- /dev/null
@@ -0,0 +1,34 @@
+using System;
+using Xamarin.Forms;
+
+namespace Tizen.Xamarin.Forms.Extension
+{
+    internal interface IDialog
+    {
+        event EventHandler Dismissed;
+
+        event EventHandler OutsideClicked;
+
+        event EventHandler Shown;
+
+        event EventHandler BackButtonPressed;
+
+        View Content { get; set; }
+
+        Button Positive { get; set; }
+
+        Button Neutral { get; set; }
+
+        Button Negative { get; set; }
+
+        string Title { get; set; }
+
+        string Subtitle { get; set; }
+
+        void Show();
+
+        void Hide();
+
+        void Dismiss();
+    }
+}
\ No newline at end of file
index 21e35e2..6ab4ac5 100644 (file)
@@ -66,6 +66,7 @@
     <Compile Include="Cells\BaseTypeCell.cs" />\r
     <Compile Include="Cells\MultilineCell.cs" />\r
     <Compile Include="DateTimeView.cs" />\r
+    <Compile Include="Dialog.cs" />\r
     <Compile Include="EnumerableExtensions.cs" />\r
     <Compile Include="FloatingButtonItem.cs" />\r
     <Compile Include="FloatingButtonMovablePosition.cs" />\r
@@ -75,6 +76,7 @@
     <Compile Include="GridView.cs" />\r
     <Compile Include="GridViewEnums.cs" />\r
     <Compile Include="GridViewEventArgs.cs" />\r
+    <Compile Include="IDialog.cs" />\r
     <Compile Include="ILongTapGestureController.cs" />\r
     <Compile Include="ItemsView.cs" />\r
     <Compile Include="IToast.cs" />\r
   <Target Name="AfterBuild">\r
   </Target>\r
   -->\r
-</Project>
+</Project>\r