feat: Add theme.

This commit is contained in:
rabbitism
2024-03-06 15:46:06 +08:00
parent 390b581cb8
commit eb14cf9e13
11 changed files with 181 additions and 57 deletions

View File

@@ -7,7 +7,7 @@
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="VerticalAlignment" Value="Bottom" />
<Setter Property="Cursor" Value="Hand"></Setter>
<Setter Property="Margin" Value="0, 0, 32, 32" />
<Setter Property="Margin" Value="0, 0, 16, 16" />
<Setter Property="Template">
<ControlTemplate TargetType="u:ScrollToButton">
<Border
@@ -35,5 +35,14 @@
<Setter Property="BorderBrush" Value="{DynamicResource ButtonDefaultPressedBorderBrush}" />
<Setter Property="Background" Value="{DynamicResource ButtonDefaultPressedBackground}" />
</Style>
<Style Selector="^[Direction=Right] /template/ PathIcon#PART_Icon">
<Setter Property="RenderTransform" Value="rotate(90deg)"></Setter>
</Style>
<Style Selector="^[Direction=Bottom] /template/ PathIcon#PART_Icon">
<Setter Property="RenderTransform" Value="rotate(180deg)"></Setter>
</Style>
<Style Selector="^[Direction=Left] /template/ PathIcon#PART_Icon">
<Setter Property="RenderTransform" Value="rotate(270deg)"></Setter>
</Style>
</ControlTheme>
</ResourceDictionary>

View File

@@ -2,20 +2,22 @@ using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Notifications;
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
using Avalonia.Layout;
using Avalonia.LogicalTree;
using Avalonia.Styling;
using Avalonia.VisualTree;
using Ursa.Common;
namespace Ursa.Controls;
public class ScrollTo
{
public static readonly AttachedProperty<Position> DirectionProperty =
AvaloniaProperty.RegisterAttached<ScrollTo, Control, Position>("Direction");
public static readonly AttachedProperty<Position?> DirectionProperty =
AvaloniaProperty.RegisterAttached<ScrollTo, Control, Position?>("Direction");
public static void SetDirection(Control obj, Position value) => obj.SetValue(DirectionProperty, value);
public static Position GetDirection(Control obj) => obj.GetValue(DirectionProperty);
public static Position? GetDirection(Control obj) => obj.GetValue(DirectionProperty);
public static readonly AttachedProperty<ControlTheme?> ButtonThemeProperty =
AvaloniaProperty.RegisterAttached<ScrollTo, Control, ControlTheme?>("ButtonTheme");
@@ -25,7 +27,7 @@ public class ScrollTo
static ScrollTo()
{
DirectionProperty.Changed.AddClassHandler<Control, Position>(OnDirectionChanged);
DirectionProperty.Changed.AddClassHandler<Control, Position?>(OnDirectionChanged);
ButtonThemeProperty.Changed.AddClassHandler<Control, ControlTheme?>(OnButtonThemeChanged);
}
@@ -36,8 +38,9 @@ public class ScrollTo
button.SetCurrentValue(StyledElement.ThemeProperty, arg2.NewValue.Value);
}
private static void OnDirectionChanged(Control control, AvaloniaPropertyChangedEventArgs<Position> args)
private static void OnDirectionChanged(Control control, AvaloniaPropertyChangedEventArgs<Position?> args)
{
if (args.NewValue.Value is null) return;
var button = EnsureButtonInAdorner(control);
if (button is null) return;
button.SetCurrentValue(ScrollToButton.DirectionProperty, args.NewValue.Value);
@@ -45,15 +48,13 @@ public class ScrollTo
private static ScrollToButton? EnsureButtonInAdorner(Control control)
{
var scroll = control.GetSelfAndLogicalDescendants().OfType<ScrollViewer>().FirstOrDefault();
if (scroll is null) return null;
var adorner = AdornerLayer.GetAdorner(scroll);
var adorner = AdornerLayer.GetAdorner(control);
if (adorner is not ScrollToButton button)
{
button = new ScrollToButton();
AdornerLayer.SetAdorner(control, button);
}
button.SetCurrentValue(ScrollToButton.TargetProperty, scroll);
button.SetCurrentValue(ScrollToButton.TargetProperty, control);
button.SetCurrentValue(ScrollToButton.DirectionProperty, GetDirection(control));
if ( GetButtonTheme(control) is { } theme)
{

View File

@@ -1,6 +1,8 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.LogicalTree;
using Avalonia.VisualTree;
using Irihi.Avalonia.Shared.Helpers;
using Ursa.Common;
@@ -46,10 +48,11 @@ public class ScrollToButton: Button
_disposable?.Dispose();
if (arg2.NewValue.Value is { } newValue)
{
var scroll = newValue.GetSelfAndLogicalDescendants().OfType<ScrollViewer>().FirstOrDefault();
var scroll = newValue.GetSelfAndVisualDescendants().OfType<ScrollViewer>().FirstOrDefault();
if (_scroll is not null)
{
_disposable?.Dispose();
_scroll = null;
}
_scroll = scroll;
_disposable = ScrollViewer.OffsetProperty.Changed.AddClassHandler<ScrollViewer, Vector>(OnScrollChanged);
@@ -69,14 +72,15 @@ public class ScrollToButton: Button
};
_scroll?.SetCurrentValue(ScrollViewer.OffsetProperty, vector);
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
protected override void OnLoaded(RoutedEventArgs e)
{
base.OnAttachedToVisualTree(e);
var scroll = Target.GetSelfAndLogicalDescendants().OfType<ScrollViewer>().FirstOrDefault();
base.OnLoaded(e);
var scroll = Target.GetSelfAndVisualDescendants().OfType<ScrollViewer>().FirstOrDefault();
if (_scroll is not null)
{
_disposable?.Dispose();
_scroll = null;
}
_scroll = scroll;
_disposable = ScrollViewer.OffsetProperty.Changed.AddClassHandler<ScrollViewer, Vector>(OnScrollChanged);
@@ -91,8 +95,8 @@ public class ScrollToButton: Button
private void SetVisibility(Position direction, Vector? vector)
{
if (vector is null) return;
if (direction == Position.Bottom && vector.Value.Y < 0)
if (vector is null || _scroll is null) return;
if (direction == Position.Bottom && vector.Value.Y < _scroll.Extent.Height - _scroll.Bounds.Height)
{
IsVisible = true;
}
@@ -100,11 +104,11 @@ public class ScrollToButton: Button
{
IsVisible = true;
}
else if (direction == Position.Left && vector.Value.X < 0)
else if (direction == Position.Left && vector.Value.X > 0)
{
IsVisible = true;
}
else if (direction == Position.Right && vector.Value.X > 0)
else if (direction == Position.Right && vector.Value.X < _scroll.Extent.Width - _scroll.Bounds.Width)
{
IsVisible = true;
}