feat: Add theme.
This commit is contained in:
@@ -1,37 +0,0 @@
|
||||
namespace Ursa.Demo;
|
||||
|
||||
public static class MenuKeys
|
||||
{
|
||||
public const string MenuKeyIntroduction = "Introduction";
|
||||
public const string MenuKeyBadge = "Badge";
|
||||
public const string MenuKeyBanner = "Banner";
|
||||
public const string MenuKeyButtonGroup = "ButtonGroup";
|
||||
public const string MenuKeyBreadcrumb = "Breadcrumb";
|
||||
public const string MenuKeyClassInput = "Class Input";
|
||||
public const string MenuKeyDialog = "Dialog";
|
||||
public const string MenuKeyDivider = "Divider";
|
||||
public const string MenuKeyDisableContainer = "DisableContainer";
|
||||
public const string MenuKeyDrawer = "Drawer";
|
||||
public const string MenuKeyDualBadge = "DualBadge";
|
||||
public const string MenuKeyEnumSelector = "EnumSelector";
|
||||
public const string MenuKeyForm = "Form";
|
||||
public const string MenuKeyImageViewer = "ImageViewer";
|
||||
public const string MenuKeyIpBox = "IPv4Box";
|
||||
public const string MenuKeyIconButton = "IconButton";
|
||||
public const string MenuKeyKeyGestureInput = "KeyGestureInput";
|
||||
public const string MenuKeyLoading = "Loading";
|
||||
public const string MenuKeyMessageBox = "MessageBox";
|
||||
public const string MenuKeyNavMenu = "NavMenu";
|
||||
public const string MenuKeyNumberDisplayer = "NumberDisplayer";
|
||||
public const string MenuKeyNumericUpDown = "NumericUpDown";
|
||||
public const string MenuKeyPagination = "Pagination";
|
||||
public const string MenuKeyRangeSlider = "RangeSlider";
|
||||
public const string MenuKeySelectionList = "SelectionList";
|
||||
public const string MenuKeyTagInput = "TagInput";
|
||||
public const string MenuKeySkeleton = "Skeleton";
|
||||
public const string MenuKeyTimeline = "Timeline";
|
||||
public const string MenuKeyTwoTonePathIcon = "TwoTonePathIcon";
|
||||
public const string MenuKeyThemeToggler = "ThemeToggler";
|
||||
public const string MenuKeyToolBar = "ToolBar";
|
||||
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
d:DesignHeight="850"
|
||||
d:DesignWidth="850"
|
||||
mc:Ignorable="d">
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Auto" u:ScrollTo.Direction="Top">
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Auto" u:ScrollTo.Direction="Bottom">
|
||||
<StackPanel
|
||||
Margin="24"
|
||||
HorizontalAlignment="Left"
|
||||
|
||||
76
demo/Ursa.Demo/Pages/ScrollToButtonDemo.axaml
Normal file
76
demo/Ursa.Demo/Pages/ScrollToButtonDemo.axaml
Normal file
@@ -0,0 +1,76 @@
|
||||
<UserControl
|
||||
x:Class="Ursa.Demo.Pages.ScrollToButtonDemo"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:u="https://irihi.tech/ursa"
|
||||
xmlns:vm="clr-namespace:Ursa.Demo.ViewModels"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
x:CompileBindings="True"
|
||||
x:DataType="vm:ScrollToButtonDemoViewModel"
|
||||
mc:Ignorable="d">
|
||||
<UserControl.Styles>
|
||||
<Style Selector="ScrollViewer">
|
||||
<Setter Property="Margin" Value="8" />
|
||||
</Style>
|
||||
<Style Selector="ScrollViewer Border.Content">
|
||||
<Setter Property="Background">
|
||||
<Setter.Value>
|
||||
<LinearGradientBrush StartPoint="0, 0" EndPoint="2000, 2000">
|
||||
<GradientStop Color="{DynamicResource SemiPurple9Color}" Offset="0.0"></GradientStop>
|
||||
<GradientStop Color="{DynamicResource SemiPurple5Color}" Offset="0.5"></GradientStop>
|
||||
<GradientStop Color="{DynamicResource SemiPurple1Color}" Offset="1.0"></GradientStop>
|
||||
</LinearGradientBrush>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Styles>
|
||||
<Grid ColumnDefinitions="*, *, *, *, *" RowDefinitions="Auto, *">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0">Scroll To Top</TextBlock>
|
||||
<TextBlock Grid.Row="0" Grid.Column="1">Scroll To Bottom</TextBlock>
|
||||
<TextBlock Grid.Row="0" Grid.Column="2">Scroll To Left</TextBlock>
|
||||
<TextBlock Grid.Row="0" Grid.Column="3">Scroll To Right</TextBlock>
|
||||
<TextBlock Grid.Row="0" Grid.Column="4">Scroll To Top</TextBlock>
|
||||
<ScrollViewer
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
u:ScrollTo.Direction="Top"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<Border Classes="Content" Height="2000" HorizontalAlignment="Stretch" />
|
||||
</ScrollViewer>
|
||||
<ScrollViewer
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
u:ScrollTo.Direction="Bottom"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<Border Classes="Content" Height="2000" HorizontalAlignment="Stretch" />
|
||||
</ScrollViewer>
|
||||
<ScrollViewer
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
u:ScrollTo.Direction="Left"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Disabled">
|
||||
<Border Classes="Content" Width="2000" VerticalAlignment="Stretch" />
|
||||
</ScrollViewer>
|
||||
<ScrollViewer
|
||||
Grid.Row="1"
|
||||
Grid.Column="3"
|
||||
u:ScrollTo.Direction="Right"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Disabled">
|
||||
<Border Classes="Content" Width="2000" VerticalAlignment="Stretch" />
|
||||
</ScrollViewer>
|
||||
<ListBox
|
||||
Grid.Row="1"
|
||||
Grid.Column="4"
|
||||
u:ScrollTo.Direction="Top"
|
||||
ItemsSource="{Binding Items}"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
13
demo/Ursa.Demo/Pages/ScrollToButtonDemo.axaml.cs
Normal file
13
demo/Ursa.Demo/Pages/ScrollToButtonDemo.axaml.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Ursa.Demo.Pages;
|
||||
|
||||
public partial class ScrollToButtonDemo : UserControl
|
||||
{
|
||||
public ScrollToButtonDemo()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -32,4 +32,8 @@
|
||||
<DependentUpon>SkeletonDemo.axaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Models\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -48,6 +48,7 @@ public class MainViewViewModel : ViewModelBase
|
||||
MenuKeys.MenuKeyNumericUpDown => new NumericUpDownDemoViewModel(),
|
||||
MenuKeys.MenuKeyPagination => new PaginationDemoViewModel(),
|
||||
MenuKeys.MenuKeyRangeSlider => new RangeSliderDemoViewModel(),
|
||||
MenuKeys.MenuKeyScrollToButton => new ScrollToButtonDemoViewModel(),
|
||||
MenuKeys.MenuKeySelectionList => new SelectionListDemoViewModel(),
|
||||
MenuKeys.MenuKeySkeleton => new SkeletonDemoViewModel(),
|
||||
MenuKeys.MenuKeyTagInput => new TagInputDemoViewModel(),
|
||||
|
||||
@@ -35,6 +35,7 @@ public class MenuViewModel: ViewModelBase
|
||||
new() { MenuHeader = "Numeric UpDown", Key = MenuKeys.MenuKeyNumericUpDown },
|
||||
new() { MenuHeader = "Pagination", Key = MenuKeys.MenuKeyPagination },
|
||||
new() { MenuHeader = "RangeSlider", Key = MenuKeys.MenuKeyRangeSlider },
|
||||
new() { MenuHeader = "ScrollToButton", Key = MenuKeys.MenuKeyScrollToButton, Status = "New" },
|
||||
new() { MenuHeader = "Selection List", Key = MenuKeys.MenuKeySelectionList, Status = "New" },
|
||||
new() { MenuHeader = "Skeleton", Key = MenuKeys.MenuKeySkeleton, Status = "New" },
|
||||
new() { MenuHeader = "TagInput", Key = MenuKeys.MenuKeyTagInput },
|
||||
@@ -44,4 +45,41 @@ public class MenuViewModel: ViewModelBase
|
||||
new() { MenuHeader = "ToolBar", Key = MenuKeys.MenuKeyToolBar, Status = "New" }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class MenuKeys
|
||||
{
|
||||
public const string MenuKeyIntroduction = "Introduction";
|
||||
public const string MenuKeyBadge = "Badge";
|
||||
public const string MenuKeyBanner = "Banner";
|
||||
public const string MenuKeyButtonGroup = "ButtonGroup";
|
||||
public const string MenuKeyBreadcrumb= "Breadcrumb";
|
||||
public const string MenuKeyClassInput = "Class Input";
|
||||
public const string MenuKeyDialog = "Dialog";
|
||||
public const string MenuKeyDivider = "Divider";
|
||||
public const string MenuKeyDisableContainer = "DisableContainer";
|
||||
public const string MenuKeyDrawer = "Drawer";
|
||||
public const string MenuKeyDualBadge = "DualBadge";
|
||||
public const string MenuKeyEnumSelector = "EnumSelector";
|
||||
public const string MenuKeyForm = "Form";
|
||||
public const string MenuKeyImageViewer = "ImageViewer";
|
||||
public const string MenuKeyIpBox = "IPv4Box";
|
||||
public const string MenuKeyIconButton = "IconButton";
|
||||
public const string MenuKeyKeyGestureInput = "KeyGestureInput";
|
||||
public const string MenuKeyLoading = "Loading";
|
||||
public const string MenuKeyMessageBox = "MessageBox";
|
||||
public const string MenuKeyNavMenu = "NavMenu";
|
||||
public const string MenuKeyNumberDisplayer = "NumberDisplayer";
|
||||
public const string MenuKeyNumericUpDown = "NumericUpDown";
|
||||
public const string MenuKeyPagination = "Pagination";
|
||||
public const string MenuKeyRangeSlider = "RangeSlider";
|
||||
public const string MenuKeyScrollToButton = "ScrollToButton";
|
||||
public const string MenuKeySelectionList = "SelectionList";
|
||||
public const string MenuKeyTagInput = "TagInput";
|
||||
public const string MenuKeySkeleton = "Skeleton";
|
||||
public const string MenuKeyTimeline = "Timeline";
|
||||
public const string MenuKeyTwoTonePathIcon = "TwoTonePathIcon";
|
||||
public const string MenuKeyThemeToggler = "ThemeToggler";
|
||||
public const string MenuKeyToolBar = "ToolBar";
|
||||
|
||||
}
|
||||
15
demo/Ursa.Demo/ViewModels/ScrollToButtonDemoViewModel.cs
Normal file
15
demo/Ursa.Demo/ViewModels/ScrollToButtonDemoViewModel.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace Ursa.Demo.ViewModels;
|
||||
|
||||
public class ScrollToButtonDemoViewModel: ObservableObject
|
||||
{
|
||||
public ObservableCollection<string> Items { get; set; }
|
||||
|
||||
public ScrollToButtonDemoViewModel()
|
||||
{
|
||||
Items = new ObservableCollection<string>(Enumerable.Range(0, 1000).Select(a => "Item " + a));
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user