Add user rating editing to grid

This commit is contained in:
Michael Bucari-Tovo 2022-12-30 17:00:16 -07:00
parent 3a44bef0d9
commit c900fe8461
24 changed files with 942 additions and 62 deletions

View file

@ -0,0 +1,52 @@
<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"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="LibationAvalonia.Controls.RatingBox">
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto,Auto">
<Grid.Styles>
<Style Selector="TextBlock">
<Setter Property="FontSize" Value="11" />
</Style>
</Grid.Styles>
<TextBlock Grid.Column="0" Grid.Row="0" Name="tblockOverall" Text="Overall:" />
<TextBlock Grid.Column="0" Grid.Row="1" Name="tblockPerform" Text="Perform:" />
<TextBlock Grid.Column="0" Grid.Row="2" Name="tblockStory" Text="Story:" />
<Panel Background="Transparent" PointerEntered="Panel_PointerEntered" PointerExited="Panel_PointerExited" Grid.Column="1" Grid.Row="0">
<TextBlock Name="tblockOverallRating" />
<StackPanel IsVisible="false" Orientation="Horizontal">
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
</StackPanel>
</Panel>
<Panel Background="Transparent" PointerEntered="Panel_PointerEntered" PointerExited="Panel_PointerExited" Grid.Column="1" Grid.Row="1">
<TextBlock Name="tblockPerformRating" />
<StackPanel IsVisible="false" Orientation="Horizontal">
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
</StackPanel>
</Panel>
<Panel Background="Transparent" PointerEntered="Panel_PointerEntered" PointerExited="Panel_PointerExited" Grid.Column="1" Grid.Row="2">
<TextBlock Name="tblockStoryRating" />
<StackPanel IsVisible="false" Orientation="Horizontal">
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
</StackPanel>
</Panel>
</Grid>
</UserControl>

View file

@ -0,0 +1,125 @@
using Avalonia;
using Avalonia.Controls;
using DataLayer;
using NPOI.POIFS.Storage;
using System.Linq;
namespace LibationAvalonia.Controls
{
public partial class RatingBox : UserControl
{
private const string SOLID_STAR = "★";
private const string HOLLOW_STAR = "☆";
private static readonly char[] FIVE_STARS = { '★', '★', '★', '★', '★' };
public static readonly StyledProperty<Rating> RatingProperty =
AvaloniaProperty.Register<RatingBox, Rating>(nameof(Rating));
public Rating Rating
{
get { return GetValue(RatingProperty); }
set { SetValue(RatingProperty, value); }
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
if (change.Property.Name == nameof(Rating) && Rating is not null)
{
tblockOverallRating.Text = StarRating((int)Rating.OverallRating);
tblockPerformRating.Text = StarRating((int)Rating.PerformanceRating);
tblockStoryRating.Text = StarRating((int)Rating.StoryRating);
if (this.IsPointerOver)
RatingBox_PointerEntered(this, null);
else
RatingBox_PointerExited(this, null);
}
base.OnPropertyChanged(change);
}
public RatingBox()
{
InitializeComponent();
PointerEntered += RatingBox_PointerEntered;
PointerExited += RatingBox_PointerExited;
}
private void RatingBox_PointerExited(object sender, Avalonia.Input.PointerEventArgs e)
{
tblockOverall.IsVisible = Rating?.OverallRating > 0;
tblockPerform.IsVisible = Rating?.PerformanceRating > 0;
tblockStory.IsVisible = Rating?.StoryRating > 0;
}
private void RatingBox_PointerEntered(object sender, Avalonia.Input.PointerEventArgs e)
{
tblockOverall.IsVisible = true;
tblockPerform.IsVisible = true;
tblockStory.IsVisible = true;
}
private static string StarRating(int rating) => new string(FIVE_STARS, 0, rating);
public void Panel_PointerExited(object sender, Avalonia.Input.PointerEventArgs e)
{
var panel = sender as Panel;
var stackPanel = panel.Children.OfType<StackPanel>().Single();
panel.Children.OfType<TextBlock>().Single().IsVisible = true;
stackPanel.IsVisible = false;
foreach (TextBlock child in stackPanel.Children)
child.Text = HOLLOW_STAR;
}
public void Panel_PointerEntered(object sender, Avalonia.Input.PointerEventArgs e)
{
var panel = sender as Panel;
panel.Children.OfType<TextBlock>().Single().IsVisible = false;
panel.Children.OfType<StackPanel>().Single().IsVisible = true;
}
public void Star_PointerEntered(object sender, Avalonia.Input.PointerEventArgs e)
{
var thisTbox = sender as TextBlock;
var stackPanel = thisTbox.Parent as StackPanel;
var star = SOLID_STAR;
foreach (TextBlock child in stackPanel.Children)
{
child.Text = star;
if (child == thisTbox) star = HOLLOW_STAR;
}
}
public void Star_Tapped(object sender, Avalonia.Input.TappedEventArgs e)
{
var overall = Rating.OverallRating;
var perform = Rating.PerformanceRating;
var story = Rating.StoryRating;
var thisTbox = sender as TextBlock;
var stackPanel = thisTbox.Parent as StackPanel;
int newRating = 0;
foreach (var tbox in stackPanel.Children)
{
newRating++;
if (tbox == thisTbox) break;
}
var ratingName = ((Panel)stackPanel.Parent).Children.OfType<TextBlock>().Single().Name;
if (ratingName == tblockOverallRating.Name)
overall = newRating;
else if (ratingName == tblockPerformRating.Name)
perform = newRating;
else if (ratingName == tblockStoryRating.Name)
story = newRating;
if (overall + perform + story == 0f) return;
Rating = new Rating(overall, perform, story);
}
}
}