Improve classic and chardonnay rating editor simmilarity

This commit is contained in:
Michael Bucari-Tovo 2022-12-31 10:02:30 -07:00
parent c9497ef39e
commit 874bf9e7c0
14 changed files with 233 additions and 178 deletions

View File

@ -439,7 +439,7 @@ namespace ApplicationServices
udi.SetPdfStatus(pdfStatus); udi.SetPdfStatus(pdfStatus);
if (rating is not null) if (rating is not null)
udi.Rating = rating; udi.UpdateRating(rating.OverallRating, rating.PerformanceRating, rating.StoryRating);
}); });
public static int UpdateBookStatus(this Book book, LiberatedStatus bookStatus) public static int UpdateBookStatus(this Book book, LiberatedStatus bookStatus)
@ -497,7 +497,7 @@ namespace ApplicationServices
context.Attach(book.UserDefinedItem.Rating).State = Microsoft.EntityFrameworkCore.EntityState.Modified; context.Attach(book.UserDefinedItem.Rating).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
} }
var qtyChanges = context.SaveChanges(); var qtyChanges = context.SaveChanges();
if (qtyChanges > 0) if (qtyChanges > 0)
BookUserDefinedItemCommitted?.Invoke(null, books); BookUserDefinedItemCommitted?.Invoke(null, books);

View File

@ -95,9 +95,9 @@ namespace DataLayer
#region Rating #region Rating
// owned: not an optional one-to-one // owned: not an optional one-to-one
/// <summary>The user's individual book rating</summary> /// <summary>The user's individual book rating</summary>
public Rating Rating { get; set; } = new Rating(0, 0, 0); public Rating Rating { get; private set; } = new Rating(0, 0, 0);
public void UpdateRating(float overallRating, float performanceRating, float storyRating) public void UpdateRating(float overallRating, float performanceRating, float storyRating)
=> Rating.Update(overallRating, performanceRating, storyRating); => Rating.Update(overallRating, performanceRating, storyRating);
#endregion #endregion

View File

@ -3,49 +3,49 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" 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 ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto,Auto">
<Grid.Styles> <Grid.Styles>
<Style Selector="TextBlock"> <Style Selector="TextBlock">
<Setter Property="FontSize" Value="11" /> <Setter Property="FontSize" Value="11" />
</Style> </Style>
<Style Selector="StackPanel > TextBlock">
<Setter Property="Padding" Value="0,0,-2,0" />
</Style>
</Grid.Styles> </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="1" Name="tblockPerform" Text="Perform:" />
<TextBlock Grid.Column="0" Grid.Row="2" Name="tblockStory" Text="Story:" /> <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"> <Panel Background="Transparent" PointerExited="Panel_PointerExited" Grid.Column="1" Grid.Row="0">
<TextBlock Name="tblockOverallRating" /> <StackPanel Name="panelOverall" Orientation="Horizontal">
<StackPanel IsVisible="false" Orientation="Horizontal"> <TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" /> <TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" /> <TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" /> <TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" /> <TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
</StackPanel> </StackPanel>
</Panel> </Panel>
<Panel Background="Transparent" PointerEntered="Panel_PointerEntered" PointerExited="Panel_PointerExited" Grid.Column="1" Grid.Row="1"> <Panel Background="Transparent" PointerExited="Panel_PointerExited" Grid.Column="1" Grid.Row="1">
<TextBlock Name="tblockPerformRating" /> <StackPanel Name="panelPerform" Orientation="Horizontal">
<StackPanel IsVisible="false" Orientation="Horizontal"> <TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" /> <TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" /> <TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" /> <TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" /> <TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
</StackPanel> </StackPanel>
</Panel> </Panel>
<Panel Background="Transparent" PointerEntered="Panel_PointerEntered" PointerExited="Panel_PointerExited" Grid.Column="1" Grid.Row="2"> <Panel Background="Transparent" PointerExited="Panel_PointerExited" Grid.Column="1" Grid.Row="2">
<TextBlock Name="tblockStoryRating" /> <StackPanel Name="panelStory" Orientation="Horizontal">
<StackPanel IsVisible="false" Orientation="Horizontal"> <TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" /> <TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" /> <TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" /> <TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" /> <TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" />
<TextBlock PointerEntered="Star_PointerEntered" Tapped="Star_Tapped" Text="☆" />
</StackPanel> </StackPanel>
</Panel> </Panel>
</Grid> </Grid>

View 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);
}
}
}

View File

@ -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>

View 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;
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -45,7 +45,7 @@ namespace LibationAvalonia.ViewModels
public string Misc { get; protected set; } public string Misc { get; protected set; }
public string Description { get; protected set; } public string Description { get; protected set; }
public string ProductRating { get; protected set; } public string ProductRating { get; protected set; }
public string MyRatingString => Book.UserDefinedItem.Rating?.ToStarString()?.DefaultIfNullOrWhiteSpace(""); public string MyRatingString => MyRating?.ToStarString()?.DefaultIfNullOrWhiteSpace("");
protected Rating _myRating; protected Rating _myRating;
public Rating MyRating public Rating MyRating
{ {

View File

@ -65,7 +65,9 @@ namespace LibationAvalonia.ViewModels
Title = Book.Title; Title = Book.Title;
Series = Book.SeriesNames(); Series = Book.SeriesNames();
Length = Book.LengthInMinutes == 0 ? "" : $"{Book.LengthInMinutes / 60} hr {Book.LengthInMinutes % 60} min"; Length = Book.LengthInMinutes == 0 ? "" : $"{Book.LengthInMinutes / 60} hr {Book.LengthInMinutes % 60} min";
_myRating = Book.UserDefinedItem.Rating; //Ratings are changed using Update(), which is a problem for Avalonia data bindings because
//the reference doesn't change. Clone the rating so that it updates within Avalonia properly.
_myRating = new Rating(Book.UserDefinedItem.Rating.OverallRating, Book.UserDefinedItem.Rating.PerformanceRating, Book.UserDefinedItem.Rating.StoryRating);
PurchaseDate = libraryBook.DateAdded.ToString("d"); PurchaseDate = libraryBook.DateAdded.ToString("d");
ProductRating = Book.Rating?.ToStarString()?.DefaultIfNullOrWhiteSpace(""); ProductRating = Book.Rating?.ToStarString()?.DefaultIfNullOrWhiteSpace("");
Authors = Book.AuthorNames(); Authors = Book.AuthorNames();

View File

@ -68,7 +68,9 @@ namespace LibationAvalonia.ViewModels
Title = Book.Title; Title = Book.Title;
Series = Book.SeriesNames(); Series = Book.SeriesNames();
_myRating = Book.UserDefinedItem.Rating; //Ratings are changed using Update(), which is a problem for Avalonia data bindings because
//the reference doesn't change. Clone the rating so that it updates within Avalonia properly.
_myRating = new Rating(Book.UserDefinedItem.Rating.OverallRating, Book.UserDefinedItem.Rating.PerformanceRating, Book.UserDefinedItem.Rating.StoryRating);
ProductRating = Book.Rating?.ToStarString()?.DefaultIfNullOrWhiteSpace(""); ProductRating = Book.Rating?.ToStarString()?.DefaultIfNullOrWhiteSpace("");
Authors = Book.AuthorNames(); Authors = Book.AuthorNames();
Narrators = Book.NarratorNames(); Narrators = Book.NarratorNames();

View File

@ -140,7 +140,7 @@
</DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn.CellTemplate>
</controls:DataGridTemplateColumnExt> </controls:DataGridTemplateColumnExt>
<controls:DataGridTemplateColumnExt Width="120" Header="Product&#xA;Rating" CanUserSort="True" SortMemberPath="ProductRating" ClipboardContentBinding="{Binding ProductRating}"> <controls:DataGridTemplateColumnExt Width="115" Header="Product&#xA;Rating" CanUserSort="True" SortMemberPath="ProductRating" ClipboardContentBinding="{Binding ProductRating}">
<DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<Panel Background="{Binding BackgroundBrush}" Opacity="{Binding Opacity}"> <Panel Background="{Binding BackgroundBrush}" Opacity="{Binding Opacity}">
@ -160,16 +160,9 @@
</DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn.CellTemplate>
</controls:DataGridTemplateColumnExt> </controls:DataGridTemplateColumnExt>
<controls:DataGridTemplateColumnExt Width="120" Header="My Rating" CanUserSort="True" SortMemberPath="MyRating" ClipboardContentBinding="{Binding MyRatingString}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Panel Background="{Binding BackgroundBrush}" Opacity="{Binding Opacity}">
<controls:RatingBox Margin="4" VerticalAlignment="Center" Rating="{Binding MyRating, Mode=TwoWay}" />
</Panel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</controls:DataGridTemplateColumnExt>
<controls:MyRatingGridColumn IsReadOnly="false" Width="115" Header="My Rating" CanUserSort="True" SortMemberPath="MyRating" ClipboardContentBinding="{Binding MyRatingString}" Binding="{Binding MyRating, Mode=TwoWay}" />
<controls:DataGridTemplateColumnExt Width="135" Header="Misc" CanUserSort="True" SortMemberPath="Misc" ClipboardContentBinding="{Binding Misc}"> <controls:DataGridTemplateColumnExt Width="135" Header="Misc" CanUserSort="True" SortMemberPath="Misc" ClipboardContentBinding="{Binding Misc}">
<DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellTemplate>
<DataTemplate> <DataTemplate>

View File

@ -90,8 +90,8 @@ namespace LibationSearchEngine
["ProductRating"] = lb => lb.Book.Rating.OverallRating.ToLuceneString(), ["ProductRating"] = lb => lb.Book.Rating.OverallRating.ToLuceneString(),
["Rating"] = lb => lb.Book.Rating.OverallRating.ToLuceneString(), ["Rating"] = lb => lb.Book.Rating.OverallRating.ToLuceneString(),
["UserRating"] = lb => userRating(lb.Book), ["UserRating"] = lb => userOverallRating(lb.Book),
["MyRating"] = lb => userRating(lb.Book) ["MyRating"] = lb => userOverallRating(lb.Book)
} }
); );
@ -136,7 +136,7 @@ namespace LibationSearchEngine
var narrators = lb.Book.Narrators.Select(a => a.Name).ToArray(); var narrators = lb.Book.Narrators.Select(a => a.Name).ToArray();
return authors.Intersect(narrators).Any(); return authors.Intersect(narrators).Any();
} }
private static string userRating(Book book) => book.UserDefinedItem.Rating.OverallRating.ToLuceneString(); private static string userOverallRating(Book book) => book.UserDefinedItem.Rating.OverallRating.ToLuceneString();
private static bool isLiberated(Book book) => book.UserDefinedItem.BookStatus == LiberatedStatus.Liberated; private static bool isLiberated(Book book) => book.UserDefinedItem.BookStatus == LiberatedStatus.Liberated;
private static bool liberatedError(Book book) => book.UserDefinedItem.BookStatus == LiberatedStatus.Error; private static bool liberatedError(Book book) => book.UserDefinedItem.BookStatus == LiberatedStatus.Error;
@ -300,7 +300,7 @@ namespace LibationSearchEngine
// fields are key value pairs. MULTIPLE FIELDS CAN POTENTIALLY HAVE THE SAME KEY. // fields are key value pairs. MULTIPLE FIELDS CAN POTENTIALLY HAVE THE SAME KEY.
// ie: must remove old before adding new else will create unwanted duplicates. // ie: must remove old before adding new else will create unwanted duplicates.
var v1 = userRating(book); var v1 = userOverallRating(book);
d.RemoveField("UserRating"); d.RemoveField("UserRating");
d.AddNotAnalyzed("UserRating", v1); d.AddNotAnalyzed("UserRating", v1);
d.RemoveField("MyRating"); d.RemoveField("MyRating");

View File

@ -39,10 +39,10 @@ namespace LibationWinForms.GridView
private void Star_MouseEnter(object sender, EventArgs e) private void Star_MouseEnter(object sender, EventArgs e)
{ {
var thisTbox = sender as Label; var thisTbox = sender as Label;
var stackPanel = thisTbox.Parent as Panel; var panel = thisTbox.Parent as Panel;
var star = SOLID_STAR; var star = SOLID_STAR;
foreach (Label child in stackPanel.Controls) foreach (Label child in panel.Controls)
{ {
child.Text = star; child.Text = star;
if (child == thisTbox) star = HOLLOW_STAR; if (child == thisTbox) star = HOLLOW_STAR;

View File

@ -26,7 +26,7 @@ namespace LibationWinForms.GridView
internal class MyRatingGridViewCell : DataGridViewTextBoxCell internal class MyRatingGridViewCell : DataGridViewTextBoxCell
{ {
private Rating DefaultRating => new Rating(0, 0, 0); private static Rating DefaultRating => new Rating(0, 0, 0);
public override object DefaultNewRowValue => DefaultRating; public override object DefaultNewRowValue => DefaultRating;
public override Type EditType => typeof(MyRatingCellEditor); public override Type EditType => typeof(MyRatingCellEditor);
public override Type ValueType => typeof(Rating); public override Type ValueType => typeof(Rating);
@ -45,6 +45,7 @@ namespace LibationWinForms.GridView
if (value is Rating rating) if (value is Rating rating)
{ {
var starString = rating.ToStarString(); var starString = rating.ToStarString();
ToolTipText = starString;
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, starString, starString, errorText, cellStyle, advancedBorderStyle, paintParts); base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, starString, starString, errorText, cellStyle, advancedBorderStyle, paintParts);
} }
else else