From f20e874c284be3e54ae37698334c146f872b9e0d Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Tue, 18 Dec 2018 13:35:54 -0500 Subject: [PATCH 1/7] Attempting to create a pull request status circle --- .../PullRequestListItemViewModelDesigner.cs | 3 + src/GitHub.App/Services/PullRequestService.cs | 36 ++- .../PullRequestListItemViewModel.cs | 12 + .../IPullRequestListItemViewModel.cs | 15 ++ .../Models/PullRequestListItemModel.cs | 15 ++ .../UI/Controls/PullRequestStatusCircle.xaml | 59 +++++ .../Controls/PullRequestStatusCircle.xaml.cs | 227 ++++++++++++++++++ .../GitHubPane/PullRequestListItemView.xaml | 13 +- 8 files changed, 375 insertions(+), 5 deletions(-) create mode 100644 src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml create mode 100644 src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs diff --git a/src/GitHub.App/SampleData/PullRequestListItemViewModelDesigner.cs b/src/GitHub.App/SampleData/PullRequestListItemViewModelDesigner.cs index 500089fb84..19b7037b6e 100644 --- a/src/GitHub.App/SampleData/PullRequestListItemViewModelDesigner.cs +++ b/src/GitHub.App/SampleData/PullRequestListItemViewModelDesigner.cs @@ -18,5 +18,8 @@ public class PullRequestListItemViewModelDesigner : ViewModelBase, IPullRequestL public string Title { get; set; } public DateTimeOffset UpdatedAt { get; set; } public PullRequestChecksState Checks { get; set; } + public int ChecksPendingCount { get; set; } + public int ChecksSuccessCount { get; set; } + public int ChecksErrorCount { get; set; } } } diff --git a/src/GitHub.App/Services/PullRequestService.cs b/src/GitHub.App/Services/PullRequestService.cs index abfc1feac1..566bcb9d68 100644 --- a/src/GitHub.App/Services/PullRequestService.cs +++ b/src/GitHub.App/Services/PullRequestService.cs @@ -217,9 +217,10 @@ public async Task> ReadPullRequests( item.Reviews = null; var checkRuns = item.LastCommit?.CheckSuites?.SelectMany(model => model.CheckRuns).ToArray(); + var statuses = item.LastCommit?.Statuses; var hasCheckRuns = checkRuns?.Any() ?? false; - var hasStatuses = item.LastCommit?.Statuses?.Any() ?? false; + var hasStatuses = statuses?.Any() ?? false; if (!hasCheckRuns && !hasStatuses) { @@ -277,6 +278,39 @@ public async Task> ReadPullRequests( } } + var pendingCount = 0; + var successCount = 0; + var errorCount = 0; + + if (checkRuns != null) + { + pendingCount += checkRuns.Count(model => model.Status != CheckStatusState.Completed); + + successCount += checkRuns.Count(model => model.Status == CheckStatusState.Completed && + model.Conclusion.HasValue && + (model.Conclusion == CheckConclusionState.Success || + model.Conclusion == CheckConclusionState.Neutral)); + errorCount += checkRuns.Count(model => model.Status == CheckStatusState.Completed && + model.Conclusion.HasValue && + !(model.Conclusion == CheckConclusionState.Success || + model.Conclusion == CheckConclusionState.Neutral)); + } + + if (statuses != null) + { + pendingCount += statuses.Count(model => + model.State == StatusState.Pending || model.State == StatusState.Expected); + + successCount += statuses.Count(model => model.State == StatusState.Success); + + errorCount += statuses.Count(model => + model.State == StatusState.Error || model.State == StatusState.Failure); + } + + item.ChecksPendingCount = pendingCount; + item.ChecksSuccessCount = successCount; + item.ChecksErrorCount = errorCount; + item.LastCommit = null; } diff --git a/src/GitHub.App/ViewModels/GitHubPane/PullRequestListItemViewModel.cs b/src/GitHub.App/ViewModels/GitHubPane/PullRequestListItemViewModel.cs index b60cf0e70b..66c8cc6664 100644 --- a/src/GitHub.App/ViewModels/GitHubPane/PullRequestListItemViewModel.cs +++ b/src/GitHub.App/ViewModels/GitHubPane/PullRequestListItemViewModel.cs @@ -20,6 +20,9 @@ public PullRequestListItemViewModel(PullRequestListItemModel model) Id = model.Id; Author = new ActorViewModel(model.Author); Checks = model.Checks; + ChecksErrorCount = model.ChecksErrorCount; + ChecksPendingCount = model.ChecksPendingCount; + ChecksSuccessCount = model.ChecksSuccessCount; CommentCount = model.CommentCount; Number = model.Number; Title = model.Title; @@ -35,6 +38,15 @@ public PullRequestListItemViewModel(PullRequestListItemModel model) /// public PullRequestChecksState Checks { get; } + /// + public int ChecksSuccessCount { get; } + + /// + public int ChecksPendingCount { get; } + + /// + public int ChecksErrorCount { get; } + /// public int CommentCount { get; } diff --git a/src/GitHub.Exports.Reactive/ViewModels/GitHubPane/IPullRequestListItemViewModel.cs b/src/GitHub.Exports.Reactive/ViewModels/GitHubPane/IPullRequestListItemViewModel.cs index f8fa89c351..cf145bd99e 100644 --- a/src/GitHub.Exports.Reactive/ViewModels/GitHubPane/IPullRequestListItemViewModel.cs +++ b/src/GitHub.Exports.Reactive/ViewModels/GitHubPane/IPullRequestListItemViewModel.cs @@ -33,5 +33,20 @@ public interface IPullRequestListItemViewModel : IIssueListItemViewModelBase /// Gets the pull request checks and statuses summary /// PullRequestChecksState Checks { get; } + + /// + /// Gets the number of pending checks and statuses + /// + int ChecksPendingCount { get; } + + /// + /// Gets the number of successful checks and statuses + /// + int ChecksSuccessCount { get; } + + /// + /// Gets the number of erroneous checks and statuses + /// + int ChecksErrorCount { get; } } } diff --git a/src/GitHub.Exports/Models/PullRequestListItemModel.cs b/src/GitHub.Exports/Models/PullRequestListItemModel.cs index f6a9a7fe55..a002ce127e 100644 --- a/src/GitHub.Exports/Models/PullRequestListItemModel.cs +++ b/src/GitHub.Exports/Models/PullRequestListItemModel.cs @@ -42,6 +42,21 @@ public class PullRequestListItemModel /// public PullRequestChecksState Checks { get; set; } + /// + /// Gets the number of pending checks and statuses + /// + public int ChecksPendingCount { get; set; } + + /// + /// Gets the number of successful checks and statuses + /// + public int ChecksSuccessCount { get; set; } + + /// + /// Gets the number of erroneous checks and statuses + /// + public int ChecksErrorCount { get; set; } + /// /// Gets or sets the date/time at which the pull request was last updated. /// diff --git a/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml new file mode 100644 index 0000000000..6136886e9e --- /dev/null +++ b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs new file mode 100644 index 0000000000..235832f2e5 --- /dev/null +++ b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs @@ -0,0 +1,227 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using ReactiveUI; + +namespace GitHub.VisualStudio.UI.UI.Controls +{ + /// + /// Interaction logic for PullRequestStatusCircle.xaml + /// + public partial class PullRequestStatusCircle : UserControl + { + public static readonly DependencyProperty ErrorCountProperty = DependencyProperty.Register( + "ErrorCount", typeof(int), typeof(PullRequestStatusCircle), new PropertyMetadata(0)); + + public static readonly DependencyProperty SuccessCountProperty = DependencyProperty.Register( + "SuccessCount", typeof(int), typeof(PullRequestStatusCircle), new PropertyMetadata(0)); + + public static readonly DependencyProperty PendingCountProperty = DependencyProperty.Register( + "PendingCount", typeof(int), typeof(PullRequestStatusCircle), new PropertyMetadata(0)); + + public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register( + "Radius", typeof(double), typeof(PullRequestStatusCircle), new PropertyMetadata((double)250)); + + public static readonly DependencyProperty InnerRadiusProperty = DependencyProperty.Register( + "InnerRadius", typeof(double), typeof(PullRequestStatusCircle), new PropertyMetadata((double)200)); + + public static IEnumerable GeneratePoints(double size, float percentage) + { + if (percentage < 0 || percentage > 1) + { + throw new ArgumentException(); + } + + var halfSize = size / 2; + var origin = new Point(halfSize, halfSize); + var topMiddle = new Point(halfSize, 0); + var topRight = new Point(size, 0); + var bottomRight = new Point(size, size); + var bottomLeft = new Point(0, size); + var topLeft = new Point(0, 0); + + if (percentage == 1) + { + return new[] { topLeft, topRight, bottomRight, bottomLeft }; + } + + var degrees = percentage * 360; + var adjustedDegrees = (degrees + 90) % 360; + + if (adjustedDegrees >= 90 && adjustedDegrees < 135) + { + var angleDegrees = adjustedDegrees - 90; + var angleRadians = ToRadians(angleDegrees); + var tan = Math.Tan(angleRadians); + var oppositeEdge = tan * halfSize; + return new[] { origin, topMiddle, new Point(halfSize + oppositeEdge, 0) }; + } + + if (adjustedDegrees >= 135 && adjustedDegrees < 180) + { + var angleDegrees = adjustedDegrees - 135; + var angleRadians = ToRadians(angleDegrees); + var tan = Math.Tan(angleRadians); + var oppositeEdge = tan * halfSize; + return new[] { origin, topMiddle, topRight, new Point(size, oppositeEdge) }; + } + + if (adjustedDegrees >= 180 && adjustedDegrees < 225) + { + var angleDegrees = adjustedDegrees - 180; + var angleRadians = ToRadians(angleDegrees); + var tan = Math.Tan(angleRadians); + var oppositeEdge = tan * halfSize; + return new[] { origin, topMiddle, topRight, new Point(size, halfSize + oppositeEdge) }; + } + + if (adjustedDegrees >= 225 && adjustedDegrees < 270) + { + var angleDegrees = adjustedDegrees - 225; + var angleRadians = ToRadians(angleDegrees); + var tan = Math.Tan(angleRadians); + var oppositeEdge = tan * halfSize; + return new[] { origin, topMiddle, topRight, bottomRight, new Point(size - oppositeEdge, size) }; + } + + if (adjustedDegrees >= 270 && adjustedDegrees < 315) + { + var angleDegrees = adjustedDegrees - 270; + var angleRadians = ToRadians(angleDegrees); + var tan = Math.Tan(angleRadians); + var oppositeEdge = tan * halfSize; + return new[] { origin, topMiddle, topRight, bottomRight, new Point(halfSize - oppositeEdge, size) }; + } + + if (adjustedDegrees >= 315 && adjustedDegrees < 360) + { + var angleDegrees = adjustedDegrees - 315; + var angleRadians = ToRadians(angleDegrees); + var tan = Math.Tan(angleRadians); + var oppositeEdge = tan * halfSize; + return new[] { origin, topMiddle, topRight, bottomRight, bottomLeft, new Point(0, size - oppositeEdge) }; + } + + if (adjustedDegrees >= 0 && adjustedDegrees < 45) + { + var angleDegrees = adjustedDegrees; + var angleRadians = ToRadians(angleDegrees); + var tan = Math.Tan(angleRadians); + var oppositeEdge = tan * halfSize; + return new[] { origin, topMiddle, topRight, bottomRight, bottomLeft, new Point(0, halfSize - oppositeEdge) }; + } + + if (adjustedDegrees >= 45 && adjustedDegrees < 90) + { + var angleDegrees = adjustedDegrees - 45; + var angleRadians = ToRadians(angleDegrees); + var tan = Math.Tan(angleRadians); + var oppositeEdge = tan * halfSize; + return new[] { origin, topMiddle, topRight, bottomRight, bottomLeft, topLeft, new Point(oppositeEdge, 0) }; + } + + return new Point[0]; + } + + public static double ToRadians(float val) + { + return (Math.PI / 180) * val; + } + + public PullRequestStatusCircle() + { + InitializeComponent(); + GeneratePolygons(); + ComputeMask(); + } + + private void GeneratePolygons() + { + ErrorPolygon.Points = new PointCollection(GeneratePoints(Radius * 2, (float)ErrorCount / TotalCount)); + SuccessPolygon.Points = new PointCollection(GeneratePoints(Radius * 2, (float)(SuccessCount + ErrorCount) / TotalCount)); + PendingPolygon.Points = new PointCollection(GeneratePoints(Radius * 2, (float)(SuccessCount + ErrorCount + PendingCount) / TotalCount)); + } + + private void ComputeMask() + { + var pendingPolygonClip = new CombinedGeometry( + GeometryCombineMode.Exclude, + new EllipseGeometry(Center, Radius, Radius), + new EllipseGeometry(Center, InnerRadius, InnerRadius)); + + PendingPolygon.Clip = pendingPolygonClip; + SuccessPolygon.Clip = pendingPolygonClip; + ErrorPolygon.Clip = pendingPolygonClip; + } + + private int TotalCount => ErrorCount + SuccessCount + PendingCount; + + private Point Center => new Point(Radius, Radius); + + public int ErrorCount + { + get => (int)GetValue(ErrorCountProperty); + set + { + SetValue(ErrorCountProperty, value); + ComputeMask(); + GeneratePolygons(); + } + } + + public int SuccessCount + { + get => (int)GetValue(SuccessCountProperty); + set + { + SetValue(SuccessCountProperty, value); + ComputeMask(); + GeneratePolygons(); + } + } + + public int PendingCount + { + get => (int)GetValue(PendingCountProperty); + set + { + SetValue(PendingCountProperty, value); + ComputeMask(); + GeneratePolygons(); + } + } + + public double Radius + { + get => (double)GetValue(RadiusProperty); + set + { + SetValue(RadiusProperty, value); + ComputeMask(); + GeneratePolygons(); + } + } + + public double InnerRadius + { + get => (double)GetValue(InnerRadiusProperty); + set + { + SetValue(InnerRadiusProperty, value); + ComputeMask(); + GeneratePolygons(); + } + } + } +} diff --git a/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml b/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml index 4d7e261552..3d9dac6cc4 100644 --- a/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml +++ b/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml @@ -5,6 +5,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:ghfvs="https://github.com/github/VisualStudio" xmlns:views="clr-namespace:GitHub.VisualStudio.Views" + xmlns:controls="clr-namespace:GitHub.VisualStudio.UI.UI.Controls" mc:Ignorable="d" d:DesignWidth="300" Padding="0 4"> @@ -95,12 +96,16 @@ - + - - - + From 3a3514a877cec74e0a6655370fa3382cf6c34bed Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Wed, 19 Dec 2018 10:22:16 -0500 Subject: [PATCH 2/7] Fixing Dependency Property --- .../Controls/PullRequestStatusCircle.xaml.cs | 68 +++++++++++-------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs index 235832f2e5..f0d4b11531 100644 --- a/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs +++ b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs @@ -22,33 +22,43 @@ namespace GitHub.VisualStudio.UI.UI.Controls public partial class PullRequestStatusCircle : UserControl { public static readonly DependencyProperty ErrorCountProperty = DependencyProperty.Register( - "ErrorCount", typeof(int), typeof(PullRequestStatusCircle), new PropertyMetadata(0)); + "ErrorCount", typeof(int), typeof(PullRequestStatusCircle), + new PropertyMetadata(0, (d, args) => ((PullRequestStatusCircle)d).ErrorCount = (int)args.NewValue)); public static readonly DependencyProperty SuccessCountProperty = DependencyProperty.Register( - "SuccessCount", typeof(int), typeof(PullRequestStatusCircle), new PropertyMetadata(0)); + "SuccessCount", typeof(int), typeof(PullRequestStatusCircle), + new PropertyMetadata(0, (d, args) => ((PullRequestStatusCircle)d).SuccessCount = (int)args.NewValue)); public static readonly DependencyProperty PendingCountProperty = DependencyProperty.Register( - "PendingCount", typeof(int), typeof(PullRequestStatusCircle), new PropertyMetadata(0)); + "PendingCount", typeof(int), typeof(PullRequestStatusCircle), + new PropertyMetadata(0, (d, args) => ((PullRequestStatusCircle)d).PendingCount = (int)args.NewValue)); public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register( - "Radius", typeof(double), typeof(PullRequestStatusCircle), new PropertyMetadata((double)250)); + "Radius", typeof(double), typeof(PullRequestStatusCircle), + new PropertyMetadata((double)250, (d, args) => ((PullRequestStatusCircle)d).Radius = (double)args.NewValue)); public static readonly DependencyProperty InnerRadiusProperty = DependencyProperty.Register( - "InnerRadius", typeof(double), typeof(PullRequestStatusCircle), new PropertyMetadata((double)200)); + "InnerRadius", typeof(double), typeof(PullRequestStatusCircle), + new PropertyMetadata((double)200, (d, args) => ((PullRequestStatusCircle)d).InnerRadius = (double)args.NewValue)); - public static IEnumerable GeneratePoints(double size, float percentage) + public static IEnumerable GeneratePoints(double diameter, float percentage) { + if (float.IsNaN(percentage)) + { + return Array.Empty(); + } + if (percentage < 0 || percentage > 1) { - throw new ArgumentException(); + throw new ArgumentException($@"`{nameof(percentage)}` must be >=0 and <=1", nameof(percentage)); } - var halfSize = size / 2; - var origin = new Point(halfSize, halfSize); - var topMiddle = new Point(halfSize, 0); - var topRight = new Point(size, 0); - var bottomRight = new Point(size, size); - var bottomLeft = new Point(0, size); + var radius = diameter / 2; + var origin = new Point(radius, radius); + var topMiddle = new Point(radius, 0); + var topRight = new Point(diameter, 0); + var bottomRight = new Point(diameter, diameter); + var bottomLeft = new Point(0, diameter); var topLeft = new Point(0, 0); if (percentage == 1) @@ -64,8 +74,8 @@ public static IEnumerable GeneratePoints(double size, float percentage) var angleDegrees = adjustedDegrees - 90; var angleRadians = ToRadians(angleDegrees); var tan = Math.Tan(angleRadians); - var oppositeEdge = tan * halfSize; - return new[] { origin, topMiddle, new Point(halfSize + oppositeEdge, 0) }; + var oppositeEdge = tan * radius; + return new[] { origin, topMiddle, new Point(radius + oppositeEdge, 0) }; } if (adjustedDegrees >= 135 && adjustedDegrees < 180) @@ -73,8 +83,8 @@ public static IEnumerable GeneratePoints(double size, float percentage) var angleDegrees = adjustedDegrees - 135; var angleRadians = ToRadians(angleDegrees); var tan = Math.Tan(angleRadians); - var oppositeEdge = tan * halfSize; - return new[] { origin, topMiddle, topRight, new Point(size, oppositeEdge) }; + var oppositeEdge = tan * radius; + return new[] { origin, topMiddle, topRight, new Point(diameter, oppositeEdge) }; } if (adjustedDegrees >= 180 && adjustedDegrees < 225) @@ -82,8 +92,8 @@ public static IEnumerable GeneratePoints(double size, float percentage) var angleDegrees = adjustedDegrees - 180; var angleRadians = ToRadians(angleDegrees); var tan = Math.Tan(angleRadians); - var oppositeEdge = tan * halfSize; - return new[] { origin, topMiddle, topRight, new Point(size, halfSize + oppositeEdge) }; + var oppositeEdge = tan * radius; + return new[] { origin, topMiddle, topRight, new Point(diameter, radius + oppositeEdge) }; } if (adjustedDegrees >= 225 && adjustedDegrees < 270) @@ -91,8 +101,8 @@ public static IEnumerable GeneratePoints(double size, float percentage) var angleDegrees = adjustedDegrees - 225; var angleRadians = ToRadians(angleDegrees); var tan = Math.Tan(angleRadians); - var oppositeEdge = tan * halfSize; - return new[] { origin, topMiddle, topRight, bottomRight, new Point(size - oppositeEdge, size) }; + var oppositeEdge = tan * radius; + return new[] { origin, topMiddle, topRight, bottomRight, new Point(diameter - oppositeEdge, diameter) }; } if (adjustedDegrees >= 270 && adjustedDegrees < 315) @@ -100,8 +110,8 @@ public static IEnumerable GeneratePoints(double size, float percentage) var angleDegrees = adjustedDegrees - 270; var angleRadians = ToRadians(angleDegrees); var tan = Math.Tan(angleRadians); - var oppositeEdge = tan * halfSize; - return new[] { origin, topMiddle, topRight, bottomRight, new Point(halfSize - oppositeEdge, size) }; + var oppositeEdge = tan * radius; + return new[] { origin, topMiddle, topRight, bottomRight, new Point(radius - oppositeEdge, diameter) }; } if (adjustedDegrees >= 315 && adjustedDegrees < 360) @@ -109,8 +119,8 @@ public static IEnumerable GeneratePoints(double size, float percentage) var angleDegrees = adjustedDegrees - 315; var angleRadians = ToRadians(angleDegrees); var tan = Math.Tan(angleRadians); - var oppositeEdge = tan * halfSize; - return new[] { origin, topMiddle, topRight, bottomRight, bottomLeft, new Point(0, size - oppositeEdge) }; + var oppositeEdge = tan * radius; + return new[] { origin, topMiddle, topRight, bottomRight, bottomLeft, new Point(0, diameter - oppositeEdge) }; } if (adjustedDegrees >= 0 && adjustedDegrees < 45) @@ -118,8 +128,8 @@ public static IEnumerable GeneratePoints(double size, float percentage) var angleDegrees = adjustedDegrees; var angleRadians = ToRadians(angleDegrees); var tan = Math.Tan(angleRadians); - var oppositeEdge = tan * halfSize; - return new[] { origin, topMiddle, topRight, bottomRight, bottomLeft, new Point(0, halfSize - oppositeEdge) }; + var oppositeEdge = tan * radius; + return new[] { origin, topMiddle, topRight, bottomRight, bottomLeft, new Point(0, radius - oppositeEdge) }; } if (adjustedDegrees >= 45 && adjustedDegrees < 90) @@ -127,11 +137,11 @@ public static IEnumerable GeneratePoints(double size, float percentage) var angleDegrees = adjustedDegrees - 45; var angleRadians = ToRadians(angleDegrees); var tan = Math.Tan(angleRadians); - var oppositeEdge = tan * halfSize; + var oppositeEdge = tan * radius; return new[] { origin, topMiddle, topRight, bottomRight, bottomLeft, topLeft, new Point(oppositeEdge, 0) }; } - return new Point[0]; + throw new InvalidOperationException(); } public static double ToRadians(float val) From 2526f5577e3bdde5f42335a6906991cd614d6b2a Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Wed, 19 Dec 2018 10:22:25 -0500 Subject: [PATCH 3/7] Displaying the circle int he middle of the available area; Cleaning up display logic --- .../UI/Controls/PullRequestStatusCircle.xaml | 6 - .../Controls/PullRequestStatusCircle.xaml.cs | 106 ++++++++++-------- .../GitHubPane/PullRequestListItemView.xaml | 4 +- 3 files changed, 64 insertions(+), 52 deletions(-) diff --git a/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml index 6136886e9e..4d2c0884d8 100644 --- a/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml +++ b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml @@ -8,8 +8,6 @@ d:DesignHeight="250" d:DesignWidth="250"> @@ -24,8 +22,6 @@ @@ -40,8 +36,6 @@ diff --git a/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs index f0d4b11531..47caadfc07 100644 --- a/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs +++ b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs @@ -41,8 +41,13 @@ public partial class PullRequestStatusCircle : UserControl "InnerRadius", typeof(double), typeof(PullRequestStatusCircle), new PropertyMetadata((double)200, (d, args) => ((PullRequestStatusCircle)d).InnerRadius = (double)args.NewValue)); - public static IEnumerable GeneratePoints(double diameter, float percentage) + public IEnumerable GeneratePoints(float percentage) { + double ToRadians(float val) + { + return (Math.PI / 180) * val; + } + if (float.IsNaN(percentage)) { return Array.Empty(); @@ -50,16 +55,21 @@ public static IEnumerable GeneratePoints(double diameter, float percentag if (percentage < 0 || percentage > 1) { - throw new ArgumentException($@"`{nameof(percentage)}` must be >=0 and <=1", nameof(percentage)); + throw new ArgumentException(); } - var radius = diameter / 2; - var origin = new Point(radius, radius); - var topMiddle = new Point(radius, 0); - var topRight = new Point(diameter, 0); - var bottomRight = new Point(diameter, diameter); - var bottomLeft = new Point(0, diameter); - var topLeft = new Point(0, 0); + var diameter = Diameter; + + var leftEdge = XAdjust; + var rightEdge = diameter + XAdjust; + var topEdge = YAdjust; + var bottomEdge = diameter + YAdjust; + + var topMiddle = new Point(Origin.X, topEdge); + var topRight = new Point(rightEdge, topEdge); + var bottomRight = new Point(rightEdge, bottomEdge); + var bottomLeft = new Point(leftEdge, bottomEdge); + var topLeft = new Point(leftEdge, topEdge); if (percentage == 1) { @@ -74,8 +84,8 @@ public static IEnumerable GeneratePoints(double diameter, float percentag var angleDegrees = adjustedDegrees - 90; var angleRadians = ToRadians(angleDegrees); var tan = Math.Tan(angleRadians); - var oppositeEdge = tan * radius; - return new[] { origin, topMiddle, new Point(radius + oppositeEdge, 0) }; + var oppositeEdge = tan * Radius; + return new[] { Origin, topMiddle, new Point(topMiddle.X + oppositeEdge, topMiddle.Y) }; } if (adjustedDegrees >= 135 && adjustedDegrees < 180) @@ -83,8 +93,8 @@ public static IEnumerable GeneratePoints(double diameter, float percentag var angleDegrees = adjustedDegrees - 135; var angleRadians = ToRadians(angleDegrees); var tan = Math.Tan(angleRadians); - var oppositeEdge = tan * radius; - return new[] { origin, topMiddle, topRight, new Point(diameter, oppositeEdge) }; + var oppositeEdge = tan * Radius; + return new[] { Origin, topMiddle, topRight, new Point(topRight.X, topRight.Y + oppositeEdge) }; } if (adjustedDegrees >= 180 && adjustedDegrees < 225) @@ -92,8 +102,8 @@ public static IEnumerable GeneratePoints(double diameter, float percentag var angleDegrees = adjustedDegrees - 180; var angleRadians = ToRadians(angleDegrees); var tan = Math.Tan(angleRadians); - var oppositeEdge = tan * radius; - return new[] { origin, topMiddle, topRight, new Point(diameter, radius + oppositeEdge) }; + var oppositeEdge = tan * Radius; + return new[] { Origin, topMiddle, topRight, new Point(topRight.X, topRight.Y + Radius + oppositeEdge) }; } if (adjustedDegrees >= 225 && adjustedDegrees < 270) @@ -101,8 +111,8 @@ public static IEnumerable GeneratePoints(double diameter, float percentag var angleDegrees = adjustedDegrees - 225; var angleRadians = ToRadians(angleDegrees); var tan = Math.Tan(angleRadians); - var oppositeEdge = tan * radius; - return new[] { origin, topMiddle, topRight, bottomRight, new Point(diameter - oppositeEdge, diameter) }; + var oppositeEdge = tan * Radius; + return new[] { Origin, topMiddle, topRight, bottomRight, new Point(bottomRight.X - oppositeEdge, bottomRight.Y) }; } if (adjustedDegrees >= 270 && adjustedDegrees < 315) @@ -110,8 +120,8 @@ public static IEnumerable GeneratePoints(double diameter, float percentag var angleDegrees = adjustedDegrees - 270; var angleRadians = ToRadians(angleDegrees); var tan = Math.Tan(angleRadians); - var oppositeEdge = tan * radius; - return new[] { origin, topMiddle, topRight, bottomRight, new Point(radius - oppositeEdge, diameter) }; + var oppositeEdge = tan * Radius; + return new[] { Origin, topMiddle, topRight, bottomRight, new Point(bottomRight.X - Radius - oppositeEdge, bottomRight.Y) }; } if (adjustedDegrees >= 315 && adjustedDegrees < 360) @@ -119,8 +129,8 @@ public static IEnumerable GeneratePoints(double diameter, float percentag var angleDegrees = adjustedDegrees - 315; var angleRadians = ToRadians(angleDegrees); var tan = Math.Tan(angleRadians); - var oppositeEdge = tan * radius; - return new[] { origin, topMiddle, topRight, bottomRight, bottomLeft, new Point(0, diameter - oppositeEdge) }; + var oppositeEdge = tan * Radius; + return new[] { Origin, topMiddle, topRight, bottomRight, bottomLeft, new Point(bottomLeft.X, bottomLeft.Y - oppositeEdge) }; } if (adjustedDegrees >= 0 && adjustedDegrees < 45) @@ -128,8 +138,8 @@ public static IEnumerable GeneratePoints(double diameter, float percentag var angleDegrees = adjustedDegrees; var angleRadians = ToRadians(angleDegrees); var tan = Math.Tan(angleRadians); - var oppositeEdge = tan * radius; - return new[] { origin, topMiddle, topRight, bottomRight, bottomLeft, new Point(0, radius - oppositeEdge) }; + var oppositeEdge = tan * Radius; + return new[] { Origin, topMiddle, topRight, bottomRight, bottomLeft, new Point(bottomLeft.X, bottomLeft.Y - Radius - oppositeEdge) }; } if (adjustedDegrees >= 45 && adjustedDegrees < 90) @@ -137,47 +147,48 @@ public static IEnumerable GeneratePoints(double diameter, float percentag var angleDegrees = adjustedDegrees - 45; var angleRadians = ToRadians(angleDegrees); var tan = Math.Tan(angleRadians); - var oppositeEdge = tan * radius; - return new[] { origin, topMiddle, topRight, bottomRight, bottomLeft, topLeft, new Point(oppositeEdge, 0) }; + var oppositeEdge = tan * Radius; + return new[] { Origin, topMiddle, topRight, bottomRight, bottomLeft, topLeft, new Point(topLeft.X + oppositeEdge, topLeft.Y) }; } throw new InvalidOperationException(); } - public static double ToRadians(float val) - { - return (Math.PI / 180) * val; - } - public PullRequestStatusCircle() { InitializeComponent(); GeneratePolygons(); - ComputeMask(); + GenerateMask(); } private void GeneratePolygons() { - ErrorPolygon.Points = new PointCollection(GeneratePoints(Radius * 2, (float)ErrorCount / TotalCount)); - SuccessPolygon.Points = new PointCollection(GeneratePoints(Radius * 2, (float)(SuccessCount + ErrorCount) / TotalCount)); - PendingPolygon.Points = new PointCollection(GeneratePoints(Radius * 2, (float)(SuccessCount + ErrorCount + PendingCount) / TotalCount)); + ErrorPolygon.Points = new PointCollection(GeneratePoints((float)ErrorCount / TotalCount)); + SuccessPolygon.Points = new PointCollection(GeneratePoints((float)(SuccessCount + ErrorCount) / TotalCount)); + PendingPolygon.Points = new PointCollection(GeneratePoints((float)(SuccessCount + ErrorCount + PendingCount) / TotalCount)); } - private void ComputeMask() + private void GenerateMask() { var pendingPolygonClip = new CombinedGeometry( GeometryCombineMode.Exclude, - new EllipseGeometry(Center, Radius, Radius), - new EllipseGeometry(Center, InnerRadius, InnerRadius)); + new EllipseGeometry(Origin, Radius, Radius), + new EllipseGeometry(Origin, InnerRadius, InnerRadius)); PendingPolygon.Clip = pendingPolygonClip; SuccessPolygon.Clip = pendingPolygonClip; ErrorPolygon.Clip = pendingPolygonClip; } - private int TotalCount => ErrorCount + SuccessCount + PendingCount; + private Point Origin => new Point(Radius + XAdjust, Radius + YAdjust); + + private double Diameter => Radius * 2; - private Point Center => new Point(Radius, Radius); + private double XAdjust => (ActualWidth - Diameter) / 2; + + private double YAdjust => (ActualHeight - Diameter) / 2; + + private int TotalCount => ErrorCount + SuccessCount + PendingCount; public int ErrorCount { @@ -185,7 +196,6 @@ public int ErrorCount set { SetValue(ErrorCountProperty, value); - ComputeMask(); GeneratePolygons(); } } @@ -196,7 +206,6 @@ public int SuccessCount set { SetValue(SuccessCountProperty, value); - ComputeMask(); GeneratePolygons(); } } @@ -207,7 +216,6 @@ public int PendingCount set { SetValue(PendingCountProperty, value); - ComputeMask(); GeneratePolygons(); } } @@ -218,7 +226,7 @@ public double Radius set { SetValue(RadiusProperty, value); - ComputeMask(); + GenerateMask(); GeneratePolygons(); } } @@ -229,7 +237,17 @@ public double InnerRadius set { SetValue(InnerRadiusProperty, value); - ComputeMask(); + GenerateMask(); + GeneratePolygons(); + } + } + + protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) + { + base.OnRenderSizeChanged(sizeInfo); + if (sizeInfo.WidthChanged || sizeInfo.HeightChanged) + { + GenerateMask(); GeneratePolygons(); } } diff --git a/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml b/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml index 3d9dac6cc4..4158a4d062 100644 --- a/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml +++ b/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml @@ -100,8 +100,8 @@ Date: Wed, 19 Dec 2018 16:04:04 -0500 Subject: [PATCH 4/7] Functionality to display the cirlce for non uniform states --- .../PullRequestListItemViewModelDesigner.cs | 2 +- src/GitHub.App/Services/PullRequestService.cs | 85 ++++++------------- .../PullRequestListItemViewModel.cs | 4 +- .../IPullRequestListItemViewModel.cs | 2 +- .../Models/IPullRequestModel.cs | 3 +- .../Models/PullRequestListItemModel.cs | 2 +- .../Controls/PullRequestStatusCircle.xaml.cs | 42 +++++++++ .../GitHubPane/PullRequestListItemView.xaml | 9 +- 8 files changed, 83 insertions(+), 66 deletions(-) diff --git a/src/GitHub.App/SampleData/PullRequestListItemViewModelDesigner.cs b/src/GitHub.App/SampleData/PullRequestListItemViewModelDesigner.cs index 19b7037b6e..38c6b5b740 100644 --- a/src/GitHub.App/SampleData/PullRequestListItemViewModelDesigner.cs +++ b/src/GitHub.App/SampleData/PullRequestListItemViewModelDesigner.cs @@ -17,7 +17,7 @@ public class PullRequestListItemViewModelDesigner : ViewModelBase, IPullRequestL public int Number { get; set; } public string Title { get; set; } public DateTimeOffset UpdatedAt { get; set; } - public PullRequestChecksState Checks { get; set; } + public PullRequestChecksSummaryState ChecksSummary { get; set; } public int ChecksPendingCount { get; set; } public int ChecksSuccessCount { get; set; } public int ChecksErrorCount { get; set; } diff --git a/src/GitHub.App/Services/PullRequestService.cs b/src/GitHub.App/Services/PullRequestService.cs index 566bcb9d68..6ca3757d70 100644 --- a/src/GitHub.App/Services/PullRequestService.cs +++ b/src/GitHub.App/Services/PullRequestService.cs @@ -219,71 +219,15 @@ public async Task> ReadPullRequests( var checkRuns = item.LastCommit?.CheckSuites?.SelectMany(model => model.CheckRuns).ToArray(); var statuses = item.LastCommit?.Statuses; - var hasCheckRuns = checkRuns?.Any() ?? false; - var hasStatuses = statuses?.Any() ?? false; - - if (!hasCheckRuns && !hasStatuses) - { - item.Checks = PullRequestChecksState.None; - } - else - { - var checksHasFailure = false; - var checksHasCompleteSuccess = true; - - if (hasCheckRuns) - { - checksHasFailure = checkRuns - .Any(model => model.Conclusion.HasValue - && (model.Conclusion.Value == CheckConclusionState.Failure - || model.Conclusion.Value == CheckConclusionState.ActionRequired)); - - if (!checksHasFailure) - { - checksHasCompleteSuccess = checkRuns - .All(model => model.Conclusion.HasValue - && (model.Conclusion.Value == CheckConclusionState.Success - || model.Conclusion.Value == CheckConclusionState.Neutral)); - } - } - - var statusHasFailure = false; - var statusHasCompleteSuccess = true; - - if (!checksHasFailure && hasStatuses) - { - statusHasFailure = item.LastCommit - .Statuses - .Any(status => status.State == StatusState.Failure - || status.State == StatusState.Error); - - if (!statusHasFailure) - { - statusHasCompleteSuccess = - item.LastCommit.Statuses.All(status => status.State == StatusState.Success); - } - } - - if (checksHasFailure || statusHasFailure) - { - item.Checks = PullRequestChecksState.Failure; - } - else if (statusHasCompleteSuccess && checksHasCompleteSuccess) - { - item.Checks = PullRequestChecksState.Success; - } - else - { - item.Checks = PullRequestChecksState.Pending; - } - } - + var totalCount = 0; var pendingCount = 0; var successCount = 0; var errorCount = 0; if (checkRuns != null) { + totalCount += checkRuns.Length; + pendingCount += checkRuns.Count(model => model.Status != CheckStatusState.Completed); successCount += checkRuns.Count(model => model.Status == CheckStatusState.Completed && @@ -298,6 +242,8 @@ public async Task> ReadPullRequests( if (statuses != null) { + totalCount += statuses.Count; + pendingCount += statuses.Count(model => model.State == StatusState.Pending || model.State == StatusState.Expected); @@ -311,6 +257,27 @@ public async Task> ReadPullRequests( item.ChecksSuccessCount = successCount; item.ChecksErrorCount = errorCount; + if (totalCount == 0) + { + item.ChecksSummary = PullRequestChecksSummaryState.None; + } + else if (totalCount == pendingCount) + { + item.ChecksSummary = PullRequestChecksSummaryState.Pending; + } + else if (totalCount == successCount) + { + item.ChecksSummary = PullRequestChecksSummaryState.Success; + } + else if (totalCount == errorCount) + { + item.ChecksSummary = PullRequestChecksSummaryState.Failure; + } + else + { + item.ChecksSummary = PullRequestChecksSummaryState.Mixed; + } + item.LastCommit = null; } diff --git a/src/GitHub.App/ViewModels/GitHubPane/PullRequestListItemViewModel.cs b/src/GitHub.App/ViewModels/GitHubPane/PullRequestListItemViewModel.cs index 66c8cc6664..30436ed5a0 100644 --- a/src/GitHub.App/ViewModels/GitHubPane/PullRequestListItemViewModel.cs +++ b/src/GitHub.App/ViewModels/GitHubPane/PullRequestListItemViewModel.cs @@ -19,7 +19,7 @@ public PullRequestListItemViewModel(PullRequestListItemModel model) { Id = model.Id; Author = new ActorViewModel(model.Author); - Checks = model.Checks; + ChecksSummary = model.ChecksSummary; ChecksErrorCount = model.ChecksErrorCount; ChecksPendingCount = model.ChecksPendingCount; ChecksSuccessCount = model.ChecksSuccessCount; @@ -36,7 +36,7 @@ public PullRequestListItemViewModel(PullRequestListItemModel model) public IActorViewModel Author { get; } /// - public PullRequestChecksState Checks { get; } + public PullRequestChecksSummaryState ChecksSummary { get; } /// public int ChecksSuccessCount { get; } diff --git a/src/GitHub.Exports.Reactive/ViewModels/GitHubPane/IPullRequestListItemViewModel.cs b/src/GitHub.Exports.Reactive/ViewModels/GitHubPane/IPullRequestListItemViewModel.cs index cf145bd99e..9f6758243b 100644 --- a/src/GitHub.Exports.Reactive/ViewModels/GitHubPane/IPullRequestListItemViewModel.cs +++ b/src/GitHub.Exports.Reactive/ViewModels/GitHubPane/IPullRequestListItemViewModel.cs @@ -32,7 +32,7 @@ public interface IPullRequestListItemViewModel : IIssueListItemViewModelBase /// /// Gets the pull request checks and statuses summary /// - PullRequestChecksState Checks { get; } + PullRequestChecksSummaryState ChecksSummary { get; } /// /// Gets the number of pending checks and statuses diff --git a/src/GitHub.Exports/Models/IPullRequestModel.cs b/src/GitHub.Exports/Models/IPullRequestModel.cs index 4d78de08ab..3a8df4952f 100644 --- a/src/GitHub.Exports/Models/IPullRequestModel.cs +++ b/src/GitHub.Exports/Models/IPullRequestModel.cs @@ -13,9 +13,10 @@ public enum PullRequestStateEnum Merged, } - public enum PullRequestChecksState + public enum PullRequestChecksSummaryState { None, + Mixed, Pending, Success, Failure diff --git a/src/GitHub.Exports/Models/PullRequestListItemModel.cs b/src/GitHub.Exports/Models/PullRequestListItemModel.cs index a002ce127e..0301af0da9 100644 --- a/src/GitHub.Exports/Models/PullRequestListItemModel.cs +++ b/src/GitHub.Exports/Models/PullRequestListItemModel.cs @@ -40,7 +40,7 @@ public class PullRequestListItemModel /// /// Gets the pull request checks and statuses summary /// - public PullRequestChecksState Checks { get; set; } + public PullRequestChecksSummaryState ChecksSummary { get; set; } /// /// Gets the number of pending checks and statuses diff --git a/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs index 47caadfc07..2e1651f709 100644 --- a/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs +++ b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs @@ -41,6 +41,18 @@ public partial class PullRequestStatusCircle : UserControl "InnerRadius", typeof(double), typeof(PullRequestStatusCircle), new PropertyMetadata((double)200, (d, args) => ((PullRequestStatusCircle)d).InnerRadius = (double)args.NewValue)); + public static readonly DependencyProperty PendingColorProperty = DependencyProperty.Register( + "PendingColor", typeof(Brush), typeof(PullRequestStatusCircle), + new PropertyMetadata(Brushes.Yellow, (d, args) => ((PullRequestStatusCircle)d).PendingColor = (Brush)args.NewValue)); + + public static readonly DependencyProperty ErrorColorProperty = DependencyProperty.Register( + "ErrorColor", typeof(Brush), typeof(PullRequestStatusCircle), + new PropertyMetadata(Brushes.Red, (d, args) => ((PullRequestStatusCircle)d).ErrorColor = (Brush)args.NewValue)); + + public static readonly DependencyProperty SuccessColorProperty = DependencyProperty.Register( + "SuccessColor", typeof(Brush), typeof(PullRequestStatusCircle), + new PropertyMetadata(Brushes.Green, (d, args) => ((PullRequestStatusCircle)d).SuccessColor = (Brush)args.NewValue)); + public IEnumerable GeneratePoints(float percentage) { double ToRadians(float val) @@ -242,6 +254,36 @@ public double InnerRadius } } + public Brush PendingColor + { + get => (Brush)GetValue(PendingColorProperty); + set + { + SetValue(PendingColorProperty, value); + PendingPolygon.Fill = value; + } + } + + public Brush ErrorColor + { + get => (Brush)GetValue(ErrorColorProperty); + set + { + SetValue(ErrorColorProperty, value); + ErrorPolygon.Fill = value; + } + } + + public Brush SuccessColor + { + get => (Brush)GetValue(SuccessColorProperty); + set + { + SetValue(SuccessColorProperty, value); + SuccessPolygon.Fill = value; + } + } + protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) { base.OnRenderSizeChanged(sizeInfo); diff --git a/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml b/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml index 4158a4d062..b87fe50579 100644 --- a/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml +++ b/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml @@ -14,7 +14,7 @@ CommentCount="4" IsCurrent="True" UpdatedAt="2018-01-29" - Checks="Success"> + ChecksSummary="Success"> @@ -99,12 +99,19 @@ + + + From a4d9dfb590e67f4f9eb6c52cd8e9b446aabbb98b Mon Sep 17 00:00:00 2001 From: Don Okuda Date: Thu, 10 Jan 2019 16:37:07 -0800 Subject: [PATCH 5/7] Tweak line thickness --- .../Views/GitHubPane/PullRequestListItemView.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml b/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml index b87fe50579..6051444ea0 100644 --- a/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml +++ b/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml @@ -104,7 +104,7 @@ Date: Fri, 25 Jan 2019 10:00:41 -0500 Subject: [PATCH 6/7] Calling methods to update internal state from dependency property change functions --- .../Controls/PullRequestStatusCircle.xaml.cs | 87 +++++++++++++++---- 1 file changed, 69 insertions(+), 18 deletions(-) diff --git a/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs index 2e1651f709..dafe75e05c 100644 --- a/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs +++ b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs @@ -23,35 +23,96 @@ public partial class PullRequestStatusCircle : UserControl { public static readonly DependencyProperty ErrorCountProperty = DependencyProperty.Register( "ErrorCount", typeof(int), typeof(PullRequestStatusCircle), - new PropertyMetadata(0, (d, args) => ((PullRequestStatusCircle)d).ErrorCount = (int)args.NewValue)); + new PropertyMetadata(0, OnErrorCountChanged)); + + private static void OnErrorCountChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs) + { + var pullRequestStatusCircle = ((PullRequestStatusCircle)dependencyObject); + pullRequestStatusCircle.ErrorCount = (int)eventArgs.NewValue; + pullRequestStatusCircle.GeneratePolygons(); + } public static readonly DependencyProperty SuccessCountProperty = DependencyProperty.Register( "SuccessCount", typeof(int), typeof(PullRequestStatusCircle), - new PropertyMetadata(0, (d, args) => ((PullRequestStatusCircle)d).SuccessCount = (int)args.NewValue)); + new PropertyMetadata(0, OnSuccessCountChanged)); + + private static void OnSuccessCountChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs) + { + var pullRequestStatusCircle = ((PullRequestStatusCircle)dependencyObject); + pullRequestStatusCircle.SuccessCount = (int)eventArgs.NewValue; + pullRequestStatusCircle.GeneratePolygons(); + } public static readonly DependencyProperty PendingCountProperty = DependencyProperty.Register( "PendingCount", typeof(int), typeof(PullRequestStatusCircle), - new PropertyMetadata(0, (d, args) => ((PullRequestStatusCircle)d).PendingCount = (int)args.NewValue)); + new PropertyMetadata(0, OnPendingCountChanged)); + + private static void OnPendingCountChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs) + { + var pullRequestStatusCircle = ((PullRequestStatusCircle) dependencyObject); + pullRequestStatusCircle.PendingCount = (int) eventArgs.NewValue; + pullRequestStatusCircle.GeneratePolygons(); + } public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register( "Radius", typeof(double), typeof(PullRequestStatusCircle), - new PropertyMetadata((double)250, (d, args) => ((PullRequestStatusCircle)d).Radius = (double)args.NewValue)); + new PropertyMetadata((double)250, OnRadiusChanged)); + + private static void OnRadiusChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs) + { + var pullRequestStatusCircle = ((PullRequestStatusCircle) dependencyObject); + pullRequestStatusCircle.Radius = (double) eventArgs.NewValue; + pullRequestStatusCircle.GenerateMask(); + pullRequestStatusCircle.GeneratePolygons(); + } public static readonly DependencyProperty InnerRadiusProperty = DependencyProperty.Register( "InnerRadius", typeof(double), typeof(PullRequestStatusCircle), - new PropertyMetadata((double)200, (d, args) => ((PullRequestStatusCircle)d).InnerRadius = (double)args.NewValue)); + new PropertyMetadata((double)200, OnInnerRadiusChanged)); + + private static void OnInnerRadiusChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs) + { + var pullRequestStatusCircle = ((PullRequestStatusCircle) dependencyObject); + pullRequestStatusCircle.InnerRadius = (double) eventArgs.NewValue; + pullRequestStatusCircle.GenerateMask(); + pullRequestStatusCircle.GeneratePolygons(); + } public static readonly DependencyProperty PendingColorProperty = DependencyProperty.Register( "PendingColor", typeof(Brush), typeof(PullRequestStatusCircle), - new PropertyMetadata(Brushes.Yellow, (d, args) => ((PullRequestStatusCircle)d).PendingColor = (Brush)args.NewValue)); + new PropertyMetadata(Brushes.Yellow, OnPendingColorChanged)); + + private static void OnPendingColorChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs) + { + var pullRequestStatusCircle = ((PullRequestStatusCircle) dependencyObject); + var brush = (Brush) eventArgs.NewValue; + pullRequestStatusCircle.PendingColor = brush; + pullRequestStatusCircle.PendingPolygon.Fill = brush; + } public static readonly DependencyProperty ErrorColorProperty = DependencyProperty.Register( "ErrorColor", typeof(Brush), typeof(PullRequestStatusCircle), - new PropertyMetadata(Brushes.Red, (d, args) => ((PullRequestStatusCircle)d).ErrorColor = (Brush)args.NewValue)); + new PropertyMetadata(Brushes.Red, OnErrorColorChanged)); + + private static void OnErrorColorChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs) + { + var pullRequestStatusCircle = ((PullRequestStatusCircle) dependencyObject); + var brush = (Brush) eventArgs.NewValue; + pullRequestStatusCircle.ErrorColor = brush; + pullRequestStatusCircle.ErrorPolygon.Fill = brush; + } public static readonly DependencyProperty SuccessColorProperty = DependencyProperty.Register( "SuccessColor", typeof(Brush), typeof(PullRequestStatusCircle), - new PropertyMetadata(Brushes.Green, (d, args) => ((PullRequestStatusCircle)d).SuccessColor = (Brush)args.NewValue)); + new PropertyMetadata(Brushes.Green, OnSuccessColorChanged)); + + private static void OnSuccessColorChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs) + { + var pullRequestStatusCircle = ((PullRequestStatusCircle) dependencyObject); + var brush = (Brush) eventArgs.NewValue; + pullRequestStatusCircle.SuccessColor = brush; + pullRequestStatusCircle.SuccessPolygon.Fill = brush; + } public IEnumerable GeneratePoints(float percentage) { @@ -208,7 +269,6 @@ public int ErrorCount set { SetValue(ErrorCountProperty, value); - GeneratePolygons(); } } @@ -218,7 +278,6 @@ public int SuccessCount set { SetValue(SuccessCountProperty, value); - GeneratePolygons(); } } @@ -228,7 +287,6 @@ public int PendingCount set { SetValue(PendingCountProperty, value); - GeneratePolygons(); } } @@ -238,8 +296,6 @@ public double Radius set { SetValue(RadiusProperty, value); - GenerateMask(); - GeneratePolygons(); } } @@ -249,8 +305,6 @@ public double InnerRadius set { SetValue(InnerRadiusProperty, value); - GenerateMask(); - GeneratePolygons(); } } @@ -260,7 +314,6 @@ public Brush PendingColor set { SetValue(PendingColorProperty, value); - PendingPolygon.Fill = value; } } @@ -270,7 +323,6 @@ public Brush ErrorColor set { SetValue(ErrorColorProperty, value); - ErrorPolygon.Fill = value; } } @@ -280,7 +332,6 @@ public Brush SuccessColor set { SetValue(SuccessColorProperty, value); - SuccessPolygon.Fill = value; } } From 677328b6184044c7e038a35eb47b59dc5145678f Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Fri, 25 Jan 2019 10:00:50 -0500 Subject: [PATCH 7/7] Fixing namespace --- .../UI/Controls/PullRequestStatusCircle.xaml | 4 ++-- .../UI/Controls/PullRequestStatusCircle.xaml.cs | 2 +- .../Views/GitHubPane/PullRequestListItemView.xaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml index 4d2c0884d8..66984bda34 100644 --- a/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml +++ b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml @@ -1,9 +1,9 @@ - diff --git a/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs index dafe75e05c..a46e2f1224 100644 --- a/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs +++ b/src/GitHub.VisualStudio.UI/UI/Controls/PullRequestStatusCircle.xaml.cs @@ -14,7 +14,7 @@ using System.Windows.Shapes; using ReactiveUI; -namespace GitHub.VisualStudio.UI.UI.Controls +namespace GitHub.VisualStudio.UI.Controls { /// /// Interaction logic for PullRequestStatusCircle.xaml diff --git a/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml b/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml index 6051444ea0..ffc8210ced 100644 --- a/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml +++ b/src/GitHub.VisualStudio.UI/Views/GitHubPane/PullRequestListItemView.xaml @@ -5,7 +5,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:ghfvs="https://github.com/github/VisualStudio" xmlns:views="clr-namespace:GitHub.VisualStudio.Views" - xmlns:controls="clr-namespace:GitHub.VisualStudio.UI.UI.Controls" + xmlns:controls="clr-namespace:GitHub.VisualStudio.UI.Controls" mc:Ignorable="d" d:DesignWidth="300" Padding="0 4">