feat: initialize Rating.
This commit is contained in:
114
demo/Ursa.Demo/Pages/RatingDemo.axaml
Normal file
114
demo/Ursa.Demo/Pages/RatingDemo.axaml
Normal file
@@ -0,0 +1,114 @@
|
||||
<UserControl x:Class="Ursa.Demo.Pages.RatingDemo"
|
||||
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:vm="clr-namespace:Ursa.Demo.ViewModels"
|
||||
xmlns:u="https://irihi.tech/ursa"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
x:CompileBindings="True"
|
||||
x:DataType="vm:RatingDemoViewModel"
|
||||
mc:Ignorable="d">
|
||||
<StackPanel Spacing="20">
|
||||
<Grid ColumnDefinitions="*, 300">
|
||||
<Grid Grid.Column="0">
|
||||
<StackPanel>
|
||||
<u:RatingCharacter />
|
||||
<u:Rating
|
||||
AllowClear="{Binding AllowClear }"
|
||||
AllowHalf="{Binding AllowHalf }"
|
||||
AllowFocus="{Binding AllowFocus }"
|
||||
IsEnabled="{Binding IsEnabled}"
|
||||
Value="{Binding Value}"
|
||||
Count="{Binding Count}"
|
||||
DefaultValue="{Binding DefaultValue }"
|
||||
Tooltips="{Binding Tooltips }" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Border Grid.Column="1" VerticalAlignment="Top">
|
||||
<Grid ColumnDefinitions="*, Auto" RowDefinitions="*,*,*,*,*,*,*">
|
||||
<Label
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Content="AllowClear" />
|
||||
<ToggleSwitch
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
MinWidth="200"
|
||||
IsChecked="{Binding AllowClear}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Content="AllowHalf" />
|
||||
<ToggleSwitch
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
IsChecked="{Binding AllowHalf}" />
|
||||
<Label
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Content="AllowFocus" />
|
||||
<ToggleSwitch
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
IsChecked="{Binding AllowFocus}" />
|
||||
<Label
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Content="IsEnabled" />
|
||||
<ToggleSwitch
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
IsChecked="{Binding IsEnabled}" />
|
||||
<Label
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Content="Value" />
|
||||
<NumericUpDown
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Maximum="100"
|
||||
Minimum="-1"
|
||||
Increment="0.1"
|
||||
VerticalAlignment="Center"
|
||||
Value="{Binding Value}" />
|
||||
<Label
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Content="Count" />
|
||||
<NumericUpDown
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Maximum="100"
|
||||
Minimum="-1"
|
||||
Increment="1"
|
||||
VerticalAlignment="Center"
|
||||
Value="{Binding Count}" />
|
||||
<Label
|
||||
Grid.Row="6"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Content="DefaultValue" />
|
||||
<NumericUpDown
|
||||
Grid.Row="6"
|
||||
Grid.Column="1"
|
||||
Maximum="100"
|
||||
Minimum="-1"
|
||||
Increment="0.1"
|
||||
VerticalAlignment="Center"
|
||||
Value="{Binding DefaultValue}" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
13
demo/Ursa.Demo/Pages/RatingDemo.axaml.cs
Normal file
13
demo/Ursa.Demo/Pages/RatingDemo.axaml.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Avalonia.Controls;
|
||||
using Ursa.Demo.ViewModels;
|
||||
|
||||
namespace Ursa.Demo.Pages;
|
||||
|
||||
public partial class RatingDemo : UserControl
|
||||
{
|
||||
public RatingDemo()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.DataContext = new RatingDemoViewModel();
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,7 @@ public class MainViewViewModel : ViewModelBase
|
||||
MenuKeys.MenuKeyNumPad => new NumPadDemoViewModel(),
|
||||
MenuKeys.MenuKeyPagination => new PaginationDemoViewModel(),
|
||||
MenuKeys.MenuKeyRangeSlider => new RangeSliderDemoViewModel(),
|
||||
MenuKeys.MenuKeyRating => new RatingDemoViewModel(),
|
||||
MenuKeys.MenuKeyScrollToButton => new ScrollToButtonDemoViewModel(),
|
||||
MenuKeys.MenuKeySelectionList => new SelectionListDemoViewModel(),
|
||||
MenuKeys.MenuKeySkeleton => new SkeletonDemoViewModel(),
|
||||
|
||||
@@ -38,6 +38,7 @@ public class MenuViewModel: ViewModelBase
|
||||
new() { MenuHeader = "NumPad", Key = MenuKeys.MenuKeyNumPad },
|
||||
new() { MenuHeader = "Pagination", Key = MenuKeys.MenuKeyPagination },
|
||||
new() { MenuHeader = "RangeSlider", Key = MenuKeys.MenuKeyRangeSlider },
|
||||
new() { MenuHeader = "Rating", Key = MenuKeys.MenuKeyRating },
|
||||
new() { MenuHeader = "Scroll To", Key = MenuKeys.MenuKeyScrollToButton },
|
||||
new() { MenuHeader = "Selection List", Key = MenuKeys.MenuKeySelectionList },
|
||||
new() { MenuHeader = "Skeleton", Key = MenuKeys.MenuKeySkeleton },
|
||||
@@ -83,6 +84,7 @@ public static class MenuKeys
|
||||
public const string MenuKeyNumPad = "NumPad";
|
||||
public const string MenuKeyPagination = "Pagination";
|
||||
public const string MenuKeyRangeSlider = "RangeSlider";
|
||||
public const string MenuKeyRating = "Rating";
|
||||
public const string MenuKeyScrollToButton = "ScrollToButton";
|
||||
public const string MenuKeySelectionList = "SelectionList";
|
||||
public const string MenuKeyTagInput = "TagInput";
|
||||
|
||||
20
demo/Ursa.Demo/ViewModels/RatingDemoViewModel.cs
Normal file
20
demo/Ursa.Demo/ViewModels/RatingDemoViewModel.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace Ursa.Demo.ViewModels;
|
||||
|
||||
public partial class RatingDemoViewModel : ViewModelBase
|
||||
{
|
||||
[ObservableProperty] private bool _allowClear = true;
|
||||
[ObservableProperty] private bool _allowHalf = true;
|
||||
[ObservableProperty] private bool _allowFocus;
|
||||
[ObservableProperty] private bool _isEnabled = true;
|
||||
|
||||
[ObservableProperty] private double _value;
|
||||
|
||||
// [ObservableProperty] private object _character;
|
||||
[ObservableProperty] private int _count = 10;
|
||||
[ObservableProperty] private double _defaultValue = 5;
|
||||
|
||||
public ObservableCollection<string> Tooltips { get; set; } = ["1", "2", "3", "4", "5"];
|
||||
}
|
||||
65
src/Ursa.Themes.Semi/Controls/Rating.axaml
Normal file
65
src/Ursa.Themes.Semi/Controls/Rating.axaml
Normal file
@@ -0,0 +1,65 @@
|
||||
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:u="https://irihi.tech/ursa">
|
||||
<ControlTheme x:Key="{x:Type u:RatingCharacter}" TargetType="u:RatingCharacter">
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource RatingCharacterDefaultForeground}" />
|
||||
<Setter Property="Background" Value="{DynamicResource RatingCharacterDefaultBackground}" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate TargetType="u:RatingCharacter">
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}">
|
||||
<PathIcon Name="{x:Static u:RatingCharacter.PART_IconGlyph}"
|
||||
Width="16"
|
||||
Height="16"
|
||||
Margin="4,0"
|
||||
Data="{DynamicResource RatingStarUnSelectedIconGlyph}"
|
||||
Foreground="{TemplateBinding Foreground}" />
|
||||
<ToolTip.Tip>
|
||||
<TextBlock Text="{Binding $parent[u:Rating].SelectedTooltip}" />
|
||||
</ToolTip.Tip>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
<Style Selector="^:selected /template/ PathIcon#PART_IconGlyph">
|
||||
<Setter Property="Data" Value="{DynamicResource RatingStarSelectedIconGlyph}" />
|
||||
</Style>
|
||||
</ControlTheme>
|
||||
|
||||
<ControlTheme x:Key="{x:Type u:Rating}" TargetType="u:Rating">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="ItemTemplate">
|
||||
<DataTemplate>
|
||||
<u:RatingCharacter Content="{Binding}" />
|
||||
</DataTemplate>
|
||||
</Setter>
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate TargetType="u:Rating">
|
||||
<Border Name="PART_RootBorder"
|
||||
MinHeight="30"
|
||||
Padding="8,4"
|
||||
VerticalAlignment="Stretch"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<Panel HorizontalAlignment="Stretch">
|
||||
<ItemsControl Name="{x:Static u:Rating.PART_ItemsControl}"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
ItemTemplate="{TemplateBinding ItemTemplate}"
|
||||
ItemsSource="{TemplateBinding Items}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
</Panel>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
</ControlTheme>
|
||||
</ResourceDictionary>
|
||||
@@ -28,6 +28,7 @@
|
||||
<ResourceInclude Source="NumberDisplayer.axaml" />
|
||||
<ResourceInclude Source="Pagination.axaml" />
|
||||
<ResourceInclude Source="RangeSlider.axaml" />
|
||||
<ResourceInclude Source="Rating.axaml" />
|
||||
<ResourceInclude Source="ScrollToButton.axaml" />
|
||||
<ResourceInclude Source="SelectionList.axaml" />
|
||||
<ResourceInclude Source="TagInput.axaml" />
|
||||
|
||||
4
src/Ursa.Themes.Semi/Themes/Dark/Rating.axaml
Normal file
4
src/Ursa.Themes.Semi/Themes/Dark/Rating.axaml
Normal file
@@ -0,0 +1,4 @@
|
||||
<ResourceDictionary xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<SolidColorBrush x:Key="RatingCharacterDefaultForeground" Color="#FDDE43" />
|
||||
<SolidColorBrush x:Key="RatingCharacterDefaultBackground" Color="Transparent" />
|
||||
</ResourceDictionary>
|
||||
@@ -12,6 +12,7 @@
|
||||
<MergeResourceInclude Source="Loading.axaml" />
|
||||
<MergeResourceInclude Source="NavigationMenu.axaml" />
|
||||
<MergeResourceInclude Source="Pagination.axaml" />
|
||||
<MergeResourceInclude Source="Rating.axaml" />
|
||||
<MergeResourceInclude Source="TagInput.axaml" />
|
||||
<MergeResourceInclude Source="Timeline.axaml" />
|
||||
<MergeResourceInclude Source="Skeleton.axaml" />
|
||||
|
||||
4
src/Ursa.Themes.Semi/Themes/Light/Rating.axaml
Normal file
4
src/Ursa.Themes.Semi/Themes/Light/Rating.axaml
Normal file
@@ -0,0 +1,4 @@
|
||||
<ResourceDictionary xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<SolidColorBrush x:Key="RatingCharacterDefaultForeground" Color="#FAC800" />
|
||||
<SolidColorBrush x:Key="RatingCharacterDefaultBackground" Color="Transparent" />
|
||||
</ResourceDictionary>
|
||||
@@ -12,6 +12,7 @@
|
||||
<MergeResourceInclude Source="Loading.axaml" />
|
||||
<MergeResourceInclude Source="NavigationMenu.axaml" />
|
||||
<MergeResourceInclude Source="Pagination.axaml" />
|
||||
<MergeResourceInclude Source="Rating.axaml" />
|
||||
<MergeResourceInclude Source="TagInput.axaml" />
|
||||
<MergeResourceInclude Source="Timeline.axaml" />
|
||||
<MergeResourceInclude Source="Skeleton.axaml" />
|
||||
|
||||
5
src/Ursa.Themes.Semi/Themes/Shared/Rating.axaml
Normal file
5
src/Ursa.Themes.Semi/Themes/Shared/Rating.axaml
Normal file
@@ -0,0 +1,5 @@
|
||||
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<PathGeometry x:Key="RatingStarUnSelectedIconGlyph">M12 5.02863L9.56867 9.10197C9.39633 9.39072 9.10801 9.59094 8.77762 9.65133L4.47932 10.4369L7.47279 13.9041C7.69195 14.158 7.79145 14.494 7.74589 14.8265L7.13481 19.2864L11.5403 17.3919C11.8338 17.2657 12.1662 17.2657 12.4597 17.3919L16.8652 19.2864L16.2541 14.8265C16.2086 14.494 16.308 14.158 16.5272 13.9041L19.5207 10.4369L15.2224 9.65133C14.892 9.59095 14.6037 9.39072 14.4313 9.10198L12 5.02863ZM10.9998 2.56831C11.4521 1.81056 12.5479 1.81057 13.0002 2.56831L16.028 7.64098L21.5427 8.64887C22.4298 8.81101 22.8049 9.87773 22.215 10.561L18.4119 14.9659L19.1938 20.672C19.3171 21.5718 18.4126 22.2617 17.5795 21.9035L12 19.5041L6.4205 21.9035C5.58741 22.2617 4.68294 21.5718 4.80622 20.672L5.58806 14.9659L1.78503 10.561C1.19513 9.87772 1.57018 8.81101 2.45731 8.64887L7.97197 7.64098L10.9998 2.56831Z</PathGeometry>
|
||||
<PathGeometry x:Key="RatingStarSelectedIconGlyph">M10.7525 1.90411C11.1451 0.698628 12.8549 0.698631 13.2475 1.90411L15.2395 8.01946H21.6858C22.9565 8.01946 23.4848 9.64143 22.4568 10.3865L17.2417 14.1659L19.2337 20.2813C19.6263 21.4868 18.2431 22.4892 17.2151 21.7442L12 17.9647L6.78489 21.7442C5.75687 22.4892 4.37368 21.4868 4.76635 20.2813L6.75834 14.1659L1.54323 10.3865C0.515206 9.64142 1.04354 8.01946 2.31425 8.01946H8.76048L10.7525 1.90411Z</PathGeometry>
|
||||
</ResourceDictionary>
|
||||
@@ -13,6 +13,7 @@
|
||||
<MergeResourceInclude Source="MessageBox.axaml" />
|
||||
<MergeResourceInclude Source="NavigationMenu.axaml" />
|
||||
<MergeResourceInclude Source="Pagination.axaml" />
|
||||
<MergeResourceInclude Source="Rating.axaml" />
|
||||
<MergeResourceInclude Source="ScrollToButton.axaml" />
|
||||
<MergeResourceInclude Source="TagInput.axaml" />
|
||||
<MergeResourceInclude Source="Skeleton.axaml" />
|
||||
|
||||
250
src/Ursa/Controls/Rating/Rating.cs
Normal file
250
src/Ursa/Controls/Rating/Rating.cs
Normal file
@@ -0,0 +1,250 @@
|
||||
using System.Collections;
|
||||
using System.Collections.ObjectModel;
|
||||
using Avalonia;
|
||||
using Avalonia.Collections;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Metadata;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Input;
|
||||
|
||||
namespace Ursa.Controls;
|
||||
|
||||
[PseudoClasses(PC_Selected)]
|
||||
[TemplatePart(PART_ItemsControl, typeof(ItemsControl))]
|
||||
public class Rating : TemplatedControl
|
||||
{
|
||||
public const string PART_ItemsControl = "PART_ItemsControl";
|
||||
protected const string PC_Selected = ":selected";
|
||||
|
||||
private ItemsControl? _itemsControl;
|
||||
|
||||
public static readonly StyledProperty<double> ValueProperty =
|
||||
AvaloniaProperty.Register<Rating, double>(nameof(Value), defaultBindingMode: BindingMode.TwoWay);
|
||||
|
||||
public static readonly StyledProperty<bool> AllowClearProperty =
|
||||
AvaloniaProperty.Register<Rating, bool>(nameof(AllowClear), true);
|
||||
|
||||
public static readonly StyledProperty<bool> AllowHalfProperty =
|
||||
AvaloniaProperty.Register<Rating, bool>(nameof(AllowHalf));
|
||||
|
||||
public static readonly StyledProperty<bool> AllowFocusProperty =
|
||||
AvaloniaProperty.Register<Rating, bool>(nameof(AllowFocus));
|
||||
|
||||
public static readonly StyledProperty<object> CharacterProperty =
|
||||
AvaloniaProperty.Register<Rating, object>(nameof(Character));
|
||||
|
||||
public static readonly StyledProperty<int> CountProperty =
|
||||
AvaloniaProperty.Register<Rating, int>(nameof(Count), 5);
|
||||
|
||||
public static readonly StyledProperty<double> DefaultValueProperty =
|
||||
AvaloniaProperty.Register<Rating, double>(nameof(DefaultValue));
|
||||
|
||||
public static readonly StyledProperty<IList<string>> TooltipsProperty =
|
||||
AvaloniaProperty.Register<Rating, IList<string>>(nameof(Tooltips));
|
||||
|
||||
public static readonly StyledProperty<string> SelectedTooltipProperty =
|
||||
AvaloniaProperty.Register<Rating, string>(nameof(SelectedTooltip));
|
||||
|
||||
public string SelectedTooltip
|
||||
{
|
||||
get => GetValue(SelectedTooltipProperty);
|
||||
set => SetValue(SelectedTooltipProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<IDataTemplate?> ItemTemplateProperty =
|
||||
AvaloniaProperty.Register<Rating, IDataTemplate?>(nameof(ItemTemplate));
|
||||
|
||||
public double Value
|
||||
{
|
||||
get => GetValue(ValueProperty);
|
||||
set => SetValue(ValueProperty, value);
|
||||
}
|
||||
|
||||
public bool AllowClear
|
||||
{
|
||||
get => GetValue(AllowClearProperty);
|
||||
set => SetValue(AllowClearProperty, value);
|
||||
}
|
||||
|
||||
public bool AllowHalf
|
||||
{
|
||||
get => GetValue(AllowHalfProperty);
|
||||
set => SetValue(AllowHalfProperty, value);
|
||||
}
|
||||
|
||||
public bool AllowFocus
|
||||
{
|
||||
get => GetValue(AllowFocusProperty);
|
||||
set => SetValue(AllowFocusProperty, value);
|
||||
}
|
||||
|
||||
public object Character
|
||||
{
|
||||
get => GetValue(CharacterProperty);
|
||||
set => SetValue(CharacterProperty, value);
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get => GetValue(CountProperty);
|
||||
set => SetValue(CountProperty, value);
|
||||
}
|
||||
|
||||
public double DefaultValue
|
||||
{
|
||||
get => GetValue(DefaultValueProperty);
|
||||
set => SetValue(DefaultValueProperty, value);
|
||||
}
|
||||
|
||||
public IList<string> Tooltips
|
||||
{
|
||||
get => GetValue(TooltipsProperty);
|
||||
set => SetValue(TooltipsProperty, value);
|
||||
}
|
||||
|
||||
public IDataTemplate? ItemTemplate
|
||||
{
|
||||
get => GetValue(ItemTemplateProperty);
|
||||
set => SetValue(ItemTemplateProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DirectProperty<Rating, IList> ItemsProperty =
|
||||
AvaloniaProperty.RegisterDirect<Rating, IList>(
|
||||
nameof(Items), o => o.Items);
|
||||
|
||||
private IList _items;
|
||||
|
||||
public IList Items
|
||||
{
|
||||
get => _items;
|
||||
private set => SetAndRaise(ItemsProperty, ref _items, value);
|
||||
}
|
||||
|
||||
public Rating()
|
||||
{
|
||||
Items = new AvaloniaList<object>();
|
||||
Tooltips = new ObservableCollection<string>();
|
||||
}
|
||||
|
||||
static Rating()
|
||||
{
|
||||
ValueProperty.Changed.AddClassHandler<Rating>((s, e) => s.OnValueChanged(e));
|
||||
CountProperty.Changed.AddClassHandler<Rating>((s, e) => s.OnCountChanged(e));
|
||||
}
|
||||
|
||||
private void OnValueChanged(AvaloniaPropertyChangedEventArgs e)
|
||||
{
|
||||
UpdateItems((int)Value - 1);
|
||||
}
|
||||
|
||||
private void OnCountChanged(AvaloniaPropertyChangedEventArgs e)
|
||||
{
|
||||
if (!IsLoaded) return;
|
||||
|
||||
var currentCount = Items.Count;
|
||||
var newCount = e.GetNewValue<int>();
|
||||
|
||||
if (currentCount < newCount)
|
||||
{
|
||||
var itemsToAdd = newCount - currentCount;
|
||||
for (var i = 0; i < itemsToAdd; i++)
|
||||
{
|
||||
Items.Add(new RatingCharacter());
|
||||
}
|
||||
}
|
||||
else if (currentCount > newCount)
|
||||
{
|
||||
var itemsToRemove = currentCount - newCount;
|
||||
for (var i = 0; i < itemsToRemove && currentCount > i; i++)
|
||||
{
|
||||
Items.RemoveAt(currentCount - i - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (Value > newCount)
|
||||
{
|
||||
SetCurrentValue(ValueProperty, Math.Max(newCount, 0));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
|
||||
_itemsControl = e.NameScope.Find<ItemsControl>(PART_ItemsControl);
|
||||
for (var i = 0; i < Count; i++)
|
||||
{
|
||||
Items.Add(new RatingCharacter());
|
||||
}
|
||||
|
||||
UpdateItems((int)DefaultValue - 1);
|
||||
if (DefaultValue > Count)
|
||||
{
|
||||
SetCurrentValue(ValueProperty, Math.Max(Count, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCurrentValue(ValueProperty, DefaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
public void Preview(RatingCharacter o)
|
||||
{
|
||||
var index = Items.IndexOf(o);
|
||||
var tooltipsCount = Tooltips.Count;
|
||||
if (tooltipsCount > 0)
|
||||
{
|
||||
if (index < tooltipsCount)
|
||||
{
|
||||
SetCurrentValue(SelectedTooltipProperty, Tooltips[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCurrentValue(SelectedTooltipProperty, string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateItems(index);
|
||||
}
|
||||
|
||||
protected override void OnPointerExited(PointerEventArgs e)
|
||||
{
|
||||
UpdateItems((int)Value - 1);
|
||||
}
|
||||
|
||||
public void Select(RatingCharacter o)
|
||||
{
|
||||
var index = Items.IndexOf(o);
|
||||
if (AllowClear && index == (int)Value - 1)
|
||||
{
|
||||
UpdateItems(-1);
|
||||
SetCurrentValue(ValueProperty, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateItems(index);
|
||||
SetCurrentValue(ValueProperty, index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateItems(int index)
|
||||
{
|
||||
for (var i = 0; i <= index && i < Items.Count; i++)
|
||||
{
|
||||
if (Items[i] is RatingCharacter item)
|
||||
{
|
||||
item.Select(true);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = index + 1; i >= 0 && i < Items.Count; i++)
|
||||
{
|
||||
if (Items[i] is RatingCharacter item)
|
||||
{
|
||||
item.Select(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
40
src/Ursa/Controls/Rating/RatingCharacter.cs
Normal file
40
src/Ursa/Controls/Rating/RatingCharacter.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Metadata;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.LogicalTree;
|
||||
|
||||
namespace Ursa.Controls;
|
||||
|
||||
[PseudoClasses(PC_Selected)]
|
||||
[TemplatePart(PART_IconGlyph, typeof(PathIcon))]
|
||||
public class RatingCharacter : ContentControl
|
||||
{
|
||||
public const string PART_IconGlyph = "PART_IconGlyph";
|
||||
protected const string PC_Selected = ":selected";
|
||||
|
||||
private PathIcon? _icon;
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
_icon = e.NameScope.Find<PathIcon>(PART_IconGlyph);
|
||||
}
|
||||
|
||||
protected override void OnPointerEntered(PointerEventArgs e)
|
||||
{
|
||||
var parent = this.GetLogicalAncestors().OfType<Rating>().FirstOrDefault();
|
||||
parent?.Preview(this);
|
||||
}
|
||||
|
||||
protected override void OnPointerReleased(PointerReleasedEventArgs e)
|
||||
{
|
||||
var parent = this.GetLogicalAncestors().OfType<Rating>().FirstOrDefault();
|
||||
parent?.Select(this);
|
||||
}
|
||||
|
||||
public void Select(bool value)
|
||||
{
|
||||
PseudoClasses.Set(PC_Selected, value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user