mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Moved from a JSON to a XML save format. Implemented WPF-based layer drawing
This commit is contained in:
parent
c44c93803e
commit
36bdfa5aaa
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Serialization;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models.Profiles;
|
||||
using Newtonsoft.Json;
|
||||
@ -47,8 +48,11 @@ namespace Artemis.DAL
|
||||
if (!Directory.Exists(path))
|
||||
Directory.CreateDirectory(path);
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(prof, Formatting.Indented);
|
||||
File.WriteAllText(path + $@"\{prof.Name}.json", serialized);
|
||||
var serializer = new XmlSerializer(typeof(ProfileModel));
|
||||
using (var file = new StreamWriter(path + $@"\{prof.Name}.xml"))
|
||||
{
|
||||
serializer.Serialize(file, prof);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<ProfileModel> ReadProfiles()
|
||||
@ -57,15 +61,20 @@ namespace Artemis.DAL
|
||||
var profiles = new List<ProfileModel>();
|
||||
|
||||
// Create the directory structure
|
||||
var profileFiles = Directory.GetFiles(ProfileFolder, "*.json", SearchOption.AllDirectories);
|
||||
var profilePaths = Directory.GetFiles(ProfileFolder, "*.xml", SearchOption.AllDirectories);
|
||||
|
||||
// Parse the JSON files into objects and add them if they are valid
|
||||
foreach (var file in profileFiles)
|
||||
// TODO: Invalid file handling
|
||||
var deserializer = new XmlSerializer(typeof (ProfileModel));
|
||||
foreach (var path in profilePaths)
|
||||
{
|
||||
var prof = JsonConvert.DeserializeObject<ProfileModel>(File.ReadAllText(file));
|
||||
using (var file = new StreamReader(path))
|
||||
{
|
||||
var prof = (ProfileModel) deserializer.Deserialize(file);
|
||||
if (prof.GameName?.Length > 1 && prof.KeyboardName?.Length > 1 && prof.Name?.Length > 1)
|
||||
profiles.Add(prof);
|
||||
}
|
||||
}
|
||||
|
||||
return profiles;
|
||||
}
|
||||
|
||||
@ -19,11 +19,6 @@ namespace Artemis.Models.Profiles
|
||||
/// </summary>
|
||||
public string PercentageSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Only used when LayerPropertyType is Color
|
||||
/// </summary>
|
||||
public List<Color> LayerColors { get; set; }
|
||||
|
||||
internal void ApplyProperty<T>(IGameDataModel dataModel, LayerPropertiesModel userProps,
|
||||
LayerPropertiesModel props)
|
||||
{
|
||||
@ -37,11 +32,6 @@ namespace Artemis.Models.Profiles
|
||||
SetPercentageOf(props, userProps, dataModel, int.Parse(PercentageSource));
|
||||
if (LayerPopertyType == LayerPopertyType.PercentageOfProperty)
|
||||
SetPercentageOfProperty(props, userProps, dataModel);
|
||||
if (LayerPopertyType == LayerPopertyType.Color)
|
||||
{
|
||||
if (dataList.Where($"{GameProperty} {RequiredOperator} {RequiredValue}").Any())
|
||||
SetColor(layerProp, dataModel);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetPercentageOf(LayerPropertiesModel props, LayerPropertiesModel userProps,
|
||||
@ -67,14 +57,6 @@ namespace Artemis.Models.Profiles
|
||||
if (value != null)
|
||||
SetPercentageOf(props, userProps, dataModel, (int) value);
|
||||
}
|
||||
|
||||
private void SetColor(PropertyInfo layerProp, IGameDataModel dataModel)
|
||||
{
|
||||
if (layerProp == null)
|
||||
return;
|
||||
if (layerProp.PropertyType == typeof (List<Color>))
|
||||
layerProp.SetValue(dataModel, LayerColors, null);
|
||||
}
|
||||
}
|
||||
|
||||
public enum LayerPopertyType
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Media;
|
||||
using System.Xml.Serialization;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
@ -11,12 +11,10 @@ namespace Artemis.Models.Profiles
|
||||
{
|
||||
public class LayerModel
|
||||
{
|
||||
[JsonIgnore] private readonly LayerDrawer _drawer;
|
||||
[XmlIgnore] private readonly LayerDrawer _drawer;
|
||||
|
||||
public LayerModel(string name, LayerType layerType)
|
||||
public LayerModel()
|
||||
{
|
||||
Name = name;
|
||||
LayerType = layerType;
|
||||
LayerUserProperties = new LayerPropertiesModel();
|
||||
LayerCalculatedProperties = new LayerPropertiesModel();
|
||||
|
||||
@ -35,10 +33,10 @@ namespace Artemis.Models.Profiles
|
||||
public List<LayerConditionModel> LayerConditions { get; set; }
|
||||
public List<LayerDynamicPropertiesModel> LayerProperties { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[XmlIgnore]
|
||||
public LayerPropertiesModel LayerCalculatedProperties { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[XmlIgnore]
|
||||
public ImageSource LayerImage => _drawer.GetThumbnail();
|
||||
|
||||
public bool ConditionsMet<T>(IGameDataModel dataModel)
|
||||
@ -46,15 +44,15 @@ namespace Artemis.Models.Profiles
|
||||
return LayerConditions.All(cm => cm.ConditionMet<T>(dataModel));
|
||||
}
|
||||
|
||||
public void DrawPreview(Graphics g)
|
||||
public void DrawPreview(DrawingContext c)
|
||||
{
|
||||
if (LayerType == LayerType.KeyboardRectangle || LayerType == LayerType.KeyboardEllipse)
|
||||
_drawer.Draw(g);
|
||||
_drawer.Draw(c);
|
||||
else if (LayerType == LayerType.KeyboardGif)
|
||||
_drawer.DrawGif(g);
|
||||
_drawer.DrawGif(c);
|
||||
}
|
||||
|
||||
public void Draw<T>(IGameDataModel dataModel, Graphics g)
|
||||
public void Draw<T>(IGameDataModel dataModel, DrawingContext c)
|
||||
{
|
||||
if (!ConditionsMet<T>(dataModel))
|
||||
return;
|
||||
@ -62,11 +60,11 @@ namespace Artemis.Models.Profiles
|
||||
Update<T>(dataModel);
|
||||
|
||||
if (LayerType == LayerType.Folder)
|
||||
DrawChildren<T>(dataModel, g);
|
||||
DrawChildren<T>(dataModel, c);
|
||||
else if (LayerType == LayerType.KeyboardRectangle || LayerType == LayerType.KeyboardEllipse)
|
||||
_drawer.Draw(g);
|
||||
_drawer.Draw(c);
|
||||
else if (LayerType == LayerType.KeyboardGif)
|
||||
_drawer.DrawGif(g);
|
||||
_drawer.DrawGif(c);
|
||||
else if (LayerType == LayerType.Mouse)
|
||||
_drawer.UpdateMouse();
|
||||
else if (LayerType == LayerType.Headset)
|
||||
@ -80,10 +78,10 @@ namespace Artemis.Models.Profiles
|
||||
dynamicProperty.ApplyProperty<T>(dataModel, LayerUserProperties, LayerCalculatedProperties);
|
||||
}
|
||||
|
||||
private void DrawChildren<T>(IGameDataModel dataModel, Graphics g)
|
||||
private void DrawChildren<T>(IGameDataModel dataModel, DrawingContext c)
|
||||
{
|
||||
foreach (var layerModel in Children)
|
||||
layerModel.Draw<T>(dataModel, g);
|
||||
layerModel.Draw<T>(dataModel, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Media;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Artemis.Models.Profiles
|
||||
{
|
||||
[XmlInclude(typeof(LinearGradientBrush))]
|
||||
[XmlInclude(typeof(RadialGradientBrush))]
|
||||
[XmlInclude(typeof(MatrixTransform))]
|
||||
public class LayerPropertiesModel
|
||||
{
|
||||
public int X { get; set; }
|
||||
@ -16,23 +18,14 @@ namespace Artemis.Models.Profiles
|
||||
public LayerColorMode ColorMode { get; set; }
|
||||
public bool Rotate { get; set; }
|
||||
public double RotateSpeed { get; set; }
|
||||
public List<Color> Colors { get; set; }
|
||||
|
||||
public LayerPropertiesModel()
|
||||
{
|
||||
Colors = new List<Color>();
|
||||
}
|
||||
public Brush Brush { get; set; }
|
||||
}
|
||||
|
||||
public enum LayerColorMode
|
||||
{
|
||||
[Description("Left to right")]
|
||||
Horizontal,
|
||||
[Description("Top to bottom")]
|
||||
Vertical,
|
||||
[Description("Shift")]
|
||||
Shift,
|
||||
[Description("Pulse")]
|
||||
Pulse,
|
||||
[Description("Gradient")] Gradient,
|
||||
[Description("Moving gradient")] MovingGradient,
|
||||
[Description("Shift")] Shift,
|
||||
[Description("Pulse")] Pulse
|
||||
}
|
||||
}
|
||||
@ -4,11 +4,9 @@ namespace Artemis.Models.Profiles
|
||||
{
|
||||
public class ProfileModel
|
||||
{
|
||||
public ProfileModel(string name, string keyboardName, string gameName)
|
||||
public ProfileModel()
|
||||
{
|
||||
Name = name;
|
||||
KeyboardName = keyboardName;
|
||||
GameName = gameName;
|
||||
Layers = new List<LayerModel>();
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
@ -19,7 +17,8 @@ namespace Artemis.Models.Profiles
|
||||
|
||||
protected bool Equals(ProfileModel other)
|
||||
{
|
||||
return string.Equals(Name, other.Name) && string.Equals(KeyboardName, other.KeyboardName) && string.Equals(GameName, other.GameName);
|
||||
return string.Equals(Name, other.Name) && string.Equals(KeyboardName, other.KeyboardName) &&
|
||||
string.Equals(GameName, other.GameName);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
|
||||
@ -189,7 +189,7 @@
|
||||
|
||||
<Popup IsOpen="{Binding ElementName=PART_OpenPopup,Path=IsChecked}" StaysOpen="False"
|
||||
AllowsTransparency="True" Width="{Binding ActualWidth, ElementName=PART_Root}"
|
||||
MinWidth="250" HorizontalOffset="-1" Placement="Center">
|
||||
MinWidth="250" HorizontalOffset="-1" Placement="Center" PopupAnimation="Fade">
|
||||
<Border Background="{StaticResource ControlBackgroundBrush}"
|
||||
BorderBrush="{StaticResource AccentColorBrush}" BorderThickness="1"
|
||||
Margin="10,0,10,10">
|
||||
@ -731,6 +731,4 @@
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
|
||||
</ResourceDictionary>
|
||||
@ -1,54 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Artemis.Utilities
|
||||
{
|
||||
internal class ImageUtilities
|
||||
{
|
||||
private static Dictionary<string, ImageCodecInfo> encoders;
|
||||
|
||||
/// <summary>
|
||||
/// A lock to prevent concurrency issues loading the encoders.
|
||||
/// </summary>
|
||||
private static readonly object encodersLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// A quick lookup for getting image encoders
|
||||
/// </summary>
|
||||
public static Dictionary<string, ImageCodecInfo> Encoders
|
||||
{
|
||||
//get accessor that creates the dictionary on demand
|
||||
get
|
||||
{
|
||||
//if the quick lookup isn't initialised, initialise it
|
||||
if (encoders == null)
|
||||
{
|
||||
//protect against concurrency issues
|
||||
lock (encodersLock)
|
||||
{
|
||||
//check again, we might not have been the first person to acquire the lock (see the double checked lock pattern)
|
||||
if (encoders == null)
|
||||
{
|
||||
encoders = new Dictionary<string, ImageCodecInfo>();
|
||||
|
||||
//get all the codecs
|
||||
foreach (var codec in ImageCodecInfo.GetImageEncoders())
|
||||
{
|
||||
//add each codec to the quick lookup
|
||||
encoders.Add(codec.MimeType.ToLower(), codec);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return the lookup
|
||||
return encoders;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resize the image to the specified width and height.
|
||||
/// </summary>
|
||||
@ -73,5 +33,29 @@ namespace Artemis.Utilities
|
||||
//return the resulting bitmap
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Bitmap BitmapSourceToBitmap(BitmapSource srs)
|
||||
{
|
||||
var width = srs.PixelWidth;
|
||||
var height = srs.PixelHeight;
|
||||
var stride = width * ((srs.Format.BitsPerPixel + 7) / 8);
|
||||
var ptr = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
ptr = Marshal.AllocHGlobal(height * stride);
|
||||
srs.CopyPixels(new Int32Rect(0, 0, width, height), ptr, height * stride, stride);
|
||||
using (var btm = new Bitmap(width, height, stride, PixelFormat.Format1bppIndexed, ptr))
|
||||
{
|
||||
// Clone the bitmap so that we can dispose it and
|
||||
// release the unmanaged memory at ptr
|
||||
return new Bitmap(btm);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (ptr != IntPtr.Zero)
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,22 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Properties;
|
||||
|
||||
namespace Artemis.Utilities
|
||||
{
|
||||
internal class LayerDrawer
|
||||
{
|
||||
private readonly LayerModel _layerModel;
|
||||
private LinearGradientBrush _brush;
|
||||
private Rectangle _rectangle;
|
||||
private Rect _rectangle;
|
||||
private double _rotationProgress;
|
||||
private Rectangle _userRectangle;
|
||||
private Rect _userRectangle;
|
||||
|
||||
public LayerDrawer(LayerModel layerModel, int scale)
|
||||
{
|
||||
@ -27,22 +21,23 @@ namespace Artemis.Utilities
|
||||
|
||||
public int Scale { get; set; }
|
||||
|
||||
public void Draw(Graphics g)
|
||||
public void Draw(DrawingContext c)
|
||||
{
|
||||
if (_layerModel.LayerCalculatedProperties.Brush == null)
|
||||
return;
|
||||
|
||||
// Set up variables for this frame
|
||||
_rectangle = new Rectangle(_layerModel.LayerCalculatedProperties.X*Scale,
|
||||
_rectangle = new Rect(_layerModel.LayerCalculatedProperties.X*Scale,
|
||||
_layerModel.LayerCalculatedProperties.Y*Scale, _layerModel.LayerCalculatedProperties.Width*Scale,
|
||||
_layerModel.LayerCalculatedProperties.Height*Scale);
|
||||
_userRectangle = new Rectangle(_layerModel.LayerUserProperties.X*Scale,
|
||||
_userRectangle = new Rect(_layerModel.LayerUserProperties.X*Scale,
|
||||
_layerModel.LayerUserProperties.Y*Scale, _layerModel.LayerUserProperties.Width*Scale,
|
||||
_layerModel.LayerUserProperties.Height*Scale);
|
||||
_brush = CreateGradientBrush(
|
||||
_layerModel.LayerCalculatedProperties.Colors.Select(ColorHelpers.ToDrawingColor).ToList());
|
||||
|
||||
if (_layerModel.LayerType == LayerType.KeyboardRectangle)
|
||||
DrawRectangle(g);
|
||||
DrawRectangle(c);
|
||||
else if (_layerModel.LayerType == LayerType.KeyboardEllipse)
|
||||
DrawEllipse(g);
|
||||
DrawEllipse(c);
|
||||
|
||||
// Update the rotation progress
|
||||
_rotationProgress = _rotationProgress + _layerModel.LayerCalculatedProperties.RotateSpeed;
|
||||
@ -55,133 +50,60 @@ namespace Artemis.Utilities
|
||||
|
||||
public BitmapImage GetThumbnail()
|
||||
{
|
||||
_rectangle = new Rectangle(0, 0, 18, 18);
|
||||
_userRectangle = new Rectangle(0, 0, 18, 18);
|
||||
_layerModel.LayerCalculatedProperties.Opacity = 255;
|
||||
var brush =
|
||||
CreateGradientBrush(_layerModel.LayerUserProperties.Colors.Select(ColorHelpers.ToDrawingColor).ToList());
|
||||
var bitmap = new Bitmap(18, 18);
|
||||
if (_layerModel.LayerUserProperties.Brush == null)
|
||||
return null;
|
||||
|
||||
using (var g = Graphics.FromImage(bitmap))
|
||||
{
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
if (_layerModel.LayerType == LayerType.KeyboardEllipse)
|
||||
{
|
||||
g.FillEllipse(brush, _rectangle);
|
||||
g.DrawEllipse(new Pen(Color.Black, 1), 0, 0, 17, 17);
|
||||
}
|
||||
else if (_layerModel.LayerType == LayerType.KeyboardRectangle)
|
||||
{
|
||||
g.FillRectangle(brush, _rectangle);
|
||||
g.DrawRectangle(new Pen(Color.Black, 1), 0, 0, 17, 17);
|
||||
}
|
||||
else
|
||||
bitmap = Resources.folder;
|
||||
_rectangle = new Rect(0, 0, 18, 18);
|
||||
_userRectangle = new Rect(0, 0, 18, 18);
|
||||
|
||||
//var bitmap = new Bitmap(18, 18);
|
||||
|
||||
//using (var g = Graphics.FromImage(bitmap))
|
||||
//{
|
||||
// g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
// if (_layerModel.LayerType == LayerType.KeyboardEllipse)
|
||||
// {
|
||||
// g.FillEllipse(_layerModel.LayerUserProperties.Brush, _rectangle);
|
||||
// g.DrawEllipse(new Pen(Color.Black, 1), 0, 0, 17, 17);
|
||||
// }
|
||||
// else if (_layerModel.LayerType == LayerType.KeyboardRectangle)
|
||||
// {
|
||||
// g.FillRectangle(_layerModel.LayerUserProperties.Brush, _rectangle);
|
||||
// g.DrawRectangle(new Pen(Color.Black, 1), 0, 0, 17, 17);
|
||||
// }
|
||||
// else
|
||||
// bitmap = Resources.folder;
|
||||
//}
|
||||
|
||||
//using (var memory = new MemoryStream())
|
||||
//{
|
||||
// bitmap.Save(memory, ImageFormat.Png);
|
||||
// memory.Position = 0;
|
||||
|
||||
// var bitmapImage = new BitmapImage();
|
||||
// bitmapImage.BeginInit();
|
||||
// bitmapImage.StreamSource = memory;
|
||||
// bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||
// bitmapImage.EndInit();
|
||||
|
||||
// return bitmapImage;
|
||||
//}
|
||||
return null;
|
||||
}
|
||||
|
||||
using (var memory = new MemoryStream())
|
||||
public void DrawRectangle(DrawingContext c)
|
||||
{
|
||||
bitmap.Save(memory, ImageFormat.Png);
|
||||
memory.Position = 0;
|
||||
|
||||
var bitmapImage = new BitmapImage();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.StreamSource = memory;
|
||||
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||
bitmapImage.EndInit();
|
||||
|
||||
return bitmapImage;
|
||||
}
|
||||
c.DrawRectangle(_layerModel.LayerCalculatedProperties.Brush, null, _rectangle);
|
||||
}
|
||||
|
||||
public void DrawRectangle(Graphics g)
|
||||
public void DrawEllipse(DrawingContext c)
|
||||
{
|
||||
g.FillRectangle(_brush, _rectangle);
|
||||
c.DrawEllipse(_layerModel.LayerCalculatedProperties.Brush, null,
|
||||
new Point(_rectangle.Width/2, _rectangle.Height/2), _rectangle.Width, _rectangle.Height);
|
||||
}
|
||||
|
||||
public void DrawEllipse(Graphics g)
|
||||
public void DrawGif(DrawingContext bmp)
|
||||
{
|
||||
g.FillEllipse(_brush, _rectangle);
|
||||
}
|
||||
|
||||
public void DrawGif(Graphics g)
|
||||
{
|
||||
}
|
||||
|
||||
private LinearGradientBrush CreateGradientBrush(List<Color> colors)
|
||||
{
|
||||
ColorBlend colorBlend;
|
||||
var props = _layerModel.LayerCalculatedProperties;
|
||||
// Create a ColorBlend
|
||||
if (colors.Count == 0)
|
||||
{
|
||||
colorBlend = new ColorBlend
|
||||
{
|
||||
Colors = new[] {Color.Transparent, Color.Transparent},
|
||||
Positions = new[] {0F, 1F}
|
||||
};
|
||||
}
|
||||
else if (colors.Count == 1)
|
||||
{
|
||||
colorBlend = new ColorBlend
|
||||
{
|
||||
Colors = new[] {colors[0], colors[0]},
|
||||
Positions = new[] {0F, 1F}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
colorBlend = props.Rotate
|
||||
? new ColorBlend {Colors = CreateTilebleColors(colors).ToArray()}
|
||||
: new ColorBlend {Colors = colors.ToArray()};
|
||||
}
|
||||
|
||||
// If needed, apply opacity to the colors in the blend
|
||||
if (props.Opacity < 255)
|
||||
for (var i = 0; i < colorBlend.Colors.Length; i++)
|
||||
colorBlend.Colors[i] = Color.FromArgb(props.Opacity, colorBlend.Colors[i]);
|
||||
|
||||
// Devide the colors over the colorblend
|
||||
var devider = (float) colorBlend.Colors.Length - 1;
|
||||
var positions = new List<float>();
|
||||
for (var i = 0; i < colorBlend.Colors.Length; i++)
|
||||
positions.Add(i/devider);
|
||||
|
||||
// Apply the devided positions
|
||||
colorBlend.Positions = positions.ToArray();
|
||||
|
||||
RectangleF rect;
|
||||
if (props.Rotate)
|
||||
rect = _layerModel.LayerCalculatedProperties.ContainedBrush
|
||||
? new Rectangle((int) _rotationProgress + _rectangle.X, _rectangle.Y, _rectangle.Width*2,
|
||||
_rectangle.Height*2)
|
||||
: new Rectangle((int) _rotationProgress + _userRectangle.X, _userRectangle.Y, _userRectangle.Width*2,
|
||||
_userRectangle.Height*2);
|
||||
else
|
||||
rect = _layerModel.LayerCalculatedProperties.ContainedBrush
|
||||
? new Rectangle(_rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height)
|
||||
: new Rectangle(_userRectangle.X, _userRectangle.Y, _userRectangle.Width, _userRectangle.Height);
|
||||
|
||||
if (_layerModel.LayerCalculatedProperties.ColorMode == LayerColorMode.Horizontal)
|
||||
return new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, LinearGradientMode.Horizontal)
|
||||
{
|
||||
InterpolationColors = colorBlend
|
||||
};
|
||||
return new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, LinearGradientMode.Vertical)
|
||||
{
|
||||
InterpolationColors = colorBlend
|
||||
};
|
||||
}
|
||||
|
||||
private List<Color> CreateTilebleColors(List<Color> sourceColors)
|
||||
{
|
||||
// Create a list using the original colors
|
||||
var tilebleColors = new List<Color>(sourceColors);
|
||||
// Add the original colors again
|
||||
tilebleColors.AddRange(sourceColors);
|
||||
// Add the first color, smoothing the transition
|
||||
tilebleColors.Add(sourceColors.FirstOrDefault());
|
||||
return tilebleColors;
|
||||
}
|
||||
|
||||
public void UpdateMouse()
|
||||
|
||||
@ -1,35 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Artemis.DAL;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.ViewModels.LayerEditor;
|
||||
using Caliburn.Micro;
|
||||
using Color = System.Windows.Media.Color;
|
||||
|
||||
namespace Artemis.ViewModels
|
||||
{
|
||||
public class LayerEditorViewModel<T> : Screen
|
||||
{
|
||||
private readonly ProfileModel _profile;
|
||||
private readonly BackgroundWorker _previewWorker;
|
||||
private LayerModel _layer;
|
||||
private LayerPropertiesModel _proposedProperties;
|
||||
|
||||
public LayerEditorViewModel(LayerModel layer)
|
||||
public LayerEditorViewModel(ProfileModel profile, LayerModel layer)
|
||||
{
|
||||
_profile = profile;
|
||||
Layer = layer;
|
||||
|
||||
DataModelProps = new BindableCollection<GeneralHelpers.PropertyCollection>();
|
||||
ProposedColors = new BindableCollection<Color>();
|
||||
ProposedProperties = new LayerPropertiesModel();
|
||||
ProposedColors.CollectionChanged += UpdateColors;
|
||||
DataModelProps.AddRange(GeneralHelpers.GenerateTypeMap<T>());
|
||||
|
||||
LayerConditionVms =
|
||||
@ -39,8 +37,8 @@ namespace Artemis.ViewModels
|
||||
_previewWorker = new BackgroundWorker();
|
||||
_previewWorker.WorkerSupportsCancellation = true;
|
||||
_previewWorker.DoWork += PreviewWorkerOnDoWork;
|
||||
|
||||
_previewWorker.RunWorkerAsync();
|
||||
|
||||
PreSelect();
|
||||
}
|
||||
|
||||
@ -48,8 +46,6 @@ namespace Artemis.ViewModels
|
||||
|
||||
public BindableCollection<string> LayerTypes => new BindableCollection<string>();
|
||||
|
||||
public BindableCollection<Color> ProposedColors { get; set; }
|
||||
|
||||
public BindableCollection<LayerConditionViewModel<T>> LayerConditionVms { get; set; }
|
||||
|
||||
public LayerModel Layer
|
||||
@ -80,34 +76,28 @@ namespace Artemis.ViewModels
|
||||
{
|
||||
// For the preview, put the proposed properties into the calculated properties
|
||||
_layer.LayerCalculatedProperties = ProposedProperties;
|
||||
var bitmap = new Bitmap(ProposedProperties.Width*4, ProposedProperties.Height*4);
|
||||
|
||||
using (var g = Graphics.FromImage(bitmap))
|
||||
var visual = new DrawingVisual();
|
||||
using (var drawingContext = visual.RenderOpen())
|
||||
{
|
||||
_layer.DrawPreview(g);
|
||||
}
|
||||
// TODO: Get active keyboard's size * 4
|
||||
var keyboardRect = new Rect(new Size(280, 105));
|
||||
|
||||
using (var memory = new MemoryStream())
|
||||
{
|
||||
bitmap.Save(memory, ImageFormat.Png);
|
||||
memory.Position = 0;
|
||||
// Setup the DrawingVisual's size
|
||||
drawingContext.PushClip(new RectangleGeometry(keyboardRect));
|
||||
drawingContext.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect);
|
||||
|
||||
var bitmapImage = new BitmapImage();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.StreamSource = memory;
|
||||
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||
bitmapImage.EndInit();
|
||||
// Draw the layer
|
||||
_layer.DrawPreview(drawingContext);
|
||||
|
||||
return bitmapImage;
|
||||
// Remove the clip
|
||||
drawingContext.Pop();
|
||||
}
|
||||
var image = new DrawingImage(visual.Drawing);
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateColors(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
ProposedProperties.Colors = ProposedColors.ToList();
|
||||
}
|
||||
|
||||
private void PreviewWorkerOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
|
||||
{
|
||||
while (!_previewWorker.CancellationPending)
|
||||
@ -117,11 +107,9 @@ namespace Artemis.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
private void PreSelect()
|
||||
public void PreSelect()
|
||||
{
|
||||
GeneralHelpers.CopyProperties(ProposedProperties, Layer.LayerUserProperties);
|
||||
ProposedColors.Clear();
|
||||
ProposedColors.AddRange(ProposedProperties.Colors);
|
||||
}
|
||||
|
||||
public void AddCondition()
|
||||
@ -131,19 +119,10 @@ namespace Artemis.ViewModels
|
||||
LayerConditionVms.Add(new LayerConditionViewModel<T>(this, condition, DataModelProps));
|
||||
}
|
||||
|
||||
public void AddColor()
|
||||
{
|
||||
ProposedColors.Add(ColorHelpers.ToMediaColor(ColorHelpers.GetRandomRainbowColor()));
|
||||
}
|
||||
|
||||
public void DeleteColor(Color c)
|
||||
{
|
||||
ProposedColors.Remove(c);
|
||||
}
|
||||
|
||||
public void Apply()
|
||||
{
|
||||
GeneralHelpers.CopyProperties(Layer.LayerUserProperties, ProposedProperties);
|
||||
ProfileProvider.AddOrUpdate(_profile);
|
||||
}
|
||||
|
||||
public void DeleteCondition(LayerConditionViewModel<T> layerConditionViewModel,
|
||||
|
||||
@ -13,9 +13,9 @@ namespace Artemis.ViewModels
|
||||
{
|
||||
private readonly GameModel _gameModel;
|
||||
private readonly MainManager _mainManager;
|
||||
private LayerEditorViewModel<T> _editorVm;
|
||||
private BindableCollection<ProfileModel> _profileModels;
|
||||
private ProfileModel _selectedProfileModel;
|
||||
private LayerEditorViewModel<T> _editorVm;
|
||||
|
||||
public ProfileEditorViewModel(MainManager mainManager, GameModel gameModel)
|
||||
{
|
||||
@ -48,6 +48,8 @@ namespace Artemis.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public LayerModel SelectedLayer { get; set; }
|
||||
|
||||
private void LoadProfiles()
|
||||
{
|
||||
ProfileModels.Clear();
|
||||
@ -67,7 +69,12 @@ namespace Artemis.ViewModels
|
||||
return;
|
||||
}
|
||||
|
||||
var profile = new ProfileModel(name, _mainManager.KeyboardManager.ActiveKeyboard.Name, _gameModel.Name);
|
||||
var profile = new ProfileModel
|
||||
{
|
||||
Name = name,
|
||||
KeyboardName = _mainManager.KeyboardManager.ActiveKeyboard.Name,
|
||||
GameName = _gameModel.Name
|
||||
};
|
||||
if (ProfileProvider.GetAll().Contains(profile))
|
||||
{
|
||||
var overwrite =
|
||||
@ -87,13 +94,28 @@ namespace Artemis.ViewModels
|
||||
public void LayerEditor(LayerModel layer)
|
||||
{
|
||||
IWindowManager manager = new WindowManager();
|
||||
_editorVm = new LayerEditorViewModel<T>(layer);
|
||||
_editorVm = new LayerEditorViewModel<T>(SelectedProfileModel, layer);
|
||||
dynamic settings = new ExpandoObject();
|
||||
|
||||
settings.Title = "Artemis | Edit " + layer.Name;
|
||||
manager.ShowDialog(_editorVm, null, settings);
|
||||
}
|
||||
|
||||
public void SetSelectedLayer(LayerModel layer)
|
||||
{
|
||||
SelectedLayer = layer;
|
||||
}
|
||||
|
||||
public void AddLayer()
|
||||
{
|
||||
_selectedProfileModel.Layers.Add(new LayerModel
|
||||
{
|
||||
Name = "Layer " + (_selectedProfileModel.Layers.Count + 1),
|
||||
LayerType = LayerType.KeyboardRectangle
|
||||
});
|
||||
NotifyOfPropertyChange();
|
||||
}
|
||||
|
||||
private ImageSource GenerateKeyboardImage()
|
||||
{
|
||||
return null;
|
||||
|
||||
@ -169,59 +169,25 @@
|
||||
</ComboBox>
|
||||
|
||||
<!-- Colors -->
|
||||
<TextBlock Grid.Row="10" Grid.Column="2" Margin="10,13,10,0" FontSize="13.333" Text="Colors:"
|
||||
<TextBlock Grid.Row="10" Grid.Column="2" Margin="10,13,10,0" FontSize="13.333" Text="Color(s):"
|
||||
VerticalAlignment="Top" Height="18" />
|
||||
<StackPanel Grid.Row="10" Grid.Column="3" Grid.RowSpan="2">
|
||||
<ncore:ColorBox Width="100" Height="25"></ncore:ColorBox>
|
||||
<!--<Border BorderThickness="1" BorderBrush="{StaticResource GrayBrush7}" Margin="10">
|
||||
<ListBox Height="108" ItemsSource="{Binding Path=ProposedColors}"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Visible" VerticalAlignment="Top">
|
||||
<ListBox.Template>
|
||||
<ControlTemplate>
|
||||
<ScrollViewer>
|
||||
<ItemsPresenter />
|
||||
</ScrollViewer>
|
||||
</ControlTemplate>
|
||||
</ListBox.Template>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<xctk:ColorPicker SelectedColor="{Binding Path=.}"
|
||||
VerticalAlignment="Center" Width="100" Height="26"/>
|
||||
<Button x:Name="Delete" Width="26" Height="26"
|
||||
Style="{DynamicResource SquareButtonStyle}"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Right" Margin="5,5,0,5"
|
||||
cal:Message.Attach="DeleteColor($datacontext)">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="Black" Width="12" Height="12">
|
||||
<Rectangle.OpacityMask>
|
||||
<VisualBrush Visual="{StaticResource appbar_delete}" Stretch="Fill" />
|
||||
</Rectangle.OpacityMask>
|
||||
</Rectangle>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Border>-->
|
||||
<Button x:Name="AddColor" Content="Add color"
|
||||
VerticalAlignment="Center"
|
||||
Style="{DynamicResource SquareButtonStyle}" Width="95" HorizontalAlignment="Right" Height="30"
|
||||
Margin="10,0,10,10" ScrollViewer.VerticalScrollBarVisibility="Auto" />
|
||||
</StackPanel>
|
||||
|
||||
<Border Grid.Row="10" Grid.Column="3" Margin="10" BorderThickness="1" BorderBrush="{StaticResource ControlBorderBrush}" ToolTip="Click to edit">
|
||||
<ncore:ColorBox Brush="{Binding Path=ProposedProperties.Brush, Mode=TwoWay}" />
|
||||
</Border>
|
||||
<!-- Preview -->
|
||||
<TextBlock Grid.Row="11" Grid.Column="0" Margin="10,13,10,0" FontSize="13.333" Text="Preview:"
|
||||
VerticalAlignment="Top" Height="18" />
|
||||
<Border Grid.Row="11" Grid.Column="1" Grid.ColumnSpan="2" Margin="10" BorderThickness="1"
|
||||
BorderBrush="{StaticResource GrayBrush7}" Width="280" Height="105">
|
||||
<Image Source="{Binding LayerImage}" Stretch="Uniform" />
|
||||
BorderBrush="{StaticResource ControlBorderBrush}" Width="280" Height="105">
|
||||
<Image Source="{Binding LayerImage}" />
|
||||
</Border>
|
||||
|
||||
<Button Grid.Row="12" Grid.Column="0" x:Name="Apply" Content="Apply" VerticalAlignment="Bottom"
|
||||
Style="{DynamicResource SquareButtonStyle}" Width="95" HorizontalAlignment="Left" Margin="10,0,0,20"
|
||||
Height="30" />
|
||||
<Button Grid.Row="12" Grid.Column="1" x:Name="PreSelect" Content="Reset" VerticalAlignment="Bottom"
|
||||
Style="{DynamicResource SquareButtonStyle}" Width="95" HorizontalAlignment="Left" Margin="10,0,0,20"
|
||||
Height="30" />
|
||||
</Grid>
|
||||
|
||||
</controls:MetroWindow>
|
||||
@ -12,6 +12,7 @@ using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using MahApps.Metro.Controls;
|
||||
using ColorBox;
|
||||
|
||||
namespace Artemis.Views
|
||||
{
|
||||
|
||||
@ -59,7 +59,7 @@
|
||||
</TreeView.Resources>
|
||||
<TreeView.ItemTemplate>
|
||||
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
|
||||
<StackPanel Orientation="Horizontal" Tag="{Binding DataContext, ElementName=ProfileTree}">
|
||||
<StackPanel Orientation="Horizontal" Tag="{Binding DataContext, ElementName=ProfileTree}" cal:Message.Attach="SetSelectedLayer($datacontext)">
|
||||
<StackPanel.ContextMenu>
|
||||
<ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
|
||||
<MenuItem Header="Rename" />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user