diff --git a/Artemis/Artemis/Profiles/Layers/Types/AngularBrush/AngularBrushPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Types/AngularBrush/AngularBrushPropertiesModel.cs index 58fdce801..7dcced567 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AngularBrush/AngularBrushPropertiesModel.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AngularBrush/AngularBrushPropertiesModel.cs @@ -20,9 +20,5 @@ namespace Artemis.Profiles.Layers.Types.AngularBrush { } #endregion - - #region Methods - - #endregion } } diff --git a/Artemis/Artemis/Profiles/Layers/Types/AngularBrush/AngularBrushType.cs b/Artemis/Artemis/Profiles/Layers/Types/AngularBrush/AngularBrushType.cs index 0bdf2775e..0a562b8f3 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AngularBrush/AngularBrushType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AngularBrush/AngularBrushType.cs @@ -17,6 +17,7 @@ namespace Artemis.Profiles.Layers.Types.AngularBrush #region Properties & Fields private GradientDrawer _gradientDrawer; + private GradientDrawer _gradientDrawerThumbnail; public string Name => "Angular Brush"; public bool ShowInEdtor => true; @@ -27,20 +28,21 @@ namespace Artemis.Profiles.Layers.Types.AngularBrush public AngularBrushType() { _gradientDrawer = new GradientDrawer(); + _gradientDrawerThumbnail = new GradientDrawer(18, 18); } #region Methods public ImageSource DrawThumbnail(LayerModel layer) { - //TODO DarthAffe 14.01.2017: This could be replaced with the real brush but it complaints about the thread too + _gradientDrawerThumbnail.GradientStops = GetGradientStops(layer.Brush).Select(x => new Tuple(x.Offset, x.Color)).ToList(); + _gradientDrawerThumbnail.Update(); + Rect thumbnailRect = new Rect(0, 0, 18, 18); DrawingVisual visual = new DrawingVisual(); using (DrawingContext c = visual.RenderOpen()) - if (layer.Properties.Brush != null) - c.DrawRectangle(layer.Properties.Brush, - new Pen(new SolidColorBrush(Colors.White), 1), - thumbnailRect); + if (_gradientDrawerThumbnail.Brush != null) + c.DrawRectangle(_gradientDrawerThumbnail.Brush.Clone(), new Pen(new SolidColorBrush(Colors.White), 1), thumbnailRect); DrawingImage image = new DrawingImage(visual.Drawing); return image; @@ -53,10 +55,9 @@ namespace Artemis.Profiles.Layers.Types.AngularBrush Brush origBrush = layerModel.Brush; - //TODO DarthAffe 14.01.2017: Check if an update is needed _gradientDrawer.GradientStops = GetGradientStops(layerModel.Brush).Select(x => new Tuple(x.Offset, x.Color)).ToList(); _gradientDrawer.Update(); - layerModel.Brush = _gradientDrawer.Brush.Clone(); + layerModel.Brush = _gradientDrawer.Brush; // If an animation is present, let it handle the drawing if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation)) diff --git a/Artemis/Artemis/Profiles/Layers/Types/AngularBrush/Drawing/GradientDrawer.cs b/Artemis/Artemis/Profiles/Layers/Types/AngularBrush/Drawing/GradientDrawer.cs index fd3d7e8c2..112af1048 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AngularBrush/Drawing/GradientDrawer.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AngularBrush/Drawing/GradientDrawer.cs @@ -1,9 +1,12 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; +using Brush = System.Windows.Media.Brush; +using Color = System.Windows.Media.Color; namespace Artemis.Profiles.Layers.Types.AngularBrush.Drawing { @@ -13,26 +16,71 @@ namespace Artemis.Profiles.Layers.Types.AngularBrush.Drawing private static readonly double ORIGIN = Math.Atan2(-1, 0); - #endregion + #endregion #region Properties & Fields + private int _width; + private int _height; + + private bool _isDirty = true; + private int _lastGradientHash; + private WriteableBitmap _bitmap; private IList> _gradientStops; public IList> GradientStops { - set { _gradientStops = FixGradientStops(value); } + set + { + int hash = GetHash(value); + if (_lastGradientHash != hash) + { + _gradientStops = FixGradientStops(value); + _lastGradientHash = hash; + _isDirty = true; + } + } + } + + private PointF _center = new PointF(0.5f, 0.5f); + public PointF Center + { + get { return _center; } + set + { + if (_center != value) + { + _center = value; + _isDirty = true; + } + } } public Brush Brush { get; private set; } #endregion + #region Constructors + + public GradientDrawer() + : this(100, 100) + { } + + public GradientDrawer(int width, int height) + { + this._width = width; + this._height = height; + } + + #endregion + #region Methods - public void Update() + public void Update(bool force = false) { + if (!_isDirty && !force) return; + if (_bitmap == null) CreateBrush(); @@ -41,31 +89,27 @@ namespace Artemis.Profiles.Layers.Types.AngularBrush.Drawing _bitmap.Lock(); byte* buffer = (byte*)_bitmap.BackBuffer.ToPointer(); - int width = _bitmap.PixelWidth; - double widthHalf = width / 2.0; - - int height = _bitmap.PixelHeight; - double heightHalf = height / 2.0; - - for (int y = 0; y < height; y++) - for (int x = 0; x < width; x++) + for (int y = 0; y < _height; y++) + for (int x = 0; x < _width; x++) { - int offset = (((y * width) + x) * 4); + int offset = (((y * _width) + x) * 4); - double gradientOffset = CalculateGradientOffset(x, y, widthHalf, heightHalf); + double gradientOffset = CalculateGradientOffset(x, y, _width * Center.X, _height * Center.Y); GetColor(_gradientStops, gradientOffset, ref buffer[offset + 3], ref buffer[offset + 2], ref buffer[offset + 1], ref buffer[offset]); } - _bitmap.AddDirtyRect(new Int32Rect(0, 0, width, height)); + _bitmap.AddDirtyRect(new Int32Rect(0, 0, _width, _height)); _bitmap.Unlock(); } + + _isDirty = false; } private void CreateBrush() { - _bitmap = new WriteableBitmap(100, 100, 96, 96, PixelFormats.Bgra32, null); + _bitmap = new WriteableBitmap(_width, _height, 96, 96, PixelFormats.Bgra32, null); Brush = new ImageBrush(_bitmap) { Stretch = Stretch.UniformToFill }; } @@ -127,7 +171,7 @@ namespace Artemis.Profiles.Layers.Types.AngularBrush.Drawing colB = (byte)((afterColor.B - beforeColor.B) * blendFactor + beforeColor.B); } - private IList> FixGradientStops(IList> gradientStops) + private static IList> FixGradientStops(IList> gradientStops) { if (gradientStops == null) return new List>(); @@ -144,6 +188,14 @@ namespace Artemis.Profiles.Layers.Types.AngularBrush.Drawing return stops; } + private static int GetHash(IList> sequence) + { + unchecked + { + return sequence.Aggregate(487, (current, item) => (((current * 31) + item.Item1.GetHashCode()) * 31) + item.Item2.GetHashCode()); + } + } + #endregion } }