feat: pre job: change events to routed events.

This commit is contained in:
rabbitism
2024-02-04 02:07:45 +08:00
parent 0f97da7ce8
commit ed21ee8189
10 changed files with 148 additions and 33 deletions

View File

@@ -14,7 +14,7 @@
</UserControl.Resources> </UserControl.Resources>
<StackPanel HorizontalAlignment="Left" Spacing="16"> <StackPanel HorizontalAlignment="Left" Spacing="16">
<ToggleSwitch Name="loading" Content="Toggle Loading" /> <ToggleSwitch Name="loading" Content="Toggle Loading" />
<u:EnumSelector Name="placement" EnumType="{x:Type common:IconPlacement}" /> <u:EnumSelector Name="placement" EnumType="{x:Type common:Position}" />
<u:IconButton <u:IconButton
Content="Hello World" Content="Hello World"
IconPlacement="{Binding #placement.Value}" IconPlacement="{Binding #placement.Value}"

View File

@@ -1,6 +1,6 @@
namespace Ursa.Common; namespace Ursa.Common;
public enum IconPlacement public enum Position
{ {
Left, Left,
Top, Top,

View File

@@ -5,6 +5,7 @@ using Avalonia.Controls.Primitives;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Ursa.Common; using Ursa.Common;
using Ursa.EventArgs;
namespace Ursa.Controls; namespace Ursa.Controls;

View File

@@ -7,6 +7,7 @@ using Avalonia.Input.GestureRecognizers;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Threading; using Avalonia.Threading;
using Ursa.Common; using Ursa.Common;
using Ursa.EventArgs;
namespace Ursa.Controls; namespace Ursa.Controls;
@@ -32,9 +33,23 @@ public class DialogControl: ContentControl
internal double? VerticalOffsetRatio { get; set; } internal double? VerticalOffsetRatio { get; set; }
internal bool CanClickOnMaskToClose { get; set; } internal bool CanClickOnMaskToClose { get; set; }
internal bool IsCloseButtonVisible { get; set; } internal bool IsCloseButtonVisible { get; set; }
public static readonly RoutedEvent<DialogLayerChangeEventArgs> LayerChangedEvent = RoutedEvent.Register<DialogControl, DialogLayerChangeEventArgs>(
nameof(LayerChanged), RoutingStrategies.Bubble);
public event EventHandler<DialogLayerChangeEventArgs> LayerChanged
{
add => AddHandler(LayerChangedEvent, value);
remove => RemoveHandler(LayerChangedEvent, value);
}
public event EventHandler<DialogLayerChangeEventArgs>? LayerChanged; public static readonly RoutedEvent<ResultEventArgs> ClosedEvent = RoutedEvent.Register<DrawerControl, ResultEventArgs>(
public event EventHandler<object?>? DialogControlClosing; nameof(Closed), RoutingStrategies.Bubble);
public event EventHandler<ResultEventArgs> Closed
{
add => AddHandler(ClosedEvent, value);
remove => RemoveHandler(ClosedEvent, value);
}
static DialogControl() static DialogControl()
{ {
@@ -45,9 +60,8 @@ public class DialogControl: ContentControl
{ {
if (args.OldValue.Value is IDialogContext oldContext) if (args.OldValue.Value is IDialogContext oldContext)
{ {
oldContext.RequestClose-= OnContextRequestClose; oldContext.RequestClose -= OnContextRequestClose;
} }
if (args.NewValue.Value is IDialogContext newContext) if (args.NewValue.Value is IDialogContext newContext)
{ {
newContext.RequestClose += OnContextRequestClose; newContext.RequestClose += OnContextRequestClose;
@@ -99,21 +113,21 @@ public class DialogControl: ContentControl
{ {
Dispatcher.UIThread.Invoke(CloseDialog); 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); tcs.SetResult(result);
DialogControlClosing-= OnCloseHandler;
} }
else else
{ {
tcs.SetResult(default(T)); tcs.SetResult(default);
DialogControlClosing-= OnCloseHandler;
} }
RemoveHandler(ClosedEvent, OnCloseHandler);
} }
this.DialogControlClosing += OnCloseHandler; AddHandler(ClosedEvent, OnCloseHandler);
return tcs.Task; return tcs.Task;
} }
@@ -121,7 +135,7 @@ public class DialogControl: ContentControl
private void OnContextRequestClose(object sender, object? args) 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) if (o is DialogLayerChangeType t)
{ {
LayerChanged?.Invoke(this, new DialogLayerChangeEventArgs(t)); RaiseEvent(new DialogLayerChangeEventArgs(LayerChangedEvent, t));
} }
} }
@@ -138,9 +152,9 @@ public class DialogControl: ContentControl
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="args"></param> /// <param name="args"></param>
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) internal void SetAsModal(bool modal)
@@ -161,7 +175,7 @@ public class DialogControl: ContentControl
} }
else else
{ {
DialogControlClosing?.Invoke(this, null); OnDialogControlClosing(this, null);
} }
} }
} }

View File

@@ -1,12 +1,19 @@
using Avalonia.Interactivity;
namespace Ursa.Controls; namespace Ursa.Controls;
public class DialogLayerChangeEventArgs public class DialogLayerChangeEventArgs: RoutedEventArgs
{ {
public DialogLayerChangeType ChangeType { get; } public DialogLayerChangeType ChangeType { get; }
public DialogLayerChangeEventArgs(DialogLayerChangeType type) public DialogLayerChangeEventArgs(DialogLayerChangeType type)
{ {
ChangeType = type; ChangeType = type;
} }
public DialogLayerChangeEventArgs(RoutedEvent routedEvent, DialogLayerChangeType type): base(routedEvent)
{
ChangeType = type;
}
} }
public enum DialogLayerChangeType public enum DialogLayerChangeType

View File

@@ -163,8 +163,8 @@ public class OverlayDialogHost : Canvas
control.Measure(this.Bounds.Size); control.Measure(this.Bounds.Size);
control.Arrange(new Rect(control.DesiredSize)); control.Arrange(new Rect(control.DesiredSize));
SetToPosition(control); SetToPosition(control);
control.DialogControlClosing += OnDialogControlClosing; control.AddHandler(DialogControl.ClosedEvent, OnDialogControlClosing);
control.LayerChanged += OnDialogLayerChanged; control.AddHandler(DialogControl.LayerChangedEvent, OnDialogLayerChanged);
ResetZIndices(); ResetZIndices();
} }
@@ -173,8 +173,8 @@ public class OverlayDialogHost : Canvas
if (sender is DialogControl control) if (sender is DialogControl control)
{ {
Children.Remove(control); Children.Remove(control);
control.DialogControlClosing -= OnDialogControlClosing; control.RemoveHandler(DialogControl.ClosedEvent, OnDialogControlClosing);
control.LayerChanged -= OnDialogLayerChanged; control.RemoveHandler(DialogControl.LayerChangedEvent, OnDialogLayerChanged);
if (_dialogs.Contains(control)) if (_dialogs.Contains(control))
{ {
_dialogs.Remove(control); _dialogs.Remove(control);
@@ -217,8 +217,8 @@ public class OverlayDialogHost : Canvas
control.Measure(this.Bounds.Size); control.Measure(this.Bounds.Size);
control.Arrange(new Rect(control.DesiredSize)); control.Arrange(new Rect(control.DesiredSize));
SetToPosition(control); SetToPosition(control);
control.DialogControlClosing += OnDialogControlClosing; control.AddHandler(DialogControl.ClosedEvent, OnDialogControlClosing);
control.LayerChanged += OnDialogLayerChanged; control.AddHandler(DialogControl.LayerChangedEvent, OnDialogLayerChanged);
} }
// Handle dialog layer change event // Handle dialog layer change event

View File

@@ -0,0 +1,6 @@
namespace Ursa.Controls;
public static class Drawer
{
}

View File

@@ -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<Position> PositionProperty = AvaloniaProperty.Register<DrawerControl, Position>(
nameof(Position));
public Position Position
{
get => GetValue(PositionProperty);
set => SetValue(PositionProperty, value);
}
public static readonly StyledProperty<bool> IsOpenProperty = AvaloniaProperty.Register<DrawerControl, bool>(
nameof(IsOpen));
public bool IsOpen
{
get => GetValue(IsOpenProperty);
set => SetValue(IsOpenProperty, value);
}
public static readonly RoutedEvent<ResultEventArgs> CloseEvent = RoutedEvent.Register<DrawerControl, ResultEventArgs>(
"Close", RoutingStrategies.Bubble);
public event EventHandler<ResultEventArgs> Close
{
add => AddHandler(CloseEvent, value);
remove => RemoveHandler(CloseEvent, value);
}
public Task<T?> ShowAsync<T>(CancellationToken? token = default)
{
var tcs = new TaskCompletionSource<T?>();
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()
{
}
}

View File

@@ -44,10 +44,10 @@ public class IconButton: Button
set => SetValue(IsLoadingProperty, value); set => SetValue(IsLoadingProperty, value);
} }
public static readonly StyledProperty<IconPlacement> IconPlacementProperty = AvaloniaProperty.Register<IconButton, IconPlacement>( public static readonly StyledProperty<Position> IconPlacementProperty = AvaloniaProperty.Register<IconButton, Position>(
nameof(IconPlacement), defaultValue: IconPlacement.Left); nameof(IconPlacement), defaultValue: Position.Left);
public IconPlacement IconPlacement public Position IconPlacement
{ {
get => GetValue(IconPlacementProperty); get => GetValue(IconPlacementProperty);
set => SetValue(IconPlacementProperty, value); set => SetValue(IconPlacementProperty, value);
@@ -55,7 +55,7 @@ public class IconButton: Button
static IconButton() static IconButton()
{ {
IconPlacementProperty.Changed.AddClassHandler<IconButton, IconPlacement>((o, e) => IconPlacementProperty.Changed.AddClassHandler<IconButton, Position>((o, e) =>
{ {
o.SetPlacement(e.NewValue.Value, o.Icon); o.SetPlacement(e.NewValue.Value, o.Icon);
}); });
@@ -71,7 +71,7 @@ public class IconButton: Button
SetPlacement(IconPlacement, Icon); SetPlacement(IconPlacement, Icon);
} }
private void SetPlacement(IconPlacement placement, object? icon) private void SetPlacement(Position placement, object? icon)
{ {
if (icon is null) if (icon is null)
{ {
@@ -83,9 +83,9 @@ public class IconButton: Button
return; return;
} }
PseudoClasses.Set(PC_Empty, false); PseudoClasses.Set(PC_Empty, false);
PseudoClasses.Set(PC_Left, placement == IconPlacement.Left); PseudoClasses.Set(PC_Left, placement == Position.Left);
PseudoClasses.Set(PC_Right, placement == IconPlacement.Right); PseudoClasses.Set(PC_Right, placement == Position.Right);
PseudoClasses.Set(PC_Top, placement == IconPlacement.Top); PseudoClasses.Set(PC_Top, placement == Position.Top);
PseudoClasses.Set(PC_Bottom, placement == IconPlacement.Bottom); PseudoClasses.Set(PC_Bottom, placement == Position.Bottom);
} }
} }

View File

@@ -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;
}
}