- This is RFC 22.
Change-Id: I666cc946c90ecd25c3985870006825871f4f22a6
Signed-off-by: Seunghyun Choi <sh4682.choi@samsung.com>
--- /dev/null
+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
<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
<_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory)</_FullFrameworkReferenceAssemblyPaths>\r
<AutoUnifyAssemblyReferences>true</AutoUnifyAssemblyReferences>\r
</PropertyGroup>\r
-</Project>
+</Project>\r
--- /dev/null
+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
--- /dev/null
+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
<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
<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