From 8394fbc418f0a19ea9a12ab708de99d49bc16324 Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Tue, 19 Apr 2016 17:34:05 +0200 Subject: [PATCH] Implemented layer sorting --- Artemis/Artemis/App.xaml | 2 +- Artemis/Artemis/Artemis.csproj | 2 + Artemis/Artemis/Models/Profiles/LayerModel.cs | 65 ++++++++- .../Artemis/Models/Profiles/ProfileModel.cs | 70 ++++++++- .../Games/CounterStrike/CounterStrikeModel.cs | 23 +-- .../CounterStrike/CounterStrikeView.xaml | 2 +- Artemis/Artemis/Styles/ColorBox.xaml | 20 +-- Artemis/Artemis/Utilities/LayerDrawer.cs | 4 +- .../ParentChild/ChildItemCollection.cs | 138 ++++++++++++++++++ .../Utilities/ParentChild/IChildItem.cs | 12 ++ Artemis/Artemis/Utilities/ValueConverters.cs | 27 ++++ .../ViewModels/ProfileEditorViewModel.cs | 69 ++++++--- .../Views/LayerEditor/LayerConditionView.xaml | 2 +- Artemis/Artemis/Views/LayerEditorView.xaml | 10 +- Artemis/Artemis/Views/ProfileEditorView.xaml | 43 +++++- Artemis/Artemis/Views/ShellView.xaml | 4 +- 16 files changed, 403 insertions(+), 90 deletions(-) create mode 100644 Artemis/Artemis/Utilities/ParentChild/ChildItemCollection.cs create mode 100644 Artemis/Artemis/Utilities/ParentChild/IChildItem.cs diff --git a/Artemis/Artemis/App.xaml b/Artemis/Artemis/App.xaml index 18f22cfc6..7acc3be4c 100644 --- a/Artemis/Artemis/App.xaml +++ b/Artemis/Artemis/App.xaml @@ -17,7 +17,7 @@ + Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" /> diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index d286cf8ae..d3962784b 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -398,6 +398,8 @@ + + diff --git a/Artemis/Artemis/Models/Profiles/LayerModel.cs b/Artemis/Artemis/Models/Profiles/LayerModel.cs index 8eccf4c17..fae6b6dc5 100644 --- a/Artemis/Artemis/Models/Profiles/LayerModel.cs +++ b/Artemis/Artemis/Models/Profiles/LayerModel.cs @@ -5,10 +5,11 @@ using System.Windows.Media; using System.Xml.Serialization; using Artemis.Models.Interfaces; using Artemis.Utilities; +using Artemis.Utilities.ParentChild; namespace Artemis.Models.Profiles { - public class LayerModel + public class LayerModel : IChildItem, IChildItem { [XmlIgnore] private readonly LayerDrawer _drawer; [XmlIgnore] private bool _mustDraw; @@ -18,7 +19,7 @@ namespace Artemis.Models.Profiles UserProps = new LayerPropertiesModel(); CalcProps = new LayerPropertiesModel(); - Children = new List(); + Children = new ChildItemCollection(this); LayerConditions = new List(); LayerProperties = new List(); @@ -29,9 +30,10 @@ namespace Artemis.Models.Profiles public string Name { get; set; } public LayerType LayerType { get; set; } public bool Enabled { get; set; } + public int Order { get; set; } public LayerPropertiesModel UserProps { get; set; } - public List Children { get; set; } + public ChildItemCollection Children { get; } public List LayerConditions { get; set; } public List LayerProperties { get; set; } @@ -41,6 +43,28 @@ namespace Artemis.Models.Profiles [XmlIgnore] public ImageSource LayerImage => _drawer.GetThumbnail(); + [XmlIgnore] + public LayerModel ParentLayer { get; internal set; } + + [XmlIgnore] + public ProfileModel ParentProfile { get; internal set; } + + #region IChildItem Members + + LayerModel IChildItem.Parent + { + get { return ParentLayer; } + set { ParentLayer = value; } + } + + ProfileModel IChildItem.Parent + { + get { return ParentProfile; } + set { ParentProfile = value; } + } + + #endregion + public bool ConditionsMet(IGameDataModel dataModel) { return Enabled && LayerConditions.All(cm => cm.ConditionMet(dataModel)); @@ -49,7 +73,7 @@ namespace Artemis.Models.Profiles public void DrawPreview(DrawingContext c) { GeneralHelpers.CopyProperties(CalcProps, UserProps); - if (LayerType == LayerType.KeyboardRectangle || LayerType == LayerType.KeyboardEllipse) + if (LayerType == LayerType.Keyboard || LayerType == LayerType.Keyboard) _drawer.Draw(c, _mustDraw); else if (LayerType == LayerType.KeyboardGif) _drawer.DrawGif(c); @@ -62,9 +86,9 @@ namespace Artemis.Models.Profiles return; if (LayerType == LayerType.Folder) - foreach (var layerModel in Children) + foreach (var layerModel in Children.OrderByDescending(l => l.Order)) layerModel.Draw(dataModel, c); - else if (LayerType == LayerType.KeyboardRectangle || LayerType == LayerType.KeyboardEllipse) + else if (LayerType == LayerType.Keyboard || LayerType == LayerType.Keyboard) _drawer.Draw(c); else if (LayerType == LayerType.KeyboardGif) _drawer.DrawGif(c); @@ -87,13 +111,38 @@ namespace Artemis.Models.Profiles foreach (var dynamicProperty in LayerProperties) dynamicProperty.ApplyProperty(dataModel, UserProps, CalcProps); } + + public void Reorder(LayerModel selectedLayer, bool moveUp) + { + // Fix the sorting just in case + FixOrder(); + + int newOrder; + if (moveUp) + newOrder = selectedLayer.Order - 1; + else + newOrder = selectedLayer.Order + 1; + + var target = Children.FirstOrDefault(l => l.Order == newOrder); + if (target == null) + return; + + target.Order = selectedLayer.Order; + selectedLayer.Order = newOrder; + } + + private void FixOrder() + { + Children.Sort(l => l.Order); + for (var i = 0; i < Children.Count; i++) + Children[i].Order = i; + } } public enum LayerType { [Description("Folder")] Folder, - [Description("Keyboard - Rectangle")] KeyboardRectangle, - [Description("Keyboard - Ellipse")] KeyboardEllipse, + [Description("Keyboard")] Keyboard, [Description("Keyboard - GIF")] KeyboardGif, [Description("Mouse")] Mouse, [Description("Headset")] Headset diff --git a/Artemis/Artemis/Models/Profiles/ProfileModel.cs b/Artemis/Artemis/Models/Profiles/ProfileModel.cs index d6e3b5cbc..546dd1c37 100644 --- a/Artemis/Artemis/Models/Profiles/ProfileModel.cs +++ b/Artemis/Artemis/Models/Profiles/ProfileModel.cs @@ -1,8 +1,11 @@ -using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Windows; using System.Windows.Media; -using System.Xml.Serialization; +using Artemis.Models.Interfaces; using Artemis.Utilities; -using CUE.NET.Helper; +using Artemis.Utilities.ParentChild; +using Color = System.Windows.Media.Color; namespace Artemis.Models.Profiles { @@ -10,16 +13,17 @@ namespace Artemis.Models.Profiles { public ProfileModel() { - Layers = new List(); + Layers = new ChildItemCollection(this); DrawingVisual = new DrawingVisual(); } + public ChildItemCollection Layers { get; } + public string Name { get; set; } public string KeyboardName { get; set; } public string GameName { get; set; } public DrawingVisual DrawingVisual { get; set; } - public List Layers { get; set; } protected bool Equals(ProfileModel other) { @@ -56,7 +60,8 @@ namespace Artemis.Models.Profiles { Name = "New layer", Enabled = true, - LayerType = LayerType.KeyboardRectangle, + Order = -1, + LayerType = LayerType.Keyboard, UserProps = new LayerPropertiesModel { Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor()), @@ -70,7 +75,60 @@ namespace Artemis.Models.Profiles }; Layers.Add(layer); + FixOrder(); + return layer; } + + public void Reorder(LayerModel selectedLayer, bool moveUp) + { + // Fix the sorting just in case + FixOrder(); + + int newOrder; + if (moveUp) + newOrder = selectedLayer.Order - 1; + else + newOrder = selectedLayer.Order + 1; + + var target = Layers.FirstOrDefault(l => l.Order == newOrder); + if (target == null) + return; + + target.Order = selectedLayer.Order; + selectedLayer.Order = newOrder; + } + + public void FixOrder() + { + Layers.Sort(l => l.Order); + for (var i = 0; i < Layers.Count; i++) + Layers[i].Order = i; + } + + public Bitmap GenerateBitmap(Rect keyboardRect, IGameDataModel gameDataModel) + { + Bitmap bitmap = null; + DrawingVisual.Dispatcher.Invoke(delegate + { + var visual = new DrawingVisual(); + using (var c = visual.RenderOpen()) + { + // Setup the DrawingVisual's size + c.PushClip(new RectangleGeometry(keyboardRect)); + c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect); + + // Draw the layers + foreach (var layerModel in Layers.OrderByDescending(l => l.Order)) + layerModel.Draw(gameDataModel, c); + + // Remove the clip + c.Pop(); + } + + bitmap = ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect); + }); + return bitmap; + } } } \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs index b1f65f050..4a35dcf84 100644 --- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs +++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs @@ -57,28 +57,7 @@ namespace Artemis.Modules.Games.CounterStrike return null; var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(Scale); - Bitmap bitmap = null; - Profile.DrawingVisual.Dispatcher.Invoke(delegate - { - var visual = new DrawingVisual(); - using (var drawingContext = visual.RenderOpen()) - { - // Setup the DrawingVisual's size - drawingContext.PushClip(new RectangleGeometry(keyboardRect)); - drawingContext.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), - null, keyboardRect); - - // Draw the layers - foreach (var layerModel in Profile.Layers) - layerModel.Draw(GameDataModel, drawingContext); - - // Remove the clip - drawingContext.Pop(); - } - - bitmap = ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect); - }); - return bitmap; + return Profile.GenerateBitmap(keyboardRect, GameDataModel); } public void HandleGameData(object sender, GameDataReceivedEventArgs e) diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeView.xaml b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeView.xaml index 0e5f255de..fcf198769 100644 --- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeView.xaml +++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeView.xaml @@ -54,7 +54,7 @@ - + diff --git a/Artemis/Artemis/Styles/ColorBox.xaml b/Artemis/Artemis/Styles/ColorBox.xaml index 672237b09..71056de39 100644 --- a/Artemis/Artemis/Styles/ColorBox.xaml +++ b/Artemis/Artemis/Styles/ColorBox.xaml @@ -150,17 +150,13 @@