Last active
January 30, 2023 17:15
-
-
Save dhindrik/4aaa48d5f332222b3ca674cfd1447c6c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#nullable enable | |
using System; | |
using System.Collections.Generic; | |
using Xamarin.Forms; | |
using Xamarin.Forms.Shapes; | |
namespace ShapeDemo.Controls | |
{ | |
public class RatingControl : StackLayout | |
{ | |
public RatingControl() | |
{ | |
Orientation = StackOrientation.Horizontal; | |
} | |
public static BindableProperty RatingProperty = BindableProperty.Create(nameof(Rating), typeof(double), typeof(RatingControl), 0.0, BindingMode.OneWay, propertyChanged: (bindable, newValue, oldValue) => | |
{ | |
var control = (RatingControl)bindable; | |
if (newValue != oldValue) | |
{ | |
control.Draw(); | |
} | |
}); | |
private readonly List<Point> originalFullStarPoints = new List<Point>() | |
{ | |
new Point(96,1.12977573), | |
new Point(66.9427701,60.0061542), | |
new Point(1.96882894,69.4474205), | |
new Point(48.9844145,115.27629), | |
new Point(37.8855403,179.987692), | |
new Point(96,149.435112), | |
new Point(154.11446,179.987692), | |
new Point(143.015586,115.27629), | |
new Point(190.031171,69.4474205), | |
new Point(125.05723,60.0061542), | |
new Point(96,1.12977573), | |
}; | |
private readonly List<Point> originalHalfStarPoints = new List<Point>() | |
{ | |
new Point(96,1.12977573), | |
new Point(66.9427701,60.0061542), | |
new Point(1.96882894,69.4474205), | |
new Point(48.9844145,115.27629), | |
new Point(37.8855403,179.987692), | |
new Point(96,149.435112), | |
new Point(96,1.12977573) | |
}; | |
private readonly PointCollection fullStarPoints = new PointCollection(); | |
private readonly PointCollection halfStarPoints = new PointCollection(); | |
private double ratio; | |
private void Draw() | |
{ | |
Children.Clear(); | |
var newRatio = Size / 200; | |
if (newRatio != ratio) | |
{ | |
ratio = newRatio; | |
CalculatePoints(fullStarPoints, originalFullStarPoints); | |
CalculatePoints(halfStarPoints, originalHalfStarPoints); | |
} | |
for (var i = 1; i <= Max; i++) | |
{ | |
if (Rating >= i) | |
{ | |
Children.Add(GetFullStar()); | |
} | |
else if(Rating > i - 1) | |
{ | |
Children.Add(GetHalfStar()); | |
} | |
else | |
{ | |
Children.Add(GetEmptyStar()); | |
} | |
} | |
} | |
private void CalculatePoints(PointCollection calculated, List<Point> original) | |
{ | |
calculated.Clear(); | |
foreach (var point in original) | |
{ | |
var x = point.X * ratio; | |
var y = point.Y * ratio; | |
var p = new Point(x, y); | |
calculated.Add(p); | |
} | |
} | |
private Polygon GetFullStar() | |
{ | |
var fullStar = new Polygon() | |
{ | |
Points = fullStarPoints, | |
Fill = FillColor, | |
StrokeThickness = StrokeThickness, | |
Stroke = StrokeColor | |
}; | |
return fullStar; | |
} | |
private Grid GetHalfStar() | |
{ | |
var grid = new Grid(); | |
var halfStar = new Polygon() | |
{ | |
Points = halfStarPoints, | |
Fill = fillColor, | |
Stroke = Color.Transparent, | |
StrokeThickness = 0, | |
}; | |
var emptyStar = new Polygon() | |
{ | |
Points = fullStarPoints, | |
StrokeThickness = StrokeThickness, | |
Stroke = StrokeColor | |
}; | |
grid.Children.Add(halfStar); | |
grid.Children.Add(emptyStar); | |
return grid; | |
} | |
private Polygon GetEmptyStar() | |
{ | |
var emptyStar = new Polygon() | |
{ | |
Points = fullStarPoints, | |
StrokeThickness = StrokeThickness, | |
Stroke = StrokeColor | |
}; | |
return emptyStar; | |
} | |
public double Rating | |
{ | |
get => (double)GetValue(RatingProperty); | |
set => SetValue(RatingProperty, value); | |
} | |
private int max = 5; | |
public int Max | |
{ | |
get => max; | |
set => Set(ref max, value); | |
} | |
private void Set<T>(ref T field, T newValue) | |
{ | |
if (!EqualityComparer<T>.Default.Equals(field, newValue)) | |
{ | |
field = newValue; | |
Draw(); | |
} | |
} | |
private Color fillColor = Color.Yellow; | |
public Color FillColor | |
{ | |
get => fillColor; | |
set => Set(ref fillColor, value); | |
} | |
private Color strokeColor = Color.Black; | |
public Color StrokeColor | |
{ | |
get => strokeColor; | |
set => Set(ref strokeColor, value); | |
} | |
private double strokeThickness = 0; | |
public double StrokeThickness | |
{ | |
get => strokeThickness; | |
set => Set(ref strokeThickness, value); | |
} | |
private double size = 50; | |
public double Size | |
{ | |
get => size; | |
set => Set(ref size, value); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment