feat: improve demo.

This commit is contained in:
rabbitism
2024-02-08 19:19:38 +08:00
parent da511c6078
commit 2a08391dc7
4 changed files with 119 additions and 42 deletions

View File

@@ -1,15 +1,55 @@
<UserControl 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="using:Ursa.Demo.ViewModels"
x:DataType="vm:SelectionListDemoViewModel"
x:CompileBindings="True"
mc:Ignorable="d" d:DesignWidth="800"
d:DesignHeight="450"
x:Class="Ursa.Demo.Pages.SelectionListDemo">
<UserControl
x:Class="Ursa.Demo.Pages.SelectionListDemo"
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="using:Ursa.Demo.ViewModels"
d:DesignHeight="450"
d:DesignWidth="800"
x:CompileBindings="True"
x:DataType="vm:SelectionListDemoViewModel"
mc:Ignorable="d">
<StackPanel HorizontalAlignment="Left">
<u:SelectionList ItemsSource="{Binding Items}"></u:SelectionList>
<u:SelectionList ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
<u:SelectionList.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</u:SelectionList.ItemsPanel>
</u:SelectionList>
<u:SelectionList ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" />
<u:SelectionList ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
<u:SelectionList.Indicator>
<Border Background="Transparent" CornerRadius="4">
<Border
Width="4"
Margin="0,8"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Background="{DynamicResource SemiBlue6}"
CornerRadius="4" />
</Border>
</u:SelectionList.Indicator>
<u:SelectionList.ItemTemplate>
<DataTemplate>
<Panel Height="40">
<TextBlock
Classes.Active="{Binding $parent[u:SelectionListItem].IsSelected, Mode=OneWay}"
Margin="8,0"
VerticalAlignment="Center"
Text="{Binding}">
<TextBlock.Styles>
<Style Selector="TextBlock.Active">
<Setter Property="Foreground" Value="{DynamicResource SemiOrange6}" />
</Style>
</TextBlock.Styles>
</TextBlock>
</Panel>
</DataTemplate>
</u:SelectionList.ItemTemplate>
</u:SelectionList>
<Button Command="{Binding Clear}">Clear</Button>
</StackPanel>
</UserControl>

View File

@@ -3,9 +3,10 @@ using CommunityToolkit.Mvvm.ComponentModel;
namespace Ursa.Demo.ViewModels;
public class SelectionListDemoViewModel: ObservableObject
public partial class SelectionListDemoViewModel: ObservableObject
{
public ObservableCollection<string> Items { get; set; }
[ObservableProperty] private string? _selectedItem;
public SelectionListDemoViewModel()
{
@@ -14,4 +15,9 @@ public class SelectionListDemoViewModel: ObservableObject
"Ding", "Otter", "Husky", "Mr. 17", "Cass"
};
}
public void Clear()
{
SelectedItem = null;
}
}

View File

@@ -3,9 +3,19 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:u="https://irihi.tech/ursa">
<ControlTheme x:Key="{x:Type u:SelectionList}" TargetType="u:SelectionList">
<Setter Property="Background" Value="LightBlue"></Setter>
<Setter Property="Background" Value="Transparent" />
<Setter Property="Indicator">
<Template>
<Border
Margin="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="{DynamicResource SemiBlue1}"
Theme="{DynamicResource CardBorder}" />
</Template>
</Setter>
<Setter Property="ListBox.Template">
<ControlTemplate TargetType="ListBox">
<ControlTemplate TargetType="u:SelectionList">
<Border
Name="border"
Background="{TemplateBinding Background}"
@@ -14,13 +24,7 @@
ClipToBounds="{TemplateBinding ClipToBounds}"
CornerRadius="{TemplateBinding CornerRadius}">
<Panel>
<Border
Classes="Shadow"
Margin="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Name="{x:Static u:SelectionList.PART_Indicator}"
Theme="{DynamicResource CardBorder}" />
<ContentPresenter Name="{x:Static u:SelectionList.PART_Indicator}" Content="{TemplateBinding Indicator}" />
<ItemsPresenter
Name="PART_ItemsPresenter"
Margin="{TemplateBinding Padding}"
@@ -33,20 +37,25 @@
<ControlTheme x:Key="{x:Type u:SelectionListItem}" TargetType="u:SelectionListItem">
<Setter Property="Background" Value="Transparent" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="8" />
<Setter Property="Template">
<ControlTemplate TargetType="u:SelectionListItem">
<ContentPresenter
Name="PART_ContentPresenter"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Padding="{TemplateBinding Padding}"
Foreground="{TemplateBinding Foreground}"
Background="{TemplateBinding Background}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
FontWeight="{TemplateBinding FontWeight}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Foreground="{TemplateBinding Foreground}" />
</ControlTemplate>
</Setter>
<Style Selector="^:selected">
<Setter Property="Foreground" Value="Blue"></Setter>
<Setter Property="FontWeight" Value="Bold" />
</Style>
</ControlTheme>
</ResourceDictionary>

View File

@@ -1,6 +1,8 @@
using System.Runtime.CompilerServices;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Selection;
using Avalonia.Controls.Templates;
@@ -11,14 +13,23 @@ using Irihi.Avalonia.Shared.Helpers;
namespace Ursa.Controls;
[TemplatePart(PART_Indicator, typeof(Control))]
[TemplatePart(PART_Indicator, typeof(ContentPresenter))]
public class SelectionList: SelectingItemsControl
{
public const string PART_Indicator = "PART_Indicator";
private static readonly FuncTemplate<Panel?> DefaultPanel = new(() => new StackPanel());
private Control? _indicator;
private ImplicitAnimationCollection? _implicitAnimations;
private ContentPresenter? _indicator;
public static readonly StyledProperty<Control?> IndicatorProperty = AvaloniaProperty.Register<SelectionList, Control?>(
nameof(Indicator));
public Control? Indicator
{
get => GetValue(IndicatorProperty);
set => SetValue(IndicatorProperty, value);
}
static SelectionList()
{
@@ -75,25 +86,23 @@ public class SelectionList: SelectingItemsControl
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
_indicator = e.NameScope.Find<Control>(PART_Indicator);
_indicator?.Arrange(new Rect());
_indicator= e.NameScope.Find<ContentPresenter>(PART_Indicator);
EnsureIndicatorAnimation();
}
private void EnsureIndicatorAnimation()
{
if (_indicator is not null)
{
_indicator.Opacity = 0;
SetUpAnimation();
if (ElementComposition.GetElementVisual(_indicator) is { } v)
{
v.ImplicitAnimations = _implicitAnimations;
v.ImplicitAnimations = _implicitAnimations;
}
_indicator.SizeChanged += OnIndicatorSizeChanged;
}
}
private void OnIndicatorSizeChanged(object sender, SizeChangedEventArgs e)
{
}
internal void SelectByIndex(int index)
{
using var operation = Selection.BatchUpdate();
@@ -103,13 +112,16 @@ public class SelectionList: SelectingItemsControl
private void SetUpAnimation()
{
if (_implicitAnimations != null) return;
var compositorVisual = ElementComposition.GetElementVisual(this);
if (compositorVisual is null) return;
var compositor = ElementComposition.GetElementVisual(this)!.Compositor;
var offsetAnimation = compositor.CreateVector3KeyFrameAnimation();
offsetAnimation.Target = "Offset";
offsetAnimation.Target = nameof(CompositionVisual.Offset);
offsetAnimation.InsertExpressionKeyFrame(1.0f, "this.FinalValue");
offsetAnimation.Duration = TimeSpan.FromSeconds(0.3);
var sizeAnimation = compositor.CreateVector2KeyFrameAnimation();
sizeAnimation.Target = "Size";
sizeAnimation.Target = nameof(CompositionVisual.Size);
sizeAnimation.InsertExpressionKeyFrame(1.0f, "this.FinalValue");
sizeAnimation.Duration = TimeSpan.FromSeconds(0.3);
var opacityAnimation = compositor.CreateScalarKeyFrameAnimation();
@@ -118,9 +130,19 @@ public class SelectionList: SelectingItemsControl
opacityAnimation.Duration = TimeSpan.FromSeconds(0.3);
_implicitAnimations = compositor.CreateImplicitAnimationCollection();
_implicitAnimations["Offset"] = offsetAnimation;
_implicitAnimations["Size"] = sizeAnimation;
_implicitAnimations["Opacity"] = opacityAnimation;
_implicitAnimations[nameof(CompositionVisual.Offset)] = offsetAnimation;
_implicitAnimations[nameof(CompositionVisual.Size)] = sizeAnimation;
_implicitAnimations[nameof(CompositionVisual.Opacity)] = opacityAnimation;
}
}
protected override void OnKeyDown(KeyEventArgs e)
{
var hotkeys = Application.Current!.PlatformSettings?.HotkeyConfiguration;
if (e.Key.ToNavigationDirection() is { } direction && direction.IsDirectional())
{
e.Handled |= MoveSelection(direction, WrapSelection);
}
base.OnKeyDown(e);
}
}