Improve classic and chardonnay rating editor simmilarity
This commit is contained in:
parent
c9497ef39e
commit
874bf9e7c0
14 changed files with 233 additions and 178 deletions
|
|
@ -3,49 +3,49 @@
|
|||
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">
|
||||
|
||||
x:Class="LibationAvalonia.Controls.MyRatingCellEditor">
|
||||
|
||||
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto,Auto">
|
||||
<Grid.Styles>
|
||||
<Style Selector="TextBlock">
|
||||
<Setter Property="FontSize" Value="11" />
|
||||
</Style>
|
||||
<Style Selector="StackPanel > TextBlock">
|
||||
<Setter Property="Padding" Value="0,0,-2,0" />
|
||||
</Style>
|
||||
</Grid.Styles>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="0" Name="tblockOverall" Text="Overall:" />
|
||||
|
||||
<TextBlock IsVisible="false" 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="☆" />
|
||||
<Panel Background="Transparent" PointerExited="Panel_PointerExited" Grid.Column="1" Grid.Row="0">
|
||||
<StackPanel Name="panelOverall" Orientation="Horizontal">
|
||||
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
|
||||
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
|
||||
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
|
||||
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
|
||||
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
|
||||
</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="☆" />
|
||||
<Panel Background="Transparent" PointerExited="Panel_PointerExited" Grid.Column="1" Grid.Row="1">
|
||||
<StackPanel Name="panelPerform" Orientation="Horizontal">
|
||||
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
|
||||
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
|
||||
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
|
||||
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
|
||||
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
|
||||
</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="☆" />
|
||||
|
||||
<Panel Background="Transparent" PointerExited="Panel_PointerExited" Grid.Column="1" Grid.Row="2">
|
||||
<StackPanel Name="panelStory" Orientation="Horizontal">
|
||||
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
|
||||
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
|
||||
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
|
||||
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
|
||||
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
</Grid>
|
||||
108
Source/LibationAvalonia/Controls/MyRatingCellEditor.axaml.cs
Normal file
108
Source/LibationAvalonia/Controls/MyRatingCellEditor.axaml.cs
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using DataLayer;
|
||||
using System.Linq;
|
||||
|
||||
namespace LibationAvalonia.Controls
|
||||
{
|
||||
public partial class MyRatingCellEditor : UserControl
|
||||
{
|
||||
private const string SOLID_STAR = "★";
|
||||
private const string HOLLOW_STAR = "☆";
|
||||
|
||||
public static readonly StyledProperty<Rating> RatingProperty =
|
||||
AvaloniaProperty.Register<MyRatingCellEditor, Rating>(nameof(Rating));
|
||||
|
||||
public bool AllRatingsVisible { get; set; }
|
||||
public Rating Rating
|
||||
{
|
||||
get { return GetValue(RatingProperty); }
|
||||
set { SetValue(RatingProperty, value); }
|
||||
}
|
||||
public MyRatingCellEditor()
|
||||
{
|
||||
InitializeComponent();
|
||||
if (Design.IsDesignMode)
|
||||
Rating = new Rating(5, 4, 3);
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
{
|
||||
if (change.Property.Name == nameof(Rating) && Rating is not null)
|
||||
{
|
||||
int rating = 0;
|
||||
foreach (TextBlock star in panelOverall.Children)
|
||||
star.Tag = star.Text = Rating.OverallRating > rating++ ? SOLID_STAR : HOLLOW_STAR;
|
||||
|
||||
rating = 0;
|
||||
foreach (TextBlock star in panelPerform.Children)
|
||||
star.Tag = star.Text = Rating.PerformanceRating > rating++ ? SOLID_STAR : HOLLOW_STAR;
|
||||
|
||||
rating = 0;
|
||||
foreach (TextBlock star in panelStory.Children)
|
||||
star.Tag = star.Text = Rating.StoryRating > rating++ ? SOLID_STAR : HOLLOW_STAR;
|
||||
|
||||
SetVisible(AllRatingsVisible);
|
||||
}
|
||||
base.OnPropertyChanged(change);
|
||||
}
|
||||
|
||||
private void SetVisible(bool allVisible)
|
||||
{
|
||||
tblockOverall.IsVisible = panelOverall.IsVisible = allVisible || Rating?.OverallRating > 0;
|
||||
tblockPerform.IsVisible = panelPerform.IsVisible = allVisible || Rating?.PerformanceRating > 0;
|
||||
tblockStory.IsVisible = panelStory.IsVisible = allVisible || Rating?.StoryRating > 0;
|
||||
}
|
||||
|
||||
public void Panel_PointerExited(object sender, Avalonia.Input.PointerEventArgs e)
|
||||
{
|
||||
var panel = sender as Panel;
|
||||
var stackPanel = panel.Children.OfType<StackPanel>().Single();
|
||||
|
||||
//Restore defaults
|
||||
foreach (TextBlock child in stackPanel.Children)
|
||||
child.Text = (string)child.Tag;
|
||||
}
|
||||
|
||||
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 newRatingValue = 0;
|
||||
foreach (var tbox in stackPanel.Children)
|
||||
{
|
||||
newRatingValue++;
|
||||
if (tbox == thisTbox) break;
|
||||
}
|
||||
|
||||
if (stackPanel == panelOverall)
|
||||
overall = newRatingValue;
|
||||
else if (stackPanel == panelPerform)
|
||||
perform = newRatingValue;
|
||||
else if (stackPanel == panelStory)
|
||||
story = newRatingValue;
|
||||
|
||||
if (overall + perform + story == 0f) return;
|
||||
|
||||
Rating = new Rating(overall, perform, story);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<DataGridBoundColumn 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.MyRatingGridColumn">
|
||||
|
||||
</DataGridBoundColumn>
|
||||
66
Source/LibationAvalonia/Controls/MyRatingGridColumn.axaml.cs
Normal file
66
Source/LibationAvalonia/Controls/MyRatingGridColumn.axaml.cs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.Media;
|
||||
using DataLayer;
|
||||
|
||||
namespace LibationAvalonia.Controls
|
||||
{
|
||||
public partial class MyRatingGridColumn : DataGridBoundColumn
|
||||
{
|
||||
private static Rating DefaultRating => new Rating(0, 0, 0);
|
||||
public MyRatingGridColumn()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
BindingTarget = MyRatingCellEditor.RatingProperty;
|
||||
}
|
||||
|
||||
protected override IControl GenerateElement(DataGridCell cell, object dataItem)
|
||||
{
|
||||
var myRatingElement = new MyRatingCellEditor
|
||||
{
|
||||
Name = "CellMyRatingDisplay",
|
||||
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Left,
|
||||
VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center,
|
||||
AllRatingsVisible = false,
|
||||
Margin = new Thickness(3),
|
||||
IsEnabled = false
|
||||
};
|
||||
|
||||
if (Binding != null)
|
||||
{
|
||||
myRatingElement.Bind(BindingTarget, Binding);
|
||||
}
|
||||
return myRatingElement;
|
||||
}
|
||||
|
||||
protected override IControl GenerateEditingElementDirect(DataGridCell cell, object dataItem)
|
||||
{
|
||||
var myRatingElement = new MyRatingCellEditor
|
||||
{
|
||||
Name = "CellMyRatingCellEditor",
|
||||
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Left,
|
||||
VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center,
|
||||
AllRatingsVisible = true,
|
||||
Margin = new Thickness(3)
|
||||
};
|
||||
|
||||
return myRatingElement;
|
||||
}
|
||||
|
||||
protected override object PrepareCellForEdit(IControl editingElement, RoutedEventArgs editingEventArgs)
|
||||
=> editingElement is MyRatingCellEditor myRating
|
||||
? myRating.Rating
|
||||
: DefaultRating;
|
||||
|
||||
protected override void CancelCellEdit(IControl editingElement, object uneditedValue)
|
||||
{
|
||||
if (editingElement is MyRatingCellEditor myRating)
|
||||
{
|
||||
var uneditedRating = uneditedValue as Rating;
|
||||
myRating.Rating = uneditedRating ?? DefaultRating;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,125 +0,0 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue