Skip to content

Commit

Permalink
Extracted gradient stop methods into the brush utils.
Browse files Browse the repository at this point in the history
  • Loading branch information
Wibble199 committed Apr 24, 2020
1 parent 1e779b9 commit f17f6ff
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,12 @@ public Control_ParticleLayer(SimpleParticleLayerHandler context) {
private void ApplyGradientToEditor() {
// Note that I tried using a binding instead of this but since it'd need a IValueConverter which would have to create a new brush and
// the _values_ on that brush change not the brush itself, the binding was not actually being triggered.
gradientEditor.Brush = handler.Properties._ParticleColorStops.Count == 1
? (Brush)new SolidColorBrush(handler.Properties._ParticleColorStops.First().color.ToMediaColor())
: new LinearGradientBrush(new GradientStopCollection(handler.Properties._ParticleColorStops.Select(t => new GradientStop(t.color.ToMediaColor(), t.offset))));
gradientEditor.Brush = handler.Properties._ParticleColorStops.ToMediaBrush();
}

private void GradientEditor_BrushChanged(object sender, ColorBox.BrushChangedEventArgs e) {
// Set the particle's color stops from the media brush. We cannot pass the media brush directly as it causes issues with UI threading
if (e.Brush is GradientBrush gb)
handler.Properties._ParticleColorStops = gb.GradientStops.Select(gs => (gs.Color.ToDrawingColor(), (float)gs.Offset)).ToList();
else if (e.Brush is SolidColorBrush sb)
handler.Properties._ParticleColorStops = new List<(System.Drawing.Color color, float offset)> { (sb.Color.ToDrawingColor(), 0f) };
handler.Properties._ParticleColorStops = e.Brush.ToColorStopCollection();
}

private void ApplyButton_Click(object sender, RoutedEventArgs e) {
Expand Down
113 changes: 72 additions & 41 deletions Project-Aurora/Project-Aurora/Utils/BrushUtils.cs
Original file line number Diff line number Diff line change
@@ -1,37 +1,42 @@
using System;
using Corale.Colore.Core;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Data;
using D = System.Drawing;
using M = System.Windows.Media;
using ColorStopCollecion = System.Collections.Generic.List<(System.Drawing.Color color, float offset)>;
using System.Linq;

namespace Aurora.Utils
{
public static class BrushUtils
{
public static System.Drawing.Brush MediaBrushToDrawingBrush(System.Windows.Media.Brush in_brush)
public static D.Brush MediaBrushToDrawingBrush(M.Brush in_brush)
{
if (in_brush is System.Windows.Media.SolidColorBrush)
if (in_brush is M.SolidColorBrush)
{
System.Drawing.SolidBrush brush = new System.Drawing.SolidBrush(
ColorUtils.MediaColorToDrawingColor((in_brush as System.Windows.Media.SolidColorBrush).Color)
D.SolidBrush brush = new D.SolidBrush(
ColorUtils.MediaColorToDrawingColor((in_brush as M.SolidColorBrush).Color)
);

return brush;
}
else if (in_brush is System.Windows.Media.LinearGradientBrush)
else if (in_brush is M.LinearGradientBrush)
{
System.Windows.Media.LinearGradientBrush lgb = (in_brush as System.Windows.Media.LinearGradientBrush);
M.LinearGradientBrush lgb = (in_brush as M.LinearGradientBrush);

System.Drawing.PointF starting_point = new System.Drawing.PointF(
D.PointF starting_point = new D.PointF(
(float)lgb.StartPoint.X,
(float)lgb.StartPoint.Y
);

System.Drawing.PointF ending_point = new System.Drawing.PointF(
D.PointF ending_point = new D.PointF(
(float)lgb.EndPoint.X,
(float)lgb.EndPoint.Y
);

System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(
D.Drawing2D.LinearGradientBrush brush = new D.Drawing2D.LinearGradientBrush(
starting_point,
ending_point,
System.Drawing.Color.Red,
Expand All @@ -53,15 +58,15 @@ public static System.Drawing.Brush MediaBrushToDrawingBrush(System.Windows.Media
}
*/

SortedDictionary<float, System.Drawing.Color> brush_blend = new SortedDictionary<float, System.Drawing.Color>();
SortedDictionary<float, D.Color> brush_blend = new SortedDictionary<float, D.Color>();

foreach (var grad_stop in lgb.GradientStops)
{
if (!brush_blend.ContainsKey((float)grad_stop.Offset))
brush_blend.Add((float)grad_stop.Offset, ColorUtils.MediaColorToDrawingColor(grad_stop.Color));
}

List<System.Drawing.Color> brush_colors = new List<System.Drawing.Color>();
List<D.Color> brush_colors = new List<D.Color>();
List<float> brush_positions = new List<float>();

foreach (var kvp in brush_blend)
Expand All @@ -70,33 +75,33 @@ public static System.Drawing.Brush MediaBrushToDrawingBrush(System.Windows.Media
brush_positions.Add(kvp.Key);
}

System.Drawing.Drawing2D.ColorBlend color_blend = new System.Drawing.Drawing2D.ColorBlend();
D.Drawing2D.ColorBlend color_blend = new D.Drawing2D.ColorBlend();
color_blend.Colors = brush_colors.ToArray();
color_blend.Positions = brush_positions.ToArray();
brush.InterpolationColors = color_blend;

return brush;
}
else if (in_brush is System.Windows.Media.RadialGradientBrush)
else if (in_brush is M.RadialGradientBrush)
{
System.Windows.Media.RadialGradientBrush rgb = (in_brush as System.Windows.Media.RadialGradientBrush);
M.RadialGradientBrush rgb = (in_brush as M.RadialGradientBrush);

System.Drawing.RectangleF brush_region = new System.Drawing.RectangleF(
D.RectangleF brush_region = new D.RectangleF(
0.0f,
0.0f,
2.0f * (float)rgb.RadiusX,
2.0f * (float)rgb.RadiusY
);

System.Drawing.PointF center_point = new System.Drawing.PointF(
D.PointF center_point = new D.PointF(
(float)rgb.Center.X,
(float)rgb.Center.Y
);

System.Drawing.Drawing2D.GraphicsPath g_path = new System.Drawing.Drawing2D.GraphicsPath();
D.Drawing2D.GraphicsPath g_path = new D.Drawing2D.GraphicsPath();
g_path.AddEllipse(brush_region);

System.Drawing.Drawing2D.PathGradientBrush brush = new System.Drawing.Drawing2D.PathGradientBrush(g_path);
D.Drawing2D.PathGradientBrush brush = new D.Drawing2D.PathGradientBrush(g_path);

brush.CenterPoint = center_point;

Expand All @@ -115,15 +120,15 @@ public static System.Drawing.Brush MediaBrushToDrawingBrush(System.Windows.Media
}
*/

SortedDictionary<float, System.Drawing.Color> brush_blend = new SortedDictionary<float, System.Drawing.Color>();
SortedDictionary<float, D.Color> brush_blend = new SortedDictionary<float, D.Color>();

foreach (var grad_stop in rgb.GradientStops)
{
if (!brush_blend.ContainsKey((float)grad_stop.Offset))
brush_blend.Add((float)grad_stop.Offset, ColorUtils.MediaColorToDrawingColor(grad_stop.Color));
}

List<System.Drawing.Color> brush_colors = new List<System.Drawing.Color>();
List<D.Color> brush_colors = new List<D.Color>();
List<float> brush_positions = new List<float>();

foreach (var kvp in brush_blend)
Expand All @@ -132,7 +137,7 @@ public static System.Drawing.Brush MediaBrushToDrawingBrush(System.Windows.Media
brush_positions.Add(kvp.Key);
}

System.Drawing.Drawing2D.ColorBlend color_blend = new System.Drawing.Drawing2D.ColorBlend();
D.Drawing2D.ColorBlend color_blend = new D.Drawing2D.ColorBlend();
color_blend.Colors = brush_colors.ToArray();
color_blend.Positions = brush_positions.ToArray();
brush.InterpolationColors = color_blend;
Expand All @@ -141,23 +146,23 @@ public static System.Drawing.Brush MediaBrushToDrawingBrush(System.Windows.Media
}
else
{
return new System.Drawing.SolidBrush(System.Drawing.Color.Red); //Return error color
return new D.SolidBrush(System.Drawing.Color.Red); //Return error color
}
}

public static System.Windows.Media.Brush DrawingBrushToMediaBrush(System.Drawing.Brush in_brush)
public static M.Brush DrawingBrushToMediaBrush(D.Brush in_brush)
{
if (in_brush is System.Drawing.SolidBrush)
if (in_brush is D.SolidBrush)
{
System.Windows.Media.SolidColorBrush brush = new System.Windows.Media.SolidColorBrush(
ColorUtils.DrawingColorToMediaColor((in_brush as System.Drawing.SolidBrush).Color)
M.SolidColorBrush brush = new M.SolidColorBrush(
ColorUtils.DrawingColorToMediaColor((in_brush as D.SolidBrush).Color)
);

return brush;
}
else if (in_brush is System.Drawing.Drawing2D.LinearGradientBrush)
else if (in_brush is D.Drawing2D.LinearGradientBrush)
{
System.Drawing.Drawing2D.LinearGradientBrush lgb = (in_brush as System.Drawing.Drawing2D.LinearGradientBrush);
D.Drawing2D.LinearGradientBrush lgb = (in_brush as D.Drawing2D.LinearGradientBrush);

System.Windows.Point starting_point = new System.Windows.Point(
lgb.Rectangle.X,
Expand All @@ -169,7 +174,7 @@ public static System.Windows.Media.Brush DrawingBrushToMediaBrush(System.Drawing
lgb.Rectangle.Bottom
);

System.Windows.Media.GradientStopCollection collection = new System.Windows.Media.GradientStopCollection();
M.GradientStopCollection collection = new M.GradientStopCollection();

try
{
Expand All @@ -178,7 +183,7 @@ public static System.Windows.Media.Brush DrawingBrushToMediaBrush(System.Drawing
for (int x = 0; x < lgb.InterpolationColors.Colors.Length; x++)
{
collection.Add(
new System.Windows.Media.GradientStop(
new M.GradientStop(
ColorUtils.DrawingColorToMediaColor(lgb.InterpolationColors.Colors[x]),
lgb.InterpolationColors.Positions[x]
)
Expand All @@ -191,47 +196,47 @@ public static System.Windows.Media.Brush DrawingBrushToMediaBrush(System.Drawing
for (int x = 0; x < lgb.LinearColors.Length; x++)
{
collection.Add(
new System.Windows.Media.GradientStop(
new M.GradientStop(
ColorUtils.DrawingColorToMediaColor(lgb.LinearColors[x]),
x / (double)(lgb.LinearColors.Length - 1)
)
);
}
}

System.Windows.Media.LinearGradientBrush brush = new System.Windows.Media.LinearGradientBrush(
M.LinearGradientBrush brush = new M.LinearGradientBrush(
collection,
starting_point,
ending_point
);

return brush;
}
else if (in_brush is System.Drawing.Drawing2D.PathGradientBrush)
else if (in_brush is D.Drawing2D.PathGradientBrush)
{
System.Drawing.Drawing2D.PathGradientBrush pgb = (in_brush as System.Drawing.Drawing2D.PathGradientBrush);
D.Drawing2D.PathGradientBrush pgb = (in_brush as D.Drawing2D.PathGradientBrush);

System.Windows.Point starting_point = new System.Windows.Point(
pgb.CenterPoint.X,
pgb.CenterPoint.Y
);

System.Windows.Media.GradientStopCollection collection = new System.Windows.Media.GradientStopCollection();
M.GradientStopCollection collection = new M.GradientStopCollection();

if (pgb.InterpolationColors != null && pgb.InterpolationColors.Colors.Length == pgb.InterpolationColors.Positions.Length)
{
for (int x = 0; x < pgb.InterpolationColors.Colors.Length; x++)
{
collection.Add(
new System.Windows.Media.GradientStop(
new M.GradientStop(
ColorUtils.DrawingColorToMediaColor(pgb.InterpolationColors.Colors[x]),
pgb.InterpolationColors.Positions[x]
)
);
}
}

System.Windows.Media.RadialGradientBrush brush = new System.Windows.Media.RadialGradientBrush(
M.RadialGradientBrush brush = new M.RadialGradientBrush(
collection
);

Expand All @@ -241,17 +246,43 @@ public static System.Windows.Media.Brush DrawingBrushToMediaBrush(System.Drawing
}
else
{
return new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(255, 255, 0, 0)); //Return error color
return new M.SolidColorBrush(System.Windows.Media.Color.FromArgb(255, 255, 0, 0)); //Return error color
}
}

/// <summary>
/// Creates a <see cref="ColorStopCollecion"/> from the given media brush.
/// </summary>
public static ColorStopCollecion ToColorStopCollection(this M.Brush brush) {
if (brush is M.GradientBrush gb)
return gb.GradientStops.Select(gs => (gs.Color.ToDrawingColor(), (float)gs.Offset)).ToList();
else if (brush is M.SolidColorBrush sb)
return new ColorStopCollecion { (sb.Color.ToDrawingColor(), 0f) };
return null;
}

/// <summary>
/// Converts a <see cref="ColorStopCollecion"/> into a media brush (either <see cref="M.SolidColorBrush"/>
/// or a <see cref="M.LinearGradientBrush"/> depending on the amount of stops in the collection).
/// </summary>
public static M.Brush ToMediaBrush(this ColorStopCollecion stops) {
if (stops.Count == 0)
return M.Brushes.Transparent;
else if (stops.Count == 1)
return new M.SolidColorBrush(stops[0].color.ToMediaColor());
else
return new M.LinearGradientBrush(new M.GradientStopCollection(
stops.Select(s => new M.GradientStop(s.color.ToMediaColor(), s.offset))
));
}
}

/// <summary>
/// Converter that converts a <see cref="System.Windows.Media.Color"/> into a <see cref="System.Windows.Media.SolidColorBrush"/>.
/// Converter that converts a <see cref="M.Color"/> into a <see cref="M.SolidColorBrush"/>.
/// Does not support converting back.
/// </summary>
public class ColorToBrushConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) => new System.Windows.Media.SolidColorBrush((value as System.Windows.Media.Color?) ?? System.Windows.Media.Color.FromArgb(0, 0, 0, 0));
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) => new M.SolidColorBrush((value as M.Color?) ?? System.Windows.Media.Color.FromArgb(0, 0, 0, 0));
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
}
}

0 comments on commit f17f6ff

Please sign in to comment.