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