From ed21ee8189dcb8d54e8aeefcbd60ec41c35f6aab Mon Sep 17 00:00:00 2001 From: rabbitism Date: Sun, 4 Feb 2024 02:07:45 +0800 Subject: [PATCH 01/14] feat: pre job: change events to routed events. --- demo/Ursa.Demo/Pages/IconButtonDemo.axaml | 2 +- .../Common/{IconPlacement.cs => Position.cs} | 2 +- .../Controls/Dialog/DefaultDialogControl.cs | 1 + src/Ursa/Controls/Dialog/DialogControl.cs | 44 ++++++++---- .../Dialog/DialogLayerChangeEventArgs.cs | 9 ++- src/Ursa/Controls/Dialog/OverlayDialogHost.cs | 12 ++-- src/Ursa/Controls/Drawer/Drawer.cs | 6 ++ src/Ursa/Controls/Drawer/DrawerControl.cs | 69 +++++++++++++++++++ src/Ursa/Controls/IconButton.cs | 18 ++--- src/Ursa/EventArgs/ResultEventArgs.cs | 18 +++++ 10 files changed, 148 insertions(+), 33 deletions(-) rename src/Ursa/Common/{IconPlacement.cs => Position.cs} (73%) create mode 100644 src/Ursa/Controls/Drawer/Drawer.cs create mode 100644 src/Ursa/Controls/Drawer/DrawerControl.cs create mode 100644 src/Ursa/EventArgs/ResultEventArgs.cs diff --git a/demo/Ursa.Demo/Pages/IconButtonDemo.axaml b/demo/Ursa.Demo/Pages/IconButtonDemo.axaml index cde464e..59c0099 100644 --- a/demo/Ursa.Demo/Pages/IconButtonDemo.axaml +++ b/demo/Ursa.Demo/Pages/IconButtonDemo.axaml @@ -14,7 +14,7 @@ - + LayerChangedEvent = RoutedEvent.Register( + nameof(LayerChanged), RoutingStrategies.Bubble); + public event EventHandler LayerChanged + { + add => AddHandler(LayerChangedEvent, value); + remove => RemoveHandler(LayerChangedEvent, value); + } - public event EventHandler? LayerChanged; - public event EventHandler? DialogControlClosing; + public static readonly RoutedEvent ClosedEvent = RoutedEvent.Register( + nameof(Closed), RoutingStrategies.Bubble); + + public event EventHandler Closed + { + add => AddHandler(ClosedEvent, value); + remove => RemoveHandler(ClosedEvent, value); + } static DialogControl() { @@ -45,9 +60,8 @@ public class DialogControl: ContentControl { if (args.OldValue.Value is IDialogContext oldContext) { - oldContext.RequestClose-= OnContextRequestClose; + oldContext.RequestClose -= OnContextRequestClose; } - if (args.NewValue.Value is IDialogContext newContext) { newContext.RequestClose += OnContextRequestClose; @@ -99,21 +113,21 @@ public class DialogControl: ContentControl { Dispatcher.UIThread.Invoke(CloseDialog); }); - void OnCloseHandler(object sender, object? args) + + void OnCloseHandler(object sender, ResultEventArgs? args) { - if (args is T result) + if (args?.Result is T result) { tcs.SetResult(result); - DialogControlClosing-= OnCloseHandler; } else { - tcs.SetResult(default(T)); - DialogControlClosing-= OnCloseHandler; + tcs.SetResult(default); } + RemoveHandler(ClosedEvent, OnCloseHandler); } - this.DialogControlClosing += OnCloseHandler; + AddHandler(ClosedEvent, OnCloseHandler); return tcs.Task; } @@ -121,7 +135,7 @@ public class DialogControl: ContentControl private void OnContextRequestClose(object sender, object? args) { - DialogControlClosing?.Invoke(this, args); + RaiseEvent(new ResultEventArgs(ClosedEvent, args)); } @@ -129,7 +143,7 @@ public class DialogControl: ContentControl { if (o is DialogLayerChangeType t) { - LayerChanged?.Invoke(this, new DialogLayerChangeEventArgs(t)); + RaiseEvent(new DialogLayerChangeEventArgs(LayerChangedEvent, t)); } } @@ -138,9 +152,9 @@ public class DialogControl: ContentControl /// /// /// - protected internal virtual void OnDialogControlClosing(object sender, object? args) + protected virtual void OnDialogControlClosing(object sender, object? args) { - DialogControlClosing?.Invoke(this, args); + RaiseEvent(new ResultEventArgs(ClosedEvent, args)); } internal void SetAsModal(bool modal) @@ -161,7 +175,7 @@ public class DialogControl: ContentControl } else { - DialogControlClosing?.Invoke(this, null); + OnDialogControlClosing(this, null); } } } \ No newline at end of file diff --git a/src/Ursa/Controls/Dialog/DialogLayerChangeEventArgs.cs b/src/Ursa/Controls/Dialog/DialogLayerChangeEventArgs.cs index 12ec4ee..de0dfa9 100644 --- a/src/Ursa/Controls/Dialog/DialogLayerChangeEventArgs.cs +++ b/src/Ursa/Controls/Dialog/DialogLayerChangeEventArgs.cs @@ -1,12 +1,19 @@ +using Avalonia.Interactivity; + namespace Ursa.Controls; -public class DialogLayerChangeEventArgs +public class DialogLayerChangeEventArgs: RoutedEventArgs { public DialogLayerChangeType ChangeType { get; } + public DialogLayerChangeEventArgs(DialogLayerChangeType type) { ChangeType = type; } + public DialogLayerChangeEventArgs(RoutedEvent routedEvent, DialogLayerChangeType type): base(routedEvent) + { + ChangeType = type; + } } public enum DialogLayerChangeType diff --git a/src/Ursa/Controls/Dialog/OverlayDialogHost.cs b/src/Ursa/Controls/Dialog/OverlayDialogHost.cs index 76a235f..be302db 100644 --- a/src/Ursa/Controls/Dialog/OverlayDialogHost.cs +++ b/src/Ursa/Controls/Dialog/OverlayDialogHost.cs @@ -163,8 +163,8 @@ public class OverlayDialogHost : Canvas control.Measure(this.Bounds.Size); control.Arrange(new Rect(control.DesiredSize)); SetToPosition(control); - control.DialogControlClosing += OnDialogControlClosing; - control.LayerChanged += OnDialogLayerChanged; + control.AddHandler(DialogControl.ClosedEvent, OnDialogControlClosing); + control.AddHandler(DialogControl.LayerChangedEvent, OnDialogLayerChanged); ResetZIndices(); } @@ -173,8 +173,8 @@ public class OverlayDialogHost : Canvas if (sender is DialogControl control) { Children.Remove(control); - control.DialogControlClosing -= OnDialogControlClosing; - control.LayerChanged -= OnDialogLayerChanged; + control.RemoveHandler(DialogControl.ClosedEvent, OnDialogControlClosing); + control.RemoveHandler(DialogControl.LayerChangedEvent, OnDialogLayerChanged); if (_dialogs.Contains(control)) { _dialogs.Remove(control); @@ -217,8 +217,8 @@ public class OverlayDialogHost : Canvas control.Measure(this.Bounds.Size); control.Arrange(new Rect(control.DesiredSize)); SetToPosition(control); - control.DialogControlClosing += OnDialogControlClosing; - control.LayerChanged += OnDialogLayerChanged; + control.AddHandler(DialogControl.ClosedEvent, OnDialogControlClosing); + control.AddHandler(DialogControl.LayerChangedEvent, OnDialogLayerChanged); } // Handle dialog layer change event diff --git a/src/Ursa/Controls/Drawer/Drawer.cs b/src/Ursa/Controls/Drawer/Drawer.cs new file mode 100644 index 0000000..e8b3bcd --- /dev/null +++ b/src/Ursa/Controls/Drawer/Drawer.cs @@ -0,0 +1,6 @@ +namespace Ursa.Controls; + +public static class Drawer +{ + +} \ No newline at end of file diff --git a/src/Ursa/Controls/Drawer/DrawerControl.cs b/src/Ursa/Controls/Drawer/DrawerControl.cs new file mode 100644 index 0000000..31dfa3b --- /dev/null +++ b/src/Ursa/Controls/Drawer/DrawerControl.cs @@ -0,0 +1,69 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Interactivity; +using Avalonia.Threading; +using Ursa.Common; +using Ursa.EventArgs; + +namespace Ursa.Controls; + +public class DrawerControl: ContentControl +{ + public static readonly StyledProperty PositionProperty = AvaloniaProperty.Register( + nameof(Position)); + + public Position Position + { + get => GetValue(PositionProperty); + set => SetValue(PositionProperty, value); + } + + public static readonly StyledProperty IsOpenProperty = AvaloniaProperty.Register( + nameof(IsOpen)); + + public bool IsOpen + { + get => GetValue(IsOpenProperty); + set => SetValue(IsOpenProperty, value); + } + + public static readonly RoutedEvent CloseEvent = RoutedEvent.Register( + "Close", RoutingStrategies.Bubble); + + public event EventHandler Close + { + add => AddHandler(CloseEvent, value); + remove => RemoveHandler(CloseEvent, value); + } + + public Task ShowAsync(CancellationToken? token = default) + { + var tcs = new TaskCompletionSource(); + token?.Register(() => + { + Dispatcher.UIThread.Invoke(CloseDrawer); + }); + + void OnCloseHandler(object sender, ResultEventArgs args) + { + if (args is T result) + { + tcs.SetResult(result); + Close -= OnCloseHandler; + } + else + { + tcs.SetResult(default(T)); + Close -= OnCloseHandler; + } + } + + this.Close += OnCloseHandler; + return tcs.Task; + } + + internal void CloseDrawer() + { + + } +} \ No newline at end of file diff --git a/src/Ursa/Controls/IconButton.cs b/src/Ursa/Controls/IconButton.cs index f4fabda..e5e042a 100644 --- a/src/Ursa/Controls/IconButton.cs +++ b/src/Ursa/Controls/IconButton.cs @@ -44,10 +44,10 @@ public class IconButton: Button set => SetValue(IsLoadingProperty, value); } - public static readonly StyledProperty IconPlacementProperty = AvaloniaProperty.Register( - nameof(IconPlacement), defaultValue: IconPlacement.Left); + public static readonly StyledProperty IconPlacementProperty = AvaloniaProperty.Register( + nameof(IconPlacement), defaultValue: Position.Left); - public IconPlacement IconPlacement + public Position IconPlacement { get => GetValue(IconPlacementProperty); set => SetValue(IconPlacementProperty, value); @@ -55,7 +55,7 @@ public class IconButton: Button static IconButton() { - IconPlacementProperty.Changed.AddClassHandler((o, e) => + IconPlacementProperty.Changed.AddClassHandler((o, e) => { o.SetPlacement(e.NewValue.Value, o.Icon); }); @@ -71,7 +71,7 @@ public class IconButton: Button SetPlacement(IconPlacement, Icon); } - private void SetPlacement(IconPlacement placement, object? icon) + private void SetPlacement(Position placement, object? icon) { if (icon is null) { @@ -83,9 +83,9 @@ public class IconButton: Button return; } PseudoClasses.Set(PC_Empty, false); - PseudoClasses.Set(PC_Left, placement == IconPlacement.Left); - PseudoClasses.Set(PC_Right, placement == IconPlacement.Right); - PseudoClasses.Set(PC_Top, placement == IconPlacement.Top); - PseudoClasses.Set(PC_Bottom, placement == IconPlacement.Bottom); + PseudoClasses.Set(PC_Left, placement == Position.Left); + PseudoClasses.Set(PC_Right, placement == Position.Right); + PseudoClasses.Set(PC_Top, placement == Position.Top); + PseudoClasses.Set(PC_Bottom, placement == Position.Bottom); } } \ No newline at end of file diff --git a/src/Ursa/EventArgs/ResultEventArgs.cs b/src/Ursa/EventArgs/ResultEventArgs.cs new file mode 100644 index 0000000..4a78c08 --- /dev/null +++ b/src/Ursa/EventArgs/ResultEventArgs.cs @@ -0,0 +1,18 @@ +using Avalonia.Interactivity; + +namespace Ursa.EventArgs; + +public class ResultEventArgs: RoutedEventArgs +{ + public object? Result { get; set; } + + public ResultEventArgs(object? result) + { + Result = result; + } + + public ResultEventArgs(RoutedEvent routedEvent, object? result): base(routedEvent) + { + Result = result; + } +} \ No newline at end of file From f3cd4fb74b9cc4215c841d90229b1649752a184c Mon Sep 17 00:00:00 2001 From: rabbitism Date: Sun, 4 Feb 2024 12:32:08 +0800 Subject: [PATCH 02/14] feat: WIP set up interface. --- src/Ursa/Controls/Dialog/DialogControl.cs | 2 +- src/Ursa/Controls/Dialog/OverlayDialogHost.cs | 5 + .../Controls/Drawer/DefaultDrawerControl.cs | 6 ++ src/Ursa/Controls/Drawer/Drawer.cs | 9 +- src/Ursa/Controls/Drawer/DrawerControl.cs | 69 ------------ src/Ursa/Controls/Drawer/DrawerControlBase.cs | 102 ++++++++++++++++++ 6 files changed, 122 insertions(+), 71 deletions(-) create mode 100644 src/Ursa/Controls/Drawer/DefaultDrawerControl.cs delete mode 100644 src/Ursa/Controls/Drawer/DrawerControl.cs create mode 100644 src/Ursa/Controls/Drawer/DrawerControlBase.cs diff --git a/src/Ursa/Controls/Dialog/DialogControl.cs b/src/Ursa/Controls/Dialog/DialogControl.cs index f5138c9..5df18d2 100644 --- a/src/Ursa/Controls/Dialog/DialogControl.cs +++ b/src/Ursa/Controls/Dialog/DialogControl.cs @@ -42,7 +42,7 @@ public class DialogControl: ContentControl remove => RemoveHandler(LayerChangedEvent, value); } - public static readonly RoutedEvent ClosedEvent = RoutedEvent.Register( + public static readonly RoutedEvent ClosedEvent = RoutedEvent.Register( nameof(Closed), RoutingStrategies.Bubble); public event EventHandler Closed diff --git a/src/Ursa/Controls/Dialog/OverlayDialogHost.cs b/src/Ursa/Controls/Dialog/OverlayDialogHost.cs index be302db..cfb43e7 100644 --- a/src/Ursa/Controls/Dialog/OverlayDialogHost.cs +++ b/src/Ursa/Controls/Dialog/OverlayDialogHost.cs @@ -168,6 +168,11 @@ public class OverlayDialogHost : Canvas ResetZIndices(); } + internal void AddDrawer(DrawerControlBase control) + { + + } + private void OnDialogControlClosing(object sender, object? e) { if (sender is DialogControl control) diff --git a/src/Ursa/Controls/Drawer/DefaultDrawerControl.cs b/src/Ursa/Controls/Drawer/DefaultDrawerControl.cs new file mode 100644 index 0000000..c3a937f --- /dev/null +++ b/src/Ursa/Controls/Drawer/DefaultDrawerControl.cs @@ -0,0 +1,6 @@ +namespace Ursa.Controls; + +public class DefaultDrawerControl: DrawerControlBase +{ + +} \ No newline at end of file diff --git a/src/Ursa/Controls/Drawer/Drawer.cs b/src/Ursa/Controls/Drawer/Drawer.cs index e8b3bcd..47469ca 100644 --- a/src/Ursa/Controls/Drawer/Drawer.cs +++ b/src/Ursa/Controls/Drawer/Drawer.cs @@ -2,5 +2,12 @@ public static class Drawer { - + public static Task ShowDialogAsync(TViewModel viewModel) + { + var host = OverlayDialogManager.GetHost(null); + if (host is null) return Task.FromResult(default(TResult)); + var dialog = new DefaultDrawerControl(); + host.AddDrawer(dialog); + return dialog.ShowAsync(); + } } \ No newline at end of file diff --git a/src/Ursa/Controls/Drawer/DrawerControl.cs b/src/Ursa/Controls/Drawer/DrawerControl.cs deleted file mode 100644 index 31dfa3b..0000000 --- a/src/Ursa/Controls/Drawer/DrawerControl.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Avalonia; -using Avalonia.Controls; -using Avalonia.Interactivity; -using Avalonia.Threading; -using Ursa.Common; -using Ursa.EventArgs; - -namespace Ursa.Controls; - -public class DrawerControl: ContentControl -{ - public static readonly StyledProperty PositionProperty = AvaloniaProperty.Register( - nameof(Position)); - - public Position Position - { - get => GetValue(PositionProperty); - set => SetValue(PositionProperty, value); - } - - public static readonly StyledProperty IsOpenProperty = AvaloniaProperty.Register( - nameof(IsOpen)); - - public bool IsOpen - { - get => GetValue(IsOpenProperty); - set => SetValue(IsOpenProperty, value); - } - - public static readonly RoutedEvent CloseEvent = RoutedEvent.Register( - "Close", RoutingStrategies.Bubble); - - public event EventHandler Close - { - add => AddHandler(CloseEvent, value); - remove => RemoveHandler(CloseEvent, value); - } - - public Task ShowAsync(CancellationToken? token = default) - { - var tcs = new TaskCompletionSource(); - token?.Register(() => - { - Dispatcher.UIThread.Invoke(CloseDrawer); - }); - - void OnCloseHandler(object sender, ResultEventArgs args) - { - if (args is T result) - { - tcs.SetResult(result); - Close -= OnCloseHandler; - } - else - { - tcs.SetResult(default(T)); - Close -= OnCloseHandler; - } - } - - this.Close += OnCloseHandler; - return tcs.Task; - } - - internal void CloseDrawer() - { - - } -} \ No newline at end of file diff --git a/src/Ursa/Controls/Drawer/DrawerControlBase.cs b/src/Ursa/Controls/Drawer/DrawerControlBase.cs new file mode 100644 index 0000000..5cc8eb7 --- /dev/null +++ b/src/Ursa/Controls/Drawer/DrawerControlBase.cs @@ -0,0 +1,102 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Interactivity; +using Avalonia.Threading; +using Ursa.Common; +using Ursa.EventArgs; + +namespace Ursa.Controls; + +public abstract class DrawerControlBase: ContentControl +{ + internal bool CanClickOnMaskToClose { get; set; } + + + public static readonly StyledProperty PositionProperty = AvaloniaProperty.Register( + nameof(Position)); + + public Position Position + { + get => GetValue(PositionProperty); + set => SetValue(PositionProperty, value); + } + + public static readonly StyledProperty IsOpenProperty = AvaloniaProperty.Register( + nameof(IsOpen)); + + public bool IsOpen + { + get => GetValue(IsOpenProperty); + set => SetValue(IsOpenProperty, value); + } + + public static readonly StyledProperty IsCloseButtonVisibleProperty = + AvaloniaProperty.Register( + nameof(IsCloseButtonVisible)); + + public bool IsCloseButtonVisible + { + get => GetValue(IsCloseButtonVisibleProperty); + set => SetValue(IsCloseButtonVisibleProperty, value); + } + + public static readonly RoutedEvent ClosedEvent = RoutedEvent.Register( + nameof(Closed), RoutingStrategies.Bubble); + + public event EventHandler Closed + { + add => AddHandler(ClosedEvent, value); + remove => RemoveHandler(ClosedEvent, value); + } + + static DrawerControlBase() + { + DataContextProperty.Changed.AddClassHandler((o, e) => o.OnDataContextChange(e)); + } + + private void OnDataContextChange(AvaloniaPropertyChangedEventArgs args) + { + if(args.OldValue.Value is IDialogContext oldContext) + { + oldContext.RequestClose -= OnContextRequestClose; + } + if(args.NewValue.Value is IDialogContext newContext) + { + newContext.RequestClose += OnContextRequestClose; + } + } + + private void OnContextRequestClose(object sender, object? e) + { + RaiseEvent(new ResultEventArgs(ClosedEvent, e)); + } + + public Task ShowAsync(CancellationToken? token = default) + { + var tcs = new TaskCompletionSource(); + token?.Register(() => + { + Dispatcher.UIThread.Invoke(CloseDrawer); + }); + + void OnCloseHandler(object sender, ResultEventArgs args) + { + if (args.Result is T result) + { + tcs.SetResult(result); + } + else + { + tcs.SetResult(default(T)); + } + RemoveHandler(ClosedEvent, OnCloseHandler); + } + AddHandler(ClosedEvent, OnCloseHandler); + return tcs.Task; + } + + internal virtual void CloseDrawer() + { + RaiseEvent(new ResultEventArgs(ClosedEvent, null)); + } +} \ No newline at end of file From ff8d4b1dcd1582ad619625e061a484d182216ceb Mon Sep 17 00:00:00 2001 From: rabbitism Date: Sun, 4 Feb 2024 16:06:34 +0800 Subject: [PATCH 03/14] WIP: animation. --- demo/Ursa.Demo/Models/MenuKeys.cs | 1 + demo/Ursa.Demo/Pages/DrawerDemo.axaml | 14 +++ demo/Ursa.Demo/Pages/DrawerDemo.axaml.cs | 13 +++ .../ViewModels/DrawerDemoViewModel.cs | 23 ++++ .../Ursa.Demo/ViewModels/MainViewViewModel.cs | 1 + demo/Ursa.Demo/ViewModels/MenuViewModel.cs | 1 + src/Ursa.Themes.Semi/Controls/Drawer.axaml | 44 +++++++ src/Ursa.Themes.Semi/Controls/_index.axaml | 1 + .../Controls/Dialog/DefaultDialogControl.cs | 1 - src/Ursa/Controls/Dialog/OverlayDialogHost.cs | 107 ++++++++++++++++-- .../Controls/Drawer/CustomDrawerControl.cs | 6 + .../Controls/Drawer/DefaultDrawerControl.cs | 35 +++++- src/Ursa/Controls/Drawer/Drawer.cs | 15 ++- src/Ursa/Controls/Drawer/DrawerControlBase.cs | 28 ++++- .../Controls/Layout/DefaultDialogLayout.cs | 8 ++ 15 files changed, 282 insertions(+), 16 deletions(-) create mode 100644 demo/Ursa.Demo/Pages/DrawerDemo.axaml create mode 100644 demo/Ursa.Demo/Pages/DrawerDemo.axaml.cs create mode 100644 demo/Ursa.Demo/ViewModels/DrawerDemoViewModel.cs create mode 100644 src/Ursa.Themes.Semi/Controls/Drawer.axaml create mode 100644 src/Ursa/Controls/Drawer/CustomDrawerControl.cs create mode 100644 src/Ursa/Controls/Layout/DefaultDialogLayout.cs diff --git a/demo/Ursa.Demo/Models/MenuKeys.cs b/demo/Ursa.Demo/Models/MenuKeys.cs index 2b30912..f97a060 100644 --- a/demo/Ursa.Demo/Models/MenuKeys.cs +++ b/demo/Ursa.Demo/Models/MenuKeys.cs @@ -8,6 +8,7 @@ public static class MenuKeys public const string MenuKeyButtonGroup = "ButtonGroup"; public const string MenuKeyDialog = "Dialog"; public const string MenuKeyDivider = "Divider"; + public const string MenuKeyDrawer = "Drawer"; public const string MenuKeyDualBadge = "DualBadge"; public const string MenuKeyEnumSelector = "EnumSelector"; public const string MenuKeyImageViewer = "ImageViewer"; diff --git a/demo/Ursa.Demo/Pages/DrawerDemo.axaml b/demo/Ursa.Demo/Pages/DrawerDemo.axaml new file mode 100644 index 0000000..10d780a --- /dev/null +++ b/demo/Ursa.Demo/Pages/DrawerDemo.axaml @@ -0,0 +1,14 @@ + + + + + diff --git a/demo/Ursa.Demo/Pages/DrawerDemo.axaml.cs b/demo/Ursa.Demo/Pages/DrawerDemo.axaml.cs new file mode 100644 index 0000000..3aa8916 --- /dev/null +++ b/demo/Ursa.Demo/Pages/DrawerDemo.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Ursa.Demo.Pages; + +public partial class DrawerDemo : UserControl +{ + public DrawerDemo() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/DrawerDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/DrawerDemoViewModel.cs new file mode 100644 index 0000000..ff9fed2 --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/DrawerDemoViewModel.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using System.Windows.Input; +using Avalonia.Controls; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using Ursa.Controls; + +namespace Ursa.Demo.ViewModels; + +public class DrawerDemoViewModel: ObservableObject +{ + public ICommand OpenDrawerCommand { get; set; } + + public DrawerDemoViewModel() + { + OpenDrawerCommand = new AsyncRelayCommand(OpenDrawer); + } + + private async Task OpenDrawer() + { + await Drawer.Show("Hello World"); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs index 50ab100..6161fde 100644 --- a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs @@ -30,6 +30,7 @@ public class MainViewViewModel : ViewModelBase MenuKeys.MenuKeyButtonGroup => new ButtonGroupDemoViewModel(), MenuKeys.MenuKeyDialog => new DialogDemoViewModel(), MenuKeys.MenuKeyDivider => new DividerDemoViewModel(), + MenuKeys.MenuKeyDrawer => new DrawerDemoViewModel(), MenuKeys.MenuKeyDualBadge => new DualBadgeDemoViewModel(), MenuKeys.MenuKeyEnumSelector => new EnumSelectorDemoViewModel(), MenuKeys.MenuKeyImageViewer => new ImageViewerDemoViewModel(), diff --git a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs index 672c5b4..45fa3b4 100644 --- a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs @@ -17,6 +17,7 @@ public class MenuViewModel: ViewModelBase new() { MenuHeader = "Button Group", Key = MenuKeys.MenuKeyButtonGroup, Status = "Updated"}, new() { MenuHeader = "Dialog", Key = MenuKeys.MenuKeyDialog }, new() { MenuHeader = "Divider", Key = MenuKeys.MenuKeyDivider }, + new() { MenuHeader = "Drawer", Key = MenuKeys.MenuKeyDrawer }, new() { MenuHeader = "DualBadge", Key = MenuKeys.MenuKeyDualBadge }, new() { MenuHeader = "Enum Selector", Key = MenuKeys.MenuKeyEnumSelector }, new() { MenuHeader = "Icon Button", Key = MenuKeys.MenuKeyIconButton }, diff --git a/src/Ursa.Themes.Semi/Controls/Drawer.axaml b/src/Ursa.Themes.Semi/Controls/Drawer.axaml new file mode 100644 index 0000000..31b3a54 --- /dev/null +++ b/src/Ursa.Themes.Semi/Controls/Drawer.axaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + diff --git a/demo/Ursa.Demo/ViewModels/DrawerDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/DrawerDemoViewModel.cs index 68f884c..2d44a87 100644 --- a/demo/Ursa.Demo/ViewModels/DrawerDemoViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/DrawerDemoViewModel.cs @@ -13,6 +13,7 @@ namespace Ursa.Demo.ViewModels; public partial class DrawerDemoViewModel: ObservableObject { public ICommand OpenDrawerCommand { get; set; } + public ICommand OpenDefaultDrawerCommand { get; set; } [ObservableProperty] private Position _selectedPosition; @@ -20,6 +21,19 @@ public partial class DrawerDemoViewModel: ObservableObject public DrawerDemoViewModel() { OpenDrawerCommand = new AsyncRelayCommand(OpenDrawer); + OpenDefaultDrawerCommand = new AsyncRelayCommand(OpenDefaultDrawer); + SelectedPosition = Position.Right; + } + + private Task OpenDefaultDrawer() + { + return Drawer.Show(new PlainDialogViewModel(), new DefaultDrawerOptions() + { + Buttons = DialogButton.OKCancel, + Position = SelectedPosition, + Title = "Please select a date", + CanClickOnMaskToClose = false, + }); } private async Task OpenDrawer() diff --git a/src/Ursa.Themes.Semi/Controls/Drawer.axaml b/src/Ursa.Themes.Semi/Controls/Drawer.axaml index 9473930..31db2d0 100644 --- a/src/Ursa.Themes.Semi/Controls/Drawer.axaml +++ b/src/Ursa.Themes.Semi/Controls/Drawer.axaml @@ -63,4 +63,105 @@ + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + +