1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Added images for all the Corsair keyboards. ProfileEditor now shows layers

This commit is contained in:
SpoinkyNL 2016-04-11 22:45:31 +02:00
parent 2c1ddb824a
commit e78906bfa3
26 changed files with 360 additions and 66 deletions

View File

@ -267,6 +267,7 @@
</Compile> </Compile>
<Compile Include="ArtemisBootstrapper.cs" /> <Compile Include="ArtemisBootstrapper.cs" />
<Compile Include="DAL\ProfileProvider.cs" /> <Compile Include="DAL\ProfileProvider.cs" />
<Compile Include="Events\ActiveKeyboardChanged.cs" />
<Compile Include="Events\ToggleEnabled.cs" /> <Compile Include="Events\ToggleEnabled.cs" />
<Compile Include="Events\ActiveEffectChanged.cs" /> <Compile Include="Events\ActiveEffectChanged.cs" />
<Compile Include="Events\ChangeBitmap.cs" /> <Compile Include="Events\ChangeBitmap.cs" />
@ -498,8 +499,8 @@
</Compile> </Compile>
<EmbeddedResource Include="Properties\Resources.resx"> <EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType> <SubType>Designer</SubType>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<None Include="Modules\Effects\AudioVisualizer\AudioVisualization.settings"> <None Include="Modules\Effects\AudioVisualizer\AudioVisualization.settings">
<Generator>SettingsSingleFileGenerator</Generator> <Generator>SettingsSingleFileGenerator</Generator>
@ -546,6 +547,10 @@
<Resource Include="Resources\Dota2\dotaGamestateConfiguration.txt" /> <Resource Include="Resources\Dota2\dotaGamestateConfiguration.txt" />
<None Include="Resources\LogitechLED.dll" /> <None Include="Resources\LogitechLED.dll" />
<None Include="Resources\folder.png" /> <None Include="Resources\folder.png" />
<Resource Include="Resources\Keyboards\k65.png" />
<Resource Include="Resources\Keyboards\k70.png" />
<Resource Include="Resources\Keyboards\k95.png" />
<Resource Include="Resources\Keyboards\strafe.png" />
<Content Include="Resources\Witcher3\playerWitcher.txt" /> <Content Include="Resources\Witcher3\playerWitcher.txt" />
<Content Include="Resources\Witcher3\artemis.txt" /> <Content Include="Resources\Witcher3\artemis.txt" />
<Resource Include="Resources\Entypo.ttf" /> <Resource Include="Resources\Entypo.ttf" />

View File

@ -1,6 +1,7 @@
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms; using System.Windows.Forms;
using Artemis.ViewModels; using Artemis.ViewModels;
using Autofac; using Autofac;
@ -18,6 +19,47 @@ namespace Artemis
CheckDuplicateInstances(); CheckDuplicateInstances();
Initialize(); Initialize();
MessageBinder.SpecialValues.Add("$scaledmousex", (ctx) =>
{
var img = ctx.Source as Image;
var input = ctx.Source as IInputElement;
var e = ctx.EventArgs as System.Windows.Input.MouseEventArgs;
// If there is an image control, get the scaled position
if (img != null && e != null)
{
Point position = e.GetPosition(img);
return (int)(img.Source.Width * (position.X / img.ActualWidth));
}
// If there is another type of of IInputControl get the non-scaled position - or do some processing to get a scaled position, whatever needs to happen
if (e != null && input != null)
return e.GetPosition(input).X;
// Return 0 if no processing could be done
return 0;
});
MessageBinder.SpecialValues.Add("$scaledmousey", (ctx) =>
{
var img = ctx.Source as Image;
var input = ctx.Source as IInputElement;
var e = ctx.EventArgs as System.Windows.Input.MouseEventArgs;
// If there is an image control, get the scaled position
if (img != null && e != null)
{
Point position = e.GetPosition(img);
return (int)(img.Source.Width * (position.Y / img.ActualWidth));
}
// If there is another type of of IInputControl get the non-scaled position - or do some processing to get a scaled position, whatever needs to happen
if (e != null && input != null)
return e.GetPosition(input).Y;
// Return 0 if no processing could be done
return 0;
});
} }
protected override void ConfigureContainer(ContainerBuilder builder) protected override void ConfigureContainer(ContainerBuilder builder)
@ -45,5 +87,6 @@ namespace Artemis
"Artemis (╯°□°)╯︵ ┻━┻", MessageBoxButtons.OK, MessageBoxIcon.Warning); "Artemis (╯°□°)╯︵ ┻━┻", MessageBoxButtons.OK, MessageBoxIcon.Warning);
Application.Current.Shutdown(); Application.Current.Shutdown();
} }
} }
} }

View File

@ -0,0 +1,12 @@
namespace Artemis.Events
{
public class ActiveKeyboardChanged
{
public ActiveKeyboardChanged(string activeKeyboard)
{
ActiveKeyboard = activeKeyboard;
}
public string ActiveKeyboard { get; set; }
}
}

View File

@ -1,20 +1,22 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Threading; using System.Threading;
using System.Windows;
using Artemis.Properties;
using Artemis.Utilities; using Artemis.Utilities;
using CUE.NET; using CUE.NET;
using CUE.NET.Brushes; using CUE.NET.Brushes;
using CUE.NET.Devices.Generic.Enums; using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Devices.Headset;
using CUE.NET.Devices.Keyboard; using CUE.NET.Devices.Keyboard;
using CUE.NET.Devices.Mouse;
using CUE.NET.Exceptions; using CUE.NET.Exceptions;
using Point = System.Drawing.Point;
namespace Artemis.KeyboardProviders.Corsair namespace Artemis.KeyboardProviders.Corsair
{ {
internal class CorsairRGB : KeyboardProvider internal class CorsairRGB : KeyboardProvider
{ {
private CorsairKeyboard _keyboard; private CorsairKeyboard _keyboard;
public CorsairRGB() public CorsairRGB()
{ {
Name = "Corsair RGB Keyboards"; Name = "Corsair RGB Keyboards";
@ -74,6 +76,7 @@ namespace Artemis.KeyboardProviders.Corsair
case "K95 RGB": case "K95 RGB":
Height = 7; Height = 7;
Width = 25; Width = 25;
PreviewSettings = new PreviewSettings(626, 175, new Thickness(0,-15,0,0), Resources.k95);
KeyboardRegions.Add(new KeyboardRegion("TopRow", new Point(0, 1), new Point(20, 1))); KeyboardRegions.Add(new KeyboardRegion("TopRow", new Point(0, 1), new Point(20, 1)));
KeyboardRegions.Add(new KeyboardRegion("NumPad", new Point(21, 2), new Point(25, 7))); KeyboardRegions.Add(new KeyboardRegion("NumPad", new Point(21, 2), new Point(25, 7)));
KeyboardRegions.Add(new KeyboardRegion("QWER", new Point(5, 3), new Point(8, 3))); KeyboardRegions.Add(new KeyboardRegion("QWER", new Point(5, 3), new Point(8, 3)));
@ -81,6 +84,7 @@ namespace Artemis.KeyboardProviders.Corsair
case "K70 RGB": case "K70 RGB":
Height = 7; Height = 7;
Width = 21; Width = 21;
PreviewSettings = new PreviewSettings(626, 175, new Thickness(0, -15, 0, 0), Resources.k70);
KeyboardRegions.Add(new KeyboardRegion("TopRow", new Point(0, 1), new Point(18, 1))); KeyboardRegions.Add(new KeyboardRegion("TopRow", new Point(0, 1), new Point(18, 1)));
KeyboardRegions.Add(new KeyboardRegion("NumPad", new Point(17, 2), new Point(21, 7))); KeyboardRegions.Add(new KeyboardRegion("NumPad", new Point(17, 2), new Point(21, 7)));
KeyboardRegions.Add(new KeyboardRegion("QWER", new Point(2, 3), new Point(5, 3))); KeyboardRegions.Add(new KeyboardRegion("QWER", new Point(2, 3), new Point(5, 3)));
@ -88,16 +92,18 @@ namespace Artemis.KeyboardProviders.Corsair
case "K65 RGB": case "K65 RGB":
Height = 7; Height = 7;
Width = 18; Width = 18;
PreviewSettings = new PreviewSettings(626, 175, new Thickness(0, -15, 0, 0), Resources.k65);
KeyboardRegions.Add(new KeyboardRegion("TopRow", new Point(0, 1), new Point(18, 1))); KeyboardRegions.Add(new KeyboardRegion("TopRow", new Point(0, 1), new Point(18, 1)));
KeyboardRegions.Add(new KeyboardRegion("NumPad", new Point(17, 2), new Point(20, 7))); KeyboardRegions.Add(new KeyboardRegion("NumPad", new Point(17, 2), new Point(20, 7)));
KeyboardRegions.Add(new KeyboardRegion("QWER", new Point(2, 3), new Point(5, 3))); KeyboardRegions.Add(new KeyboardRegion("QWER", new Point(2, 3), new Point(5, 3)));
break; break;
case "STRAFE RGB": case "STRAFE RGB":
Height = 6; Height = 6;
Width = 22;
PreviewSettings = new PreviewSettings(626, 175, new Thickness(0, -15, 0, 0), Resources.strafe);
KeyboardRegions.Add(new KeyboardRegion("TopRow", new Point(0, 1), new Point(18, 1))); KeyboardRegions.Add(new KeyboardRegion("TopRow", new Point(0, 1), new Point(18, 1)));
KeyboardRegions.Add(new KeyboardRegion("NumPad", new Point(18, 2), new Point(22, 7))); KeyboardRegions.Add(new KeyboardRegion("NumPad", new Point(18, 2), new Point(22, 7)));
KeyboardRegions.Add(new KeyboardRegion("QWER", new Point(1, 3), new Point(4, 3))); KeyboardRegions.Add(new KeyboardRegion("QWER", new Point(1, 3), new Point(4, 3)));
Width = 22;
break; break;
} }
} }
@ -106,7 +112,7 @@ namespace Artemis.KeyboardProviders.Corsair
{ {
CueSDK.Reinitialize(); CueSDK.Reinitialize();
} }
/// <summary> /// <summary>
/// Properly resizes any size bitmap to the keyboard by creating a rectangle whose size is dependent on the bitmap /// Properly resizes any size bitmap to the keyboard by creating a rectangle whose size is dependent on the bitmap
/// size. /// size.
@ -118,7 +124,7 @@ namespace Artemis.KeyboardProviders.Corsair
using (var g = Graphics.FromImage(fixedBmp)) using (var g = Graphics.FromImage(fixedBmp))
{ {
g.Clear(Color.Black); g.Clear(Color.Black);
g.DrawImage(bitmap, 0,0); g.DrawImage(bitmap, 0, 0);
} }
var fixedImage = ImageUtilities.ResizeImage(fixedBmp, Width, Height); var fixedImage = ImageUtilities.ResizeImage(fixedBmp, Width, Height);
@ -131,4 +137,4 @@ namespace Artemis.KeyboardProviders.Corsair
_keyboard.Update(); _keyboard.Update();
} }
} }
} }

View File

@ -14,6 +14,8 @@ namespace Artemis.KeyboardProviders
public List<KeyboardRegion> KeyboardRegions { get; set; } public List<KeyboardRegion> KeyboardRegions { get; set; }
public PreviewSettings PreviewSettings { get; set; }
public abstract bool CanEnable(); public abstract bool CanEnable();
public abstract void Enable(); public abstract void Enable();
public abstract void Disable(); public abstract void Disable();
@ -33,4 +35,20 @@ namespace Artemis.KeyboardProviders
public Rect KeyboardRectangle(int scale) => new Rect(new Size(Width*scale, Height*scale)); public Rect KeyboardRectangle(int scale) => new Rect(new Size(Width*scale, Height*scale));
} }
public struct PreviewSettings
{
public int Width { get; set; }
public int Height { get; set; }
public Thickness Margin { get; set; }
public Bitmap Image { get; set; }
public PreviewSettings(int width, int height, Thickness margin, Bitmap image)
{
Width = width;
Height = height;
Margin = margin;
Image = image;
}
}
} }

View File

@ -14,6 +14,7 @@ namespace Artemis.Managers
private readonly MainManager _mainManager; private readonly MainManager _mainManager;
private bool _clearing; private bool _clearing;
private EffectModel _pauseEffect; private EffectModel _pauseEffect;
private EffectModel _activeEffect;
public EffectManager(MainManager mainManager, IEventAggregator events) public EffectManager(MainManager mainManager, IEventAggregator events)
{ {
@ -24,7 +25,16 @@ namespace Artemis.Managers
} }
public List<EffectModel> EffectModels { get; set; } public List<EffectModel> EffectModels { get; set; }
public EffectModel ActiveEffect { get; private set; }
public EffectModel ActiveEffect
{
get { return _activeEffect; }
private set
{
_activeEffect = value;
_events.PublishOnUIThread(new ActiveEffectChanged(value?.Name));
}
}
public IEnumerable<OverlayModel> EnabledOverlays public IEnumerable<OverlayModel> EnabledOverlays
{ {
@ -101,7 +111,7 @@ namespace Artemis.Managers
ActiveEffect.Enable(); ActiveEffect.Enable();
// Let the ViewModels know // Let the ViewModels know
_events.PublishOnUIThread(new ActiveEffectChanged(ActiveEffect.Name)); //_events.PublishOnUIThread(new ActiveEffectChanged(ActiveEffect.Name));
_mainManager.Unpause(); _mainManager.Unpause();
_pauseEffect = null; _pauseEffect = null;
@ -143,7 +153,7 @@ namespace Artemis.Managers
General.Default.LastEffect = null; General.Default.LastEffect = null;
General.Default.Save(); General.Default.Save();
_events.PublishOnUIThread(new ActiveEffectChanged("")); //_events.PublishOnUIThread(new ActiveEffectChanged(""));
_clearing = false; _clearing = false;
_mainManager.Unpause(); _mainManager.Unpause();

View File

@ -1,23 +1,37 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Windows.Forms; using Artemis.Events;
using Artemis.KeyboardProviders; using Artemis.KeyboardProviders;
using Artemis.Settings; using Artemis.Settings;
using Caliburn.Micro;
namespace Artemis.Managers namespace Artemis.Managers
{ {
public class KeyboardManager public class KeyboardManager
{ {
private readonly IEventAggregator _events;
private readonly MainManager _mainManager; private readonly MainManager _mainManager;
private KeyboardProvider _activeKeyboard;
public KeyboardManager(MainManager mainManager) public KeyboardManager(MainManager mainManager, IEventAggregator events)
{ {
_mainManager = mainManager; _mainManager = mainManager;
_events = events;
KeyboardProviders = ProviderHelper.GetKeyboardProviders(); KeyboardProviders = ProviderHelper.GetKeyboardProviders();
} }
public List<KeyboardProvider> KeyboardProviders { get; set; } public List<KeyboardProvider> KeyboardProviders { get; set; }
public KeyboardProvider ActiveKeyboard { get; set; }
public KeyboardProvider ActiveKeyboard
{
get { return _activeKeyboard; }
set
{
_activeKeyboard = value;
// Let the ViewModels know
_events.PublishOnUIThread(new ActiveKeyboardChanged(value?.Name));
}
}
/// <summary> /// <summary>
/// Enables the last keyboard according to the settings file /// Enables the last keyboard according to the settings file

View File

@ -25,7 +25,7 @@ namespace Artemis.Managers
Events = events; Events = events;
DialogService = dialogService; DialogService = dialogService;
KeyboardManager = new KeyboardManager(this); KeyboardManager = new KeyboardManager(this, Events);
EffectManager = new EffectManager(this, Events); EffectManager = new EffectManager(this, Events);
KeyboardHook = new KeyboardHook(); KeyboardHook = new KeyboardHook();

View File

@ -26,8 +26,9 @@ namespace Artemis.Models.Profiles
public string Name { get; set; } public string Name { get; set; }
public LayerType LayerType { get; set; } public LayerType LayerType { get; set; }
public bool Enabled { get; set; }
public LayerPropertiesModel LayerUserProperties { get; set; } public LayerPropertiesModel LayerUserProperties { get; set; }
public List<LayerModel> Children { get; set; } public List<LayerModel> Children { get; set; }
public List<LayerConditionModel> LayerConditions { get; set; } public List<LayerConditionModel> LayerConditions { get; set; }
public List<LayerDynamicPropertiesModel> LayerProperties { get; set; } public List<LayerDynamicPropertiesModel> LayerProperties { get; set; }
@ -40,11 +41,12 @@ namespace Artemis.Models.Profiles
public bool ConditionsMet<T>(IGameDataModel dataModel) public bool ConditionsMet<T>(IGameDataModel dataModel)
{ {
return LayerConditions.All(cm => cm.ConditionMet<T>(dataModel)); return Enabled && LayerConditions.All(cm => cm.ConditionMet<T>(dataModel));
} }
public void DrawPreview(DrawingContext c) public void DrawPreview(DrawingContext c)
{ {
GeneralHelpers.CopyProperties(LayerCalculatedProperties, LayerUserProperties);
if (LayerType == LayerType.KeyboardRectangle || LayerType == LayerType.KeyboardEllipse) if (LayerType == LayerType.KeyboardRectangle || LayerType == LayerType.KeyboardEllipse)
_drawer.Draw(c); _drawer.Draw(c);
else if (LayerType == LayerType.KeyboardGif) else if (LayerType == LayerType.KeyboardGif)

View File

@ -13,7 +13,7 @@ namespace Artemis.Models.Profiles
public int Y { get; set; } public int Y { get; set; }
public int Width { get; set; } public int Width { get; set; }
public int Height { get; set; } public int Height { get; set; }
public int Opacity { get; set; } public double Opacity { get; set; }
public bool ContainedBrush { get; set; } public bool ContainedBrush { get; set; }
public LayerAnimation Animation { get; set; } public LayerAnimation Animation { get; set; }
public double AnimationSpeed { get; set; } public double AnimationSpeed { get; set; }

View File

@ -1,4 +1,5 @@
using System.Drawing; using System.Diagnostics;
using System.Drawing;
using System.Windows.Media; using System.Windows.Media;
using Artemis.Managers; using Artemis.Managers;
using Artemis.Models; using Artemis.Models;
@ -88,6 +89,8 @@ namespace Artemis.Modules.Games.CounterStrike
if (!jsonString.Contains("Counter-Strike: Global Offensive")) if (!jsonString.Contains("Counter-Strike: Global Offensive"))
return; return;
Debug.WriteLine("Received data");
// Parse the JSON // Parse the JSON
GameDataModel = JsonConvert.DeserializeObject<CounterStrikeDataModel>(jsonString); GameDataModel = JsonConvert.DeserializeObject<CounterStrikeDataModel>(jsonString);
} }

View File

@ -91,10 +91,7 @@ namespace Artemis.Properties {
/// Looks up a localized string similar to &quot;Artemis&quot; /// Looks up a localized string similar to &quot;Artemis&quot;
///{ ///{
/// &quot;uri&quot; &quot;http://localhost:{{port}}/csgo_game_event&quot; /// &quot;uri&quot; &quot;http://localhost:{{port}}/csgo_game_event&quot;
/// &quot;timeout&quot; &quot;5.0&quot; /// &quot;timeout&quot; &quot;0.1&quot;
/// &quot;buffer&quot; &quot;0.1&quot;
/// &quot;throttle&quot; &quot;0.1&quot;
/// &quot;heartbeat&quot; &quot;30.0&quot;
/// &quot;data&quot; /// &quot;data&quot;
/// { /// {
/// &quot;provider&quot; &quot;1&quot; /// &quot;provider&quot; &quot;1&quot;
@ -148,6 +145,36 @@ namespace Artemis.Properties {
} }
} }
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap k65 {
get {
object obj = ResourceManager.GetObject("k65", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap k70 {
get {
object obj = ResourceManager.GetObject("k70", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap k95 {
get {
object obj = ResourceManager.GetObject("k95", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary> /// <summary>
/// Looks up a localized resource of type System.Byte[]. /// Looks up a localized resource of type System.Byte[].
/// </summary> /// </summary>
@ -201,5 +228,15 @@ namespace Artemis.Properties {
return ResourceManager.GetString("playerWitcherWs", resourceCulture); return ResourceManager.GetString("playerWitcherWs", resourceCulture);
} }
} }
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap strafe {
get {
object obj = ResourceManager.GetObject("strafe", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
} }
} }

View File

@ -145,4 +145,16 @@
<data name="folder" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="folder" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\folder.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Resources\folder.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="k65" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\resources\keyboards\k65.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="k70" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\resources\keyboards\k70.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="k95" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\resources\keyboards\k95.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="strafe" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\resources\keyboards\strafe.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root> </root>

View File

@ -1,10 +1,7 @@
"Artemis" "Artemis"
{ {
"uri" "http://localhost:{{port}}/csgo_game_event" "uri" "http://localhost:{{port}}/csgo_game_event"
"timeout" "5.0" "timeout" "0.1"
"buffer" "0.1"
"throttle" "0.1"
"heartbeat" "30.0"
"data" "data"
{ {
"provider" "1" "provider" "1"

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

View File

@ -189,7 +189,7 @@
<Popup IsOpen="{Binding ElementName=PART_OpenPopup,Path=IsChecked}" StaysOpen="False" <Popup IsOpen="{Binding ElementName=PART_OpenPopup,Path=IsChecked}" StaysOpen="False"
AllowsTransparency="True" Width="{Binding ActualWidth, ElementName=PART_Root}" AllowsTransparency="True" Width="{Binding ActualWidth, ElementName=PART_Root}"
MinWidth="250" HorizontalOffset="-1" Placement="Center" PopupAnimation="Fade"> MinWidth="250" HorizontalOffset="-1" Placement="Top" PopupAnimation="Fade">
<Border Background="{StaticResource ControlBackgroundBrush}" <Border Background="{StaticResource ControlBackgroundBrush}"
BorderBrush="{StaticResource AccentColorBrush}" BorderThickness="1" BorderBrush="{StaticResource AccentColorBrush}" BorderThickness="1"
Margin="10,0,10,10"> Margin="10,0,10,10">
@ -492,8 +492,7 @@
SelectedGradient="{Binding}" SelectedGradient="{Binding}"
Margin="0,0,0,2"> Margin="0,0,0,2">
<nc:GradientStopSlider.Background> <nc:GradientStopSlider.Background>
<SolidColorBrush <SolidColorBrush Color="{Binding Color}"/>
Color="{Binding Color}" />
</nc:GradientStopSlider.Background> </nc:GradientStopSlider.Background>
</nc:GradientStopSlider> </nc:GradientStopSlider>

View File

@ -57,8 +57,8 @@ namespace Artemis.Utilities.GameState
return; return;
try try
{ {
var rstr = HandleRequest(ctx.Request); HandleRequest(ctx.Request);
var buf = Encoding.UTF8.GetBytes(rstr); var buf = Encoding.UTF8.GetBytes("ok");
ctx.Response.ContentLength64 = buf.Length; ctx.Response.ContentLength64 = buf.Length;
ctx.Response.OutputStream.Write(buf, 0, buf.Length); ctx.Response.OutputStream.Write(buf, 0, buf.Length);
} }

View File

@ -1,4 +1,5 @@
using System.Windows; using System;
using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using Artemis.Models.Profiles; using Artemis.Models.Profiles;
@ -27,6 +28,8 @@ namespace Artemis.Utilities
if (_layerModel.LayerCalculatedProperties.Brush == null) if (_layerModel.LayerCalculatedProperties.Brush == null)
return; return;
UpdateAnimation();
// Set up variables for this frame // Set up variables for this frame
_rectangle = new Rect(_layerModel.LayerCalculatedProperties.X*Scale, _rectangle = new Rect(_layerModel.LayerCalculatedProperties.X*Scale,
_layerModel.LayerCalculatedProperties.Y*Scale, _layerModel.LayerCalculatedProperties.Width*Scale, _layerModel.LayerCalculatedProperties.Y*Scale, _layerModel.LayerCalculatedProperties.Width*Scale,
@ -36,12 +39,14 @@ namespace Artemis.Utilities
_layerModel.LayerCalculatedProperties.Brush.Dispatcher.Invoke(() => DrawRectangle(c)); _layerModel.LayerCalculatedProperties.Brush.Dispatcher.Invoke(() => DrawRectangle(c));
else if (_layerModel.LayerType == LayerType.KeyboardEllipse) else if (_layerModel.LayerType == LayerType.KeyboardEllipse)
_layerModel.LayerCalculatedProperties.Brush.Dispatcher.Invoke(() => DrawEllipse(c)); _layerModel.LayerCalculatedProperties.Brush.Dispatcher.Invoke(() => DrawEllipse(c));
UpdateAnimation();
} }
private void UpdateAnimation() private void UpdateAnimation()
{ {
if (!_layerModel.Enabled)
return;
// Slide right animation
if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideRight) if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideRight)
{ {
_firstRect = new Rect(new Point(_rectangle.X + _animationProgress, _rectangle.Y), _firstRect = new Rect(new Point(_rectangle.X + _animationProgress, _rectangle.Y),
@ -52,16 +57,20 @@ namespace Artemis.Utilities
if (_animationProgress > _layerModel.LayerCalculatedProperties.Width*4) if (_animationProgress > _layerModel.LayerCalculatedProperties.Width*4)
_animationProgress = 0; _animationProgress = 0;
} }
// Slide left animation
if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideLeft) if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideLeft)
{ {
_firstRect = new Rect(new Point(_rectangle.X - _animationProgress, _rectangle.Y), _firstRect = new Rect(new Point(_rectangle.X - _animationProgress, _rectangle.Y),
new Size(_rectangle.Width + 1, _rectangle.Height)); new Size(_rectangle.Width + 1, _rectangle.Height));
_secondRect = new Rect(new Point(_firstRect.X + _rectangle.Width, _rectangle.Y), _secondRect = new Rect(new Point(_firstRect.X + _rectangle.Width, _rectangle.Y),
new Size(_rectangle.Width , _rectangle.Height)); new Size(_rectangle.Width, _rectangle.Height));
if (_animationProgress > _layerModel.LayerCalculatedProperties.Width*4) if (_animationProgress > _layerModel.LayerCalculatedProperties.Width*4)
_animationProgress = 0; _animationProgress = 0;
} }
// Slide down animation
if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideDown) if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideDown)
{ {
_firstRect = new Rect(new Point(_rectangle.X, _rectangle.Y + _animationProgress), _firstRect = new Rect(new Point(_rectangle.X, _rectangle.Y + _animationProgress),
@ -69,9 +78,11 @@ namespace Artemis.Utilities
_secondRect = new Rect(new Point(_firstRect.X, _firstRect.Y - _rectangle.Height), _secondRect = new Rect(new Point(_firstRect.X, _firstRect.Y - _rectangle.Height),
new Size(_rectangle.Width, _rectangle.Height)); new Size(_rectangle.Width, _rectangle.Height));
if (_animationProgress > _layerModel.LayerCalculatedProperties.Height * 4) if (_animationProgress > _layerModel.LayerCalculatedProperties.Height*4)
_animationProgress = 0; _animationProgress = 0;
} }
// Slide up animation
if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideUp) if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideUp)
{ {
_firstRect = new Rect(new Point(_rectangle.X, _rectangle.Y - _animationProgress), _firstRect = new Rect(new Point(_rectangle.X, _rectangle.Y - _animationProgress),
@ -79,12 +90,25 @@ namespace Artemis.Utilities
_secondRect = new Rect(new Point(_firstRect.X, _firstRect.Y + _rectangle.Height), _secondRect = new Rect(new Point(_firstRect.X, _firstRect.Y + _rectangle.Height),
new Size(_rectangle.Width, _rectangle.Height)); new Size(_rectangle.Width, _rectangle.Height));
if (_animationProgress > _layerModel.LayerCalculatedProperties.Height * 4) if (_animationProgress > _layerModel.LayerCalculatedProperties.Height*4)
_animationProgress = 0; _animationProgress = 0;
} }
// Update the rotation progress // Pulse animation
_animationProgress = _animationProgress + _layerModel.LayerCalculatedProperties.AnimationSpeed; if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.Pulse)
{
var opac = (Math.Sin(_animationProgress*Math.PI) + 1)*(_layerModel.LayerUserProperties.Opacity/2);
_layerModel.LayerCalculatedProperties.Opacity = opac;
if (_animationProgress > 2)
_animationProgress = 0;
_animationProgress = _animationProgress + _layerModel.LayerCalculatedProperties.AnimationSpeed/2;
}
else
{
// Update the animation progress
_animationProgress = _animationProgress + _layerModel.LayerCalculatedProperties.AnimationSpeed;
}
} }
public BitmapImage GetThumbnail() public BitmapImage GetThumbnail()
@ -131,7 +155,9 @@ namespace Artemis.Utilities
public void DrawRectangle(DrawingContext c) public void DrawRectangle(DrawingContext c)
{ {
_layerModel.LayerCalculatedProperties.Brush.Opacity = _layerModel.LayerCalculatedProperties.Opacity; //_layerModel.LayerCalculatedProperties.Brush.Opacity = _layerModel.LayerCalculatedProperties.Opacity;
var brush = _layerModel.LayerCalculatedProperties.Brush.CloneCurrentValue();
brush.Opacity = _layerModel.LayerCalculatedProperties.Opacity;
if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideDown || if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideDown ||
_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideLeft || _layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideLeft ||
@ -139,13 +165,13 @@ namespace Artemis.Utilities
_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideUp) _layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideUp)
{ {
c.PushClip(new RectangleGeometry(_rectangle)); c.PushClip(new RectangleGeometry(_rectangle));
c.DrawRectangle(_layerModel.LayerCalculatedProperties.Brush, null, _firstRect); c.DrawRectangle(brush, null, _firstRect);
c.DrawRectangle(_layerModel.LayerCalculatedProperties.Brush, null, _secondRect); c.DrawRectangle(brush, null, _secondRect);
c.Pop(); c.Pop();
} }
else else
{ {
c.DrawRectangle(_layerModel.LayerCalculatedProperties.Brush, null, _rectangle); c.DrawRectangle(brush, null, _rectangle);
} }
} }

View File

@ -90,7 +90,7 @@ namespace Artemis.ViewModels.Flyouts
public void Handle(ActiveEffectChanged message) public void Handle(ActiveEffectChanged message)
{ {
var effectDisplay = message.ActiveEffect.Length > 0 ? message.ActiveEffect : "none"; var effectDisplay = string.IsNullOrEmpty(message.ActiveEffect) ? message.ActiveEffect : "none";
ActiveEffectName = $"Active effect: {effectDisplay}"; ActiveEffectName = $"Active effect: {effectDisplay}";
} }

View File

@ -1,9 +1,7 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using Artemis.DAL; using Artemis.DAL;
using Artemis.KeyboardProviders; using Artemis.KeyboardProviders;
@ -19,6 +17,7 @@ namespace Artemis.ViewModels
private readonly KeyboardProvider _activeKeyboard; private readonly KeyboardProvider _activeKeyboard;
private readonly BackgroundWorker _previewWorker; private readonly BackgroundWorker _previewWorker;
private readonly ProfileModel _profile; private readonly ProfileModel _profile;
private readonly bool _wasEnabled;
private LayerModel _layer; private LayerModel _layer;
private LayerPropertiesModel _proposedProperties; private LayerPropertiesModel _proposedProperties;
@ -26,8 +25,11 @@ namespace Artemis.ViewModels
{ {
_activeKeyboard = activeKeyboard; _activeKeyboard = activeKeyboard;
_profile = profile; _profile = profile;
_wasEnabled = layer.Enabled;
Layer = layer; Layer = layer;
Layer.Enabled = false;
DataModelProps = new BindableCollection<GeneralHelpers.PropertyCollection>(); DataModelProps = new BindableCollection<GeneralHelpers.PropertyCollection>();
ProposedProperties = new LayerPropertiesModel(); ProposedProperties = new LayerPropertiesModel();
DataModelProps.AddRange(GeneralHelpers.GenerateTypeMap<T>()); DataModelProps.AddRange(GeneralHelpers.GenerateTypeMap<T>());
@ -39,7 +41,8 @@ namespace Artemis.ViewModels
_previewWorker = new BackgroundWorker {WorkerSupportsCancellation = true}; _previewWorker = new BackgroundWorker {WorkerSupportsCancellation = true};
_previewWorker.DoWork += PreviewWorkerOnDoWork; _previewWorker.DoWork += PreviewWorkerOnDoWork;
_previewWorker.RunWorkerAsync(); _previewWorker.RunWorkerAsync();
PropertyChanged += AnimationUiHandler;
PreSelect(); PreSelect();
} }
@ -101,7 +104,7 @@ namespace Artemis.ViewModels
while (!_previewWorker.CancellationPending) while (!_previewWorker.CancellationPending)
{ {
NotifyOfPropertyChange(() => LayerImage); NotifyOfPropertyChange(() => LayerImage);
Thread.Sleep(1000 / 25); Thread.Sleep(1000/25);
} }
} }
@ -110,6 +113,12 @@ namespace Artemis.ViewModels
GeneralHelpers.CopyProperties(ProposedProperties, Layer.LayerUserProperties); GeneralHelpers.CopyProperties(ProposedProperties, Layer.LayerUserProperties);
} }
private void AnimationUiHandler(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName != "_proposedProperties")
return;
}
public void AddCondition() public void AddCondition()
{ {
var condition = new LayerConditionModel(); var condition = new LayerConditionModel();
@ -133,6 +142,7 @@ namespace Artemis.ViewModels
public override void CanClose(Action<bool> callback) public override void CanClose(Action<bool> callback)
{ {
_previewWorker.CancelAsync(); _previewWorker.CancelAsync();
_layer.Enabled = _wasEnabled;
base.CanClose(callback); base.CanClose(callback);
} }
} }

View File

@ -1,7 +1,16 @@
using System.Dynamic; using System;
using System.Drawing.Imaging;
using System.Dynamic;
using System.IO;
using System.Linq; using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging;
using Artemis.DAL; using Artemis.DAL;
using Artemis.Events;
using Artemis.KeyboardProviders;
using Artemis.Managers; using Artemis.Managers;
using Artemis.Models; using Artemis.Models;
using Artemis.Models.Profiles; using Artemis.Models.Profiles;
@ -9,7 +18,7 @@ using Caliburn.Micro;
namespace Artemis.ViewModels namespace Artemis.ViewModels
{ {
public class ProfileEditorViewModel<T> : Screen public class ProfileEditorViewModel<T> : Screen, IHandle<ActiveKeyboardChanged>
{ {
private readonly GameModel _gameModel; private readonly GameModel _gameModel;
private readonly MainManager _mainManager; private readonly MainManager _mainManager;
@ -23,6 +32,7 @@ namespace Artemis.ViewModels
_gameModel = gameModel; _gameModel = gameModel;
ProfileModels = new BindableCollection<ProfileModel>(); ProfileModels = new BindableCollection<ProfileModel>();
_mainManager.Events.Subscribe(this);
LoadProfiles(); LoadProfiles();
} }
@ -44,12 +54,78 @@ namespace Artemis.ViewModels
{ {
if (Equals(value, _selectedProfileModel)) return; if (Equals(value, _selectedProfileModel)) return;
_selectedProfileModel = value; _selectedProfileModel = value;
NotifyOfPropertyChange(); NotifyOfPropertyChange(() => SelectedProfileModel);
} }
} }
public LayerModel SelectedLayer { get; set; } public LayerModel SelectedLayer { get; set; }
public ImageSource KeyboardPreview
{
get
{
if (_selectedProfileModel == null)
return null;
var keyboardRect = _mainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(4);
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 layer
foreach (var layerModel in _selectedProfileModel.Layers)
{
// if (layerModel.Selected)
drawingContext.DrawRectangle(null, new Pen(new SolidColorBrush(Colors.White), 0.5),new Rect(layerModel.LayerUserProperties.X*4,layerModel.LayerUserProperties.Y*4, layerModel.LayerUserProperties.Width*4,layerModel.LayerUserProperties.Height*4));
layerModel.DrawPreview(drawingContext);
}
// Remove the clip
drawingContext.Pop();
}
var image = new DrawingImage(visual.Drawing);
return image;
}
}
public ImageSource KeyboardImage
{
get
{
using (var memory = new MemoryStream())
{
if (_mainManager.KeyboardManager.ActiveKeyboard?.PreviewSettings == null)
return null;
_mainManager.KeyboardManager.ActiveKeyboard.PreviewSettings.Image.Save(memory, ImageFormat.Png);
memory.Position = 0;
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
return bitmapImage;
}
}
}
public PreviewSettings? PreviewSettings
{
get { return _mainManager.KeyboardManager.ActiveKeyboard?.PreviewSettings; }
}
public void Handle(ActiveKeyboardChanged message)
{
NotifyOfPropertyChange(() => KeyboardImage);
NotifyOfPropertyChange(() => PreviewSettings);
}
private void LoadProfiles() private void LoadProfiles()
{ {
ProfileModels.Clear(); ProfileModels.Clear();
@ -94,7 +170,8 @@ namespace Artemis.ViewModels
public void LayerEditor(LayerModel layer) public void LayerEditor(LayerModel layer)
{ {
IWindowManager manager = new WindowManager(); IWindowManager manager = new WindowManager();
_editorVm = new LayerEditorViewModel<T>(_mainManager.KeyboardManager.ActiveKeyboard, SelectedProfileModel, layer); _editorVm = new LayerEditorViewModel<T>(_mainManager.KeyboardManager.ActiveKeyboard, SelectedProfileModel,
layer);
dynamic settings = new ExpandoObject(); dynamic settings = new ExpandoObject();
settings.Title = "Artemis | Edit " + layer.Name; settings.Title = "Artemis | Edit " + layer.Name;
@ -104,6 +181,7 @@ namespace Artemis.ViewModels
public void SetSelectedLayer(LayerModel layer) public void SetSelectedLayer(LayerModel layer)
{ {
SelectedLayer = layer; SelectedLayer = layer;
NotifyOfPropertyChange(() => KeyboardPreview);
} }
public void AddLayer() public void AddLayer()
@ -113,12 +191,22 @@ namespace Artemis.ViewModels
Name = "Layer " + (_selectedProfileModel.Layers.Count + 1), Name = "Layer " + (_selectedProfileModel.Layers.Count + 1),
LayerType = LayerType.KeyboardRectangle LayerType = LayerType.KeyboardRectangle
}); });
NotifyOfPropertyChange(); NotifyOfPropertyChange(() => SelectedProfileModel);
} }
private ImageSource GenerateKeyboardImage() public void MouseMoveKeyboardPreview(MouseEventArgs e)
{ {
return null; var pos = e.GetPosition((Image) e.OriginalSource);
var realX =
(int)
Math.Round(pos.X/
(_mainManager.KeyboardManager.ActiveKeyboard.PreviewSettings.Width/
_mainManager.KeyboardManager.ActiveKeyboard.Width));
var realY =
(int)
Math.Round(pos.Y/
(_mainManager.KeyboardManager.ActiveKeyboard.PreviewSettings.Height/
_mainManager.KeyboardManager.ActiveKeyboard.Height));
} }
} }
} }

View File

@ -120,17 +120,17 @@
<TextBlock Grid.Row="7" Grid.Column="2" Margin="10" FontSize="13.333" Text="Animation speed:" <TextBlock Grid.Row="7" Grid.Column="2" Margin="10" FontSize="13.333" Text="Animation speed:"
VerticalAlignment="Center" Height="18" /> VerticalAlignment="Center" Height="18" />
<Slider x:Name="RotationSpeed" Grid.Row="7" Grid.Column="3" VerticalAlignment="Center" <Slider x:Name="RotationSpeed" Grid.Row="7" Grid.Column="3" VerticalAlignment="Center"
TickPlacement="BottomRight" TickFrequency="0.1" TickPlacement="None" TickFrequency="0.05"
Value="{Binding Path=ProposedProperties.AnimationSpeed, Mode=TwoWay}" Minimum="0.1" Maximum="3" Value="{Binding Path=ProposedProperties.AnimationSpeed, Mode=TwoWay}" Minimum="0.05" Maximum="3"
SmallChange="1" IsSnapToTickEnabled="True" Margin="10,7" Height="24" /> SmallChange="1" IsSnapToTickEnabled="True" Margin="10,12,10,2" Height="24" />
<!-- Opacity --> <!-- Opacity -->
<TextBlock Grid.Row="8" Grid.Column="0" Margin="10" FontSize="13.333" Text="Opacity:" <TextBlock Grid.Row="8" Grid.Column="0" Margin="10" FontSize="13.333" Text="Opacity:"
VerticalAlignment="Center" Height="18" /> VerticalAlignment="Center" Height="18" />
<Slider x:Name="Sensitivity" Grid.Row="8" Grid.Column="1" VerticalAlignment="Center" <Slider x:Name="Sensitivity" Grid.Row="8" Grid.Column="1" VerticalAlignment="Center"
TickPlacement="BottomRight" TickFrequency="20" TickPlacement="BottomRight" TickFrequency="0.05"
Value="{Binding Path=ProposedProperties.Opacity, Mode=TwoWay}" Minimum="1" Maximum="255" Value="{Binding Path=ProposedProperties.Opacity, Mode=TwoWay}" Minimum="0.0" Maximum="1.0"
SmallChange="1" Margin="10,7" Height="24" /> SmallChange="0.05" Margin="10,7" Height="24" />
<!-- Preview --> <!-- Preview -->
<TextBlock Grid.Row="9" Grid.Column="0" Margin="10,13,10,0" FontSize="13.333" Text="Preview:" <TextBlock Grid.Row="9" Grid.Column="0" Margin="10,13,10,0" FontSize="13.333" Text="Preview:"

View File

@ -31,7 +31,17 @@
Opacity="1" Opacity="1"
BlurRadius="20" /> BlurRadius="20" />
</Border.Effect> </Border.Effect>
<Image Source="D:\Gebruiker folder\Mijn afbeeldingen\Artemis logo\keyboards\k95.png" Margin="50" /> <Grid>
<Image Grid.Column="0" Grid.Row="0" Source="{Binding Path=KeyboardImage}" Margin="50" />
<Image Grid.Column="0" Grid.Row="0" Source="{Binding Path=KeyboardPreview}" Opacity="0.666"
Width="{Binding Path=PreviewSettings.Width}"
Height="{Binding Path=PreviewSettings.Height}"
Margin="{Binding Path=PreviewSettings.Margin}"
Stretch="Fill"
cal:Message.Attach="[Event MouseMove] = [Action MouseMoveKeyboardPreview($eventArgs)]"/>
</Grid>
</Border> </Border>
</Border> </Border>
<!-- Profile management --> <!-- Profile management -->
@ -59,15 +69,17 @@
</TreeView.Resources> </TreeView.Resources>
<TreeView.ItemTemplate> <TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}"> <HierarchicalDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal" Tag="{Binding DataContext, ElementName=ProfileTree}" cal:Message.Attach="SetSelectedLayer($datacontext)"> <StackPanel Orientation="Horizontal" Tag="{Binding DataContext, ElementName=ProfileTree}"
cal:Message.Attach="SetSelectedLayer($datacontext)">
<StackPanel.ContextMenu> <StackPanel.ContextMenu>
<ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"> <ContextMenu
cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Rename" /> <MenuItem Header="Rename" />
<MenuItem Header="Delete" /> <MenuItem Header="Delete" />
<MenuItem Header="Properties" cal:Message.Attach="LayerEditor($datacontext)"/> <MenuItem Header="Properties" cal:Message.Attach="LayerEditor($datacontext)" />
</ContextMenu> </ContextMenu>
</StackPanel.ContextMenu> </StackPanel.ContextMenu>
<CheckBox VerticalAlignment="Center" ToolTip="Layer enabled" /> <CheckBox VerticalAlignment="Center" ToolTip="Layer enabled" IsChecked="{Binding Enabled}" />
<Image Height="18" Width="18" Source="{Binding LayerImage}" /> <Image Height="18" Width="18" Source="{Binding LayerImage}" />
<TextBlock Margin="5,0,0,0" Text="{Binding Name}" VerticalAlignment="Center" /> <TextBlock Margin="5,0,0,0" Text="{Binding Name}" VerticalAlignment="Center" />
</StackPanel> </StackPanel>