diff --git a/Artemis/Artemis.sln b/Artemis/Artemis.sln
index 0e9c57ea1..9e2a09e30 100644
--- a/Artemis/Artemis.sln
+++ b/Artemis/Artemis.sln
@@ -9,6 +9,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Razer2Artemis", "Razer2Arte
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnrealTournament2Artemis", "UnrealTournament2Artemis\UnrealTournament2Artemis.vcxproj", "{3541864F-1662-4BD6-8328-2C87AE61D152}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColorBox", "ColorBox\ColorBox.csproj", "{40085232-ACED-4CBE-945B-90BA8153C151}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
CD_ROM|Any CPU = CD_ROM|Any CPU
@@ -114,6 +116,36 @@ Global
{3541864F-1662-4BD6-8328-2C87AE61D152}.SingleImage|x64.Build.0 = Release|x64
{3541864F-1662-4BD6-8328-2C87AE61D152}.SingleImage|x86.ActiveCfg = Release|Win32
{3541864F-1662-4BD6-8328-2C87AE61D152}.SingleImage|x86.Build.0 = Release|Win32
+ {40085232-ACED-4CBE-945B-90BA8153C151}.CD_ROM|Any CPU.ActiveCfg = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.CD_ROM|Any CPU.Build.0 = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.CD_ROM|x64.ActiveCfg = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.CD_ROM|x64.Build.0 = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.CD_ROM|x86.ActiveCfg = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.CD_ROM|x86.Build.0 = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.Debug|x64.Build.0 = Debug|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.Debug|x86.Build.0 = Debug|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.DVD-5|Any CPU.ActiveCfg = Debug|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.DVD-5|Any CPU.Build.0 = Debug|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.DVD-5|x64.ActiveCfg = Debug|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.DVD-5|x64.Build.0 = Debug|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.DVD-5|x86.ActiveCfg = Debug|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.DVD-5|x86.Build.0 = Debug|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.Release|Any CPU.Build.0 = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.Release|x64.ActiveCfg = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.Release|x64.Build.0 = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.Release|x86.ActiveCfg = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.Release|x86.Build.0 = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.SingleImage|Any CPU.ActiveCfg = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.SingleImage|Any CPU.Build.0 = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.SingleImage|x64.ActiveCfg = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.SingleImage|x64.Build.0 = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.SingleImage|x86.ActiveCfg = Release|Any CPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}.SingleImage|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Artemis/Artemis/App.config b/Artemis/Artemis/App.config
index 5db3e623b..20723b413 100644
--- a/Artemis/Artemis/App.config
+++ b/Artemis/Artemis/App.config
@@ -333,6 +333,10 @@
+
+
+
+
diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj
index e11609de2..9604e7fd8 100644
--- a/Artemis/Artemis/Artemis.csproj
+++ b/Artemis/Artemis/Artemis.csproj
@@ -143,36 +143,32 @@
..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll
True
-
- False
- lib\ColorBox.dll
-
..\packages\Colore.5.0.0\lib\net35\Corale.Colore.dll
True
-
- ..\packages\CUE.NET.1.1.0\lib\net45\CUE.NET.dll
+
+ ..\packages\CUE.NET.1.1.0.2\lib\net45\CUE.NET.dll
True
-
- ..\packages\DeltaCompressionDotNet.1.0.0\lib\net45\DeltaCompressionDotNet.dll
+
+ ..\packages\DeltaCompressionDotNet.1.1.0\lib\net20\DeltaCompressionDotNet.dll
True
-
- ..\packages\DeltaCompressionDotNet.1.0.0\lib\net45\DeltaCompressionDotNet.MsDelta.dll
+
+ ..\packages\DeltaCompressionDotNet.1.1.0\lib\net20\DeltaCompressionDotNet.MsDelta.dll
True
-
- ..\packages\DeltaCompressionDotNet.1.0.0\lib\net45\DeltaCompressionDotNet.PatchApi.dll
+
+ ..\packages\DeltaCompressionDotNet.1.1.0\lib\net20\DeltaCompressionDotNet.PatchApi.dll
True
-
- ..\packages\DynamicExpresso.Core.1.3.1.0\lib\net40\DynamicExpresso.Core.dll
+
+ ..\packages\DynamicExpresso.Core.1.3.3.4\lib\net40\DynamicExpresso.Core.dll
True
-
- ..\packages\gong-wpf-dragdrop.0.1.4.3\lib\net40\GongSolutions.Wpf.DragDrop.dll
+
+ ..\packages\gong-wpf-dragdrop.1.0.0\lib\net46\GongSolutions.Wpf.DragDrop.dll
True
@@ -187,27 +183,27 @@
..\packages\log4net.2.0.5\lib\net45-full\log4net.dll
True
-
- ..\packages\MahApps.Metro.1.2.4.0\lib\net45\MahApps.Metro.dll
+
+ ..\packages\MahApps.Metro.1.3.0\lib\net45\MahApps.Metro.dll
True
False
- ..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.dll
+ ..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll
True
- ..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Mdb.dll
+ ..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Mdb.dll
True
- ..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Pdb.dll
+ ..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Pdb.dll
True
- ..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Rocks.dll
+ ..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Rocks.dll
True
@@ -239,7 +235,7 @@
True
- ..\packages\NLog.4.3.7\lib\net45\NLog.dll
+ ..\packages\NLog.4.3.9\lib\net45\NLog.dll
True
@@ -247,7 +243,7 @@
True
- ..\packages\Process.NET.1.0.1\lib\Process.NET.dll
+ ..\packages\Process.NET.1.0.5\lib\Process.NET.dll
True
@@ -255,7 +251,7 @@
True
- ..\packages\SpotifyAPI-NET.2.11.0\lib\SpotifyAPI.dll
+ ..\packages\SpotifyAPI-NET.2.12.0\lib\SpotifyAPI.dll
True
@@ -273,7 +269,7 @@
- ..\packages\Caliburn.Micro.3.0.1\lib\net45\System.Windows.Interactivity.dll
+ ..\packages\MahApps.Metro.1.3.0\lib\net45\System.Windows.Interactivity.dll
True
@@ -296,30 +292,6 @@
-
- ..\packages\Extended.Wpf.Toolkit.2.9\lib\net40\Xceed.Wpf.AvalonDock.dll
- True
-
-
- ..\packages\Extended.Wpf.Toolkit.2.9\lib\net40\Xceed.Wpf.AvalonDock.Themes.Aero.dll
- True
-
-
- ..\packages\Extended.Wpf.Toolkit.2.9\lib\net40\Xceed.Wpf.AvalonDock.Themes.Metro.dll
- True
-
-
- ..\packages\Extended.Wpf.Toolkit.2.9\lib\net40\Xceed.Wpf.AvalonDock.Themes.VS2010.dll
- True
-
-
- ..\packages\Extended.Wpf.Toolkit.2.9\lib\net40\Xceed.Wpf.DataGrid.dll
- True
-
-
- ..\packages\Extended.Wpf.Toolkit.2.9\lib\net40\Xceed.Wpf.Toolkit.dll
- True
-
@@ -652,6 +624,9 @@
Code
+
+ Designer
+
@@ -659,9 +634,6 @@
Designer
-
- Designer
-
@@ -678,8 +650,11 @@
-
+
+
+ Always
+
PreserveNewest
@@ -865,9 +840,6 @@
-
- PreserveNewest
-
@@ -886,14 +858,19 @@
false
-
+
+
+ {40085232-aced-4cbe-945b-90ba8153c151}
+ ColorBox
+
+
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
+
diff --git a/Artemis/Artemis/Modules/Effects/Bubbles/BubblesViewModel.cs b/Artemis/Artemis/Modules/Effects/Bubbles/BubblesViewModel.cs
index 378b26873..a0d2cb304 100644
--- a/Artemis/Artemis/Modules/Effects/Bubbles/BubblesViewModel.cs
+++ b/Artemis/Artemis/Modules/Effects/Bubbles/BubblesViewModel.cs
@@ -1,13 +1,35 @@
-using Artemis.Managers;
+using System.Windows.Media;
+using Artemis.Managers;
using Artemis.ViewModels.Abstract;
namespace Artemis.Modules.Effects.Bubbles
{
public sealed class BubblesViewModel : EffectViewModel
{
+ private readonly BubblesModel _model;
+ private SolidColorBrush _bubbleColor;
+
public BubblesViewModel(MainManager main, BubblesModel model) : base(main, model)
{
+ _model = model;
DisplayName = "Bubbles";
+ BubbleColor = new SolidColorBrush(model.Settings.BubbleColor);
+ }
+
+ ///
+ /// The bubble color wrapped in a brush to allow color selection using ColorBox
+ ///
+ public Brush BubbleColor
+ {
+ get { return _bubbleColor; }
+ set
+ {
+ if (Equals(value, _bubbleColor)) return;
+ _bubbleColor = (SolidColorBrush) value;
+
+ _model.Settings.BubbleColor = _bubbleColor.Color;
+ NotifyOfPropertyChange(() => BubbleColor);
+ }
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeDataModel.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeDataModel.cs
index 20dd851d4..6e76b2e87 100644
--- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeDataModel.cs
+++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeDataModel.cs
@@ -1,4 +1,5 @@
using Artemis.Models.Interfaces;
+using Newtonsoft.Json;
namespace Artemis.Modules.Games.CounterStrike
{
@@ -47,6 +48,10 @@ namespace Artemis.Modules.Games.CounterStrike
public class State
{
+ [JsonIgnore]
+ public bool made_kill { get; set; }
+ [JsonIgnore]
+ public bool made_headshot { get; set; }
public int health { get; set; }
public int armor { get; set; }
public bool helmet { get; set; }
@@ -58,15 +63,8 @@ namespace Artemis.Modules.Games.CounterStrike
public int round_killhs { get; set; }
}
- public class Weapon0
- {
- public string name { get; set; }
- public string paintkit { get; set; }
- public string type { get; set; }
- public string state { get; set; }
- }
- public class Weapon1
+ public class Weapon
{
public string name { get; set; }
public string paintkit { get; set; }
@@ -77,19 +75,12 @@ namespace Artemis.Modules.Games.CounterStrike
public string state { get; set; }
}
- public class Weapon2
- {
- public string name { get; set; }
- public string paintkit { get; set; }
- public string type { get; set; }
- public string state { get; set; }
- }
-
public class Weapons
{
- public Weapon0 weapon_0 { get; set; }
- public Weapon1 weapon_1 { get; set; }
- public Weapon2 weapon_2 { get; set; }
+ public Weapon active_weapon { get; set; }
+ public Weapon weapon_0 { get; set; }
+ public Weapon weapon_1 { get; set; }
+ public Weapon weapon_2 { get; set; }
}
public class MatchStats
diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs
index 8a7893c5d..6287b3e19 100644
--- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs
+++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs
@@ -12,6 +12,11 @@ namespace Artemis.Modules.Games.CounterStrike
{
public class CounterStrikeModel : GameModel
{
+ private DateTime _lastHeadshot;
+ private int _lastHeadshots;
+ private DateTime _lastKill;
+ private int _lastKills;
+
public CounterStrikeModel(MainManager mainManager)
: base(mainManager, SettingsProvider.Load(), new CounterStrikeDataModel())
{
@@ -42,7 +47,46 @@ namespace Artemis.Modules.Games.CounterStrike
public override void Update()
{
- // TODO: Set up active weapon in the datamodel
+ if (DataModel == null)
+ return;
+
+ var dm = (CounterStrikeDataModel) DataModel;
+ if (dm.player != null)
+ {
+ // Detect active weapon
+ if (dm.player.weapons.weapon_0?.state == "active")
+ dm.player.weapons.active_weapon = dm.player.weapons.weapon_0;
+ else if (dm.player.weapons.weapon_1?.state == "active")
+ dm.player.weapons.active_weapon = dm.player.weapons.weapon_1;
+ else if (dm.player.weapons.weapon_2?.state == "active")
+ dm.player.weapons.active_weapon = dm.player.weapons.weapon_2;
+
+ // Detect a kill
+ if (dm.player.state.round_kills > _lastKills)
+ {
+ dm.player.state.made_kill = true;
+ _lastKill = DateTime.Now;
+ }
+ else if (dm.player.state.made_kill && (DateTime.Now - _lastKill > TimeSpan.FromMilliseconds(500)))
+ dm.player.state.made_kill = false;
+ _lastKills = dm.player.state.round_kills;
+
+ // Detect a headshot
+ if (dm.player.state.round_killhs > _lastHeadshots)
+ {
+ dm.player.state.made_headshot = true;
+ _lastHeadshot = DateTime.Now;
+ }
+ else if (dm.player.state.made_headshot && (DateTime.Now - _lastHeadshot > TimeSpan.FromMilliseconds(500)))
+ dm.player.state.made_headshot = false;
+ _lastHeadshots = dm.player.state.round_killhs;
+
+ // Detect a round win
+
+ // Detect a round loss
+ }
+
+ DataModel = dm;
}
public void HandleGameData(object sender, GameDataReceivedEventArgs e)
@@ -56,7 +100,9 @@ namespace Artemis.Modules.Games.CounterStrike
// Parse the JSON
try
{
- DataModel = JsonConvert.DeserializeObject(jsonString);
+ if (DataModel == null)
+ DataModel = new CounterStrikeDataModel();
+ JsonConvert.PopulateObject(jsonString, DataModel);
}
catch (Exception ex)
{
diff --git a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs
index 32647e4bb..8da2d0d0d 100644
--- a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs
+++ b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
using Artemis.DAL;
using Artemis.Managers;
@@ -7,6 +8,7 @@ using Artemis.Profiles.Layers.Models;
using Artemis.Settings;
using Artemis.Utilities;
using Artemis.Utilities.Memory;
+using Newtonsoft.Json;
namespace Artemis.Modules.Games.RocketLeague
{
@@ -25,20 +27,20 @@ namespace Artemis.Modules.Games.RocketLeague
Initialized = false;
// Generate a new offset when the game is updated
-// var offset = new GamePointersCollection
-// {
-// Game = "RocketLeague",
-// GameVersion = "1.21",
-// GameAddresses = new List
-// {
-// new GamePointer
-// {
-// Description = "Boost",
-// BasePointer = new IntPtr(0x016AD528),
-// Offsets = new[] {0x304, 0x8, 0x50, 0x720, 0x224}
-// }
-// }
-// };
+ //var offset = new GamePointersCollection
+ //{
+ // Game = "RocketLeague",
+ // GameVersion = "1.24",
+ // GameAddresses = new List
+ // {
+ // new GamePointer
+ // {
+ // Description = "Boost",
+ // BasePointer = new IntPtr(0x016BBFB4),
+ // Offsets = new[] { 0xc4, 0x210, 0x320, 0x734, 0x224}
+ // }
+ // }
+ //};
//var res = JsonConvert.SerializeObject(offset, Formatting.Indented);
}
diff --git a/Artemis/Artemis/Modules/Games/WoW/WoWModel.cs b/Artemis/Artemis/Modules/Games/WoW/WoWModel.cs
index 546d47426..ad4403d55 100644
--- a/Artemis/Artemis/Modules/Games/WoW/WoWModel.cs
+++ b/Artemis/Artemis/Modules/Games/WoW/WoWModel.cs
@@ -8,7 +8,9 @@ using Artemis.Modules.Games.WoW.Data;
using Artemis.Profiles.Layers.Models;
using Artemis.Settings;
using Artemis.Utilities.Memory;
+using Newtonsoft.Json;
using Process.NET;
+using Process.NET.Memory;
namespace Artemis.Modules.Games.WoW
{
@@ -31,25 +33,36 @@ namespace Artemis.Modules.Games.WoW
Initialized = false;
- // TODO: Retrieve from GitHub
- _pointer = new GamePointersCollection
- {
- Game = "WorldOfWarcraft",
- GameVersion = "7.0.3.22522",
- GameAddresses = new List
- {
- new GamePointer
- {
- Description = "ObjectManager",
- BasePointer = new IntPtr(0x1575E10)
- },
- new GamePointer
- {
- Description = "LocalPlayer",
- BasePointer = new IntPtr(0x169BCB0)
- }
- }
- };
+ _pointer = SettingsProvider.Load().WorldOfWarcraft;
+ //_pointer = new GamePointersCollection
+ //{
+ // Game = "WorldOfWarcraft",
+ // GameVersion = "7.0.3.22810",
+ // GameAddresses = new List
+ // {
+ // new GamePointer
+ // {
+ // Description = "ObjectManager",
+ // BasePointer = new IntPtr(0x1578070)
+ // },
+ // new GamePointer
+ // {
+ // Description = "LocalPlayer",
+ // BasePointer = new IntPtr(0x169DF10)
+ // },
+ // new GamePointer
+ // {
+ // Description = "NameCache",
+ // BasePointer = new IntPtr(0x151DCE8)
+ // },
+ // new GamePointer
+ // {
+ // Description = "TargetGuid",
+ // BasePointer = new IntPtr(0x179C940)
+ // }
+ // }
+ //};
+ //var res = JsonConvert.SerializeObject(_pointer, Formatting.Indented);
}
public int Scale { get; set; }
@@ -68,8 +81,7 @@ namespace Artemis.Modules.Games.WoW
if (tempProcess == null)
return;
- _process = new ProcessSharp(tempProcess);
- _process.Memory = new ExternalProcessMemory(_process.Handle);
+ _process = new ProcessSharp(tempProcess, MemoryType.Remote);
Initialized = true;
}
@@ -83,10 +95,11 @@ namespace Artemis.Modules.Games.WoW
var objectManager = new WoWObjectManager(_process,
_pointer.GameAddresses.First(a => a.Description == "ObjectManager").BasePointer);
- var nameCache = new WoWNameCache(_process, new IntPtr(0x151BA88));
+ var nameCache = new WoWNameCache(_process,
+ _pointer.GameAddresses.First(a => a.Description == "NameCache").BasePointer);
var player = new WoWPlayer(_process,
- _pointer.GameAddresses.First(a => a.Description == "LocalPlayer").BasePointer, new IntPtr(0x179A6E0),
- true);
+ _pointer.GameAddresses.First(a => a.Description == "LocalPlayer").BasePointer,
+ _pointer.GameAddresses.First(a => a.Description == "TargetGuid").BasePointer, true);
dataModel.Player = player;
if (dataModel.Player != null && dataModel.Player.Guid != Guid.Empty)
diff --git a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs
index d19c336c9..e5d2de8d7 100644
--- a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs
+++ b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs
@@ -2,6 +2,7 @@
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
+using Artemis.DAL;
using Artemis.Managers;
using Artemis.Models;
using Artemis.Profiles.Layers.Models;
@@ -12,13 +13,15 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
{
public class VolumeDisplayModel : OverlayModel
{
- public VolumeDisplayModel(MainManager mainManager) : base(mainManager, new VolumeDisplaySettings())
+ public VolumeDisplayModel(MainManager mainManager)
+ : base(mainManager, SettingsProvider.Load())
{
Name = "VolumeDisplay";
-
- VolumeDisplay = new VolumeBar(MainManager.DeviceManager, (VolumeDisplaySettings) Settings);
+ Settings = (VolumeDisplaySettings) base.Settings;
+ VolumeDisplay = new VolumeBar(MainManager.DeviceManager, Settings);
}
+ public new VolumeDisplaySettings Settings { get; set; }
public VolumeBar VolumeDisplay { get; set; }
public override void Dispose()
@@ -67,7 +70,7 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
private void KeyPressTask(KeyEventArgs e)
{
- if (e.KeyCode != Keys.VolumeUp && e.KeyCode != Keys.VolumeDown)
+ if ((e.KeyCode != Keys.VolumeUp) && (e.KeyCode != Keys.VolumeDown))
return;
VolumeDisplay.Ttl = 1000;
@@ -76,7 +79,7 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
public override void RenderOverlay(RenderFrame frame, bool keyboardOnly)
{
- if (MainManager.DeviceManager.ActiveKeyboard == null || VolumeDisplay == null || VolumeDisplay.Ttl < 1)
+ if ((MainManager.DeviceManager.ActiveKeyboard == null) || (VolumeDisplay == null) || (VolumeDisplay.Ttl < 1))
return;
using (var g = Graphics.FromImage(frame.KeyboardBitmap))
diff --git a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplaySettings.cs b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplaySettings.cs
index a67eb0d12..2a5de5b80 100644
--- a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplaySettings.cs
+++ b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplaySettings.cs
@@ -1,5 +1,7 @@
using System.Windows.Media;
+using Artemis.DAL;
using Artemis.Settings;
+using Newtonsoft.Json;
namespace Artemis.Modules.Overlays.VolumeDisplay
{
@@ -7,5 +9,19 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
{
public Color MainColor { get; set; }
public Color SecondaryColor { get; set; }
+
+ public new void Reset(bool save = false)
+ {
+ JsonConvert.PopulateObject("{}", this, new JsonSerializerSettings
+ {
+ ObjectCreationHandling = ObjectCreationHandling.Reuse
+ });
+
+ MainColor = Colors.Red;
+ SecondaryColor = Colors.GreenYellow;
+
+ if (save)
+ SettingsProvider.Save(this);
+ }
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayView.xaml b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayView.xaml
index 51226f2cc..3cdcdd1f9 100644
--- a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayView.xaml
+++ b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayView.xaml
@@ -5,6 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:cal="http://www.caliburnproject.org"
+ xmlns:ncore="http://schemas.ncore.com/wpf/xaml/colorbox"
mc:Ignorable="d"
d:DesignHeight="476.986" d:DesignWidth="538.772">
@@ -42,21 +43,19 @@
Margin="0,8">
Main volume display color
-
-
+
+
Secondary volume display color
-
-
+
+
diff --git a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayViewModel.cs b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayViewModel.cs
index 5004e0c87..1296521ed 100644
--- a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayViewModel.cs
+++ b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayViewModel.cs
@@ -1,13 +1,48 @@
-using Artemis.Managers;
+using System.Windows.Media;
+using Artemis.Managers;
using Artemis.ViewModels.Abstract;
namespace Artemis.Modules.Overlays.VolumeDisplay
{
public sealed class VolumeDisplayViewModel : OverlayViewModel
{
+ private readonly VolumeDisplayModel _model;
+ private SolidColorBrush _mainColor;
+ private SolidColorBrush _secondaryColor;
+
public VolumeDisplayViewModel(MainManager mainManager, VolumeDisplayModel model) : base(mainManager, model)
{
+ _model = model;
DisplayName = "Volume Display";
+
+ MainColor = new SolidColorBrush(model.Settings.MainColor);
+ SecondaryColor = new SolidColorBrush(model.Settings.SecondaryColor);
+ }
+
+ public Brush MainColor
+ {
+ get { return _mainColor; }
+ set
+ {
+ if (Equals(value, _mainColor)) return;
+ _mainColor = (SolidColorBrush) value;
+
+ _model.Settings.MainColor = _mainColor.Color;
+ NotifyOfPropertyChange(() => MainColor);
+ }
+ }
+
+ public Brush SecondaryColor
+ {
+ get { return _secondaryColor; }
+ set
+ {
+ if (Equals(value, _secondaryColor)) return;
+ _secondaryColor = (SolidColorBrush) value;
+
+ _model.Settings.SecondaryColor = _secondaryColor.Color;
+ NotifyOfPropertyChange(() => SecondaryColor);
+ }
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/NLog.xsd b/Artemis/Artemis/NLog.xsd
index c489255c0..faa9681c6 100644
--- a/Artemis/Artemis/NLog.xsd
+++ b/Artemis/Artemis/NLog.xsd
@@ -368,6 +368,7 @@
+
@@ -401,6 +402,11 @@
Instance of that is used to format log messages.
+
+
+ End of line value if a newline is appended at the end of log message .
+
+
Maximum message size in bytes.
@@ -1021,8 +1027,11 @@
-
+
+
+
+
@@ -1032,15 +1041,15 @@
-
+
+
-
@@ -1102,9 +1111,14 @@
Maximum number of archive files that should be kept.
-
+
- Gets or set a value indicating whether a managed file stream is forced, instead of used the native implementation.
+ Is the an absolute or relative path?
+
+
+
+
+ Is the an absolute or relative path?
@@ -1112,6 +1126,16 @@
Cleanup invalid values in a filename, e.g. slashes in a filename. If set to true, this can impact the performance of massive writes. If set to false, nothing gets written when the filename is wrong.
+
+
+ Gets or set a value indicating whether a managed file stream is forced, instead of used the native implementation.
+
+
+
+
+ Indicates whether the footer should be written only when the file is archived.
+
+
Name of the file to write to.
@@ -1157,9 +1181,9 @@
Indicates whether concurrent writes to the log file by multiple processes on the same host.
-
+
- Delay in milliseconds to wait before attempting to write to the file again.
+ Indicates whether to keep log file open instead of opening and closing it on each logging event.
@@ -1192,16 +1216,16 @@
Indicates whether to automatically flush the file buffers after each log message.
+
+
+ Delay in milliseconds to wait before attempting to write to the file again.
+
+
Number of times the write is appended on the file before NLog discards the log message.
-
-
- Indicates whether to keep log file open instead of opening and closing it on each logging event.
-
-
@@ -1223,6 +1247,13 @@
+
+
+
+
+
+
+
@@ -1703,6 +1734,7 @@
+
@@ -1728,6 +1760,11 @@
Encoding to be used.
+
+
+ End of line value if a newline is appended at the end of log message .
+
+
Maximum message size in bytes.
@@ -1783,6 +1820,7 @@
+
@@ -1816,6 +1854,11 @@
Instance of that is used to format log messages.
+
+
+ End of line value if a newline is appended at the end of log message .
+
+
Maximum message size in bytes.
diff --git a/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs b/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs
index 5a7adc7d0..0f2ae4d53 100644
--- a/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs
+++ b/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs
@@ -9,13 +9,16 @@ namespace Artemis.Profiles.Layers.Conditions
{
public bool ConditionsMet(LayerModel layer, IDataModel dataModel)
{
- var conditionsMet = layer.Properties.Conditions.All(cm => cm.ConditionMet(dataModel));
- layer.EventProperties.Update(layer, conditionsMet);
+ lock (layer.Properties.Conditions)
+ {
+ var conditionsMet = layer.Properties.Conditions.All(cm => cm.ConditionMet(dataModel));
+ layer.EventProperties.Update(layer, conditionsMet);
- if (conditionsMet && layer.EventProperties.MustTrigger)
- layer.EventProperties.TriggerEvent(layer);
+ if (conditionsMet && layer.EventProperties.CanTrigger)
+ layer.EventProperties.TriggerEvent(layer);
- return conditionsMet && layer.EventProperties.MustDraw;
+ return layer.EventProperties.MustDraw;
+ }
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs
index 8acd950da..b13f3487a 100644
--- a/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs
+++ b/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs
@@ -1,4 +1,6 @@
using System;
+using System.Threading;
+using System.Threading.Tasks;
using Newtonsoft.Json;
namespace Artemis.Profiles.Layers.Models
@@ -10,10 +12,10 @@ namespace Artemis.Profiles.Layers.Models
public TimeSpan TriggerDelay { get; set; }
[JsonIgnore]
- public bool MustTrigger { get; set; }
+ public bool CanTrigger { get; set; }
[JsonIgnore]
- public DateTime AnimationStart { get; set; }
+ public DateTime EventTriggerTime { get; set; }
[JsonIgnore]
public bool MustDraw { get; set; }
@@ -21,23 +23,70 @@ namespace Artemis.Profiles.Layers.Models
///
/// Resets the event's properties and triggers it
///
- public abstract void TriggerEvent(LayerModel layer);
+ public virtual void TriggerEvent(LayerModel layer)
+ {
+ if (!CanTrigger)
+ return;
+
+ if (TriggerDelay > TimeSpan.Zero)
+ {
+ if (EventCanTriggerTime == DateTime.MinValue)
+ EventCanTriggerTime = DateTime.Now;
+
+ if (DateTime.Now - EventCanTriggerTime < TriggerDelay)
+ return;
+
+ EventCanTriggerTime = DateTime.MinValue;
+ }
+
+ CanTrigger = false;
+ MustDraw = true;
+ EventTriggerTime = DateTime.Now;
+ layer.Properties.AnimationProgress = 0.0;
+ }
+
+ public DateTime EventCanTriggerTime { get; set; }
+
///
/// Gets whether the event should stop
///
///
///
- public abstract bool MustStop(LayerModel layer);
+ public virtual bool MustStop(LayerModel layer)
+ {
+ if (ExpirationType == ExpirationType.Time)
+ {
+ if (EventTriggerTime == DateTime.MinValue)
+ return false;
+ return DateTime.Now - EventTriggerTime > Length;
+ }
+ if (ExpirationType == ExpirationType.Animation)
+ return (layer.LayerAnimation == null) || layer.LayerAnimation.MustExpire(layer);
+
+ return true;
+ }
// Called every frame, if parent conditions met.
public void Update(LayerModel layerModel, bool conditionsMet)
{
- if (MustStop(layerModel))
+ if (EventCanTriggerTime > DateTime.MinValue && (DateTime.Now - EventCanTriggerTime > TriggerDelay))
+ {
+ CanTrigger = true;
+ TriggerEvent(layerModel);
+ return;
+ }
+
+ if (MustDraw && MustStop(layerModel))
MustDraw = false;
if (!conditionsMet)
- MustTrigger = true;
+ CanTrigger = true;
+ }
+
+ protected bool DelayExpired()
+ {
+ return EventCanTriggerTime > DateTime.MinValue && DateTime.Now - EventCanTriggerTime >= TriggerDelay;
}
}
diff --git a/Artemis/Artemis/Profiles/Layers/Models/KeyboardEventPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Models/KeyboardEventPropertiesModel.cs
index ce0cb8bd2..76c9cfb08 100644
--- a/Artemis/Artemis/Profiles/Layers/Models/KeyboardEventPropertiesModel.cs
+++ b/Artemis/Artemis/Profiles/Layers/Models/KeyboardEventPropertiesModel.cs
@@ -1,5 +1,4 @@
using System;
-using Artemis.Profiles.Layers.Types.Keyboard;
using Artemis.Profiles.Layers.Types.KeyboardGif;
namespace Artemis.Profiles.Layers.Models
@@ -8,40 +7,23 @@ namespace Artemis.Profiles.Layers.Models
{
public override void TriggerEvent(LayerModel layer)
{
- var keyboardProperties = layer.Properties as KeyboardPropertiesModel;
- if (keyboardProperties == null)
- throw new ArgumentException("Layer's properties cannot be null " +
- "and must be of type KeyboardPropertiesModel");
- if (!MustTrigger)
- return;
+ if (CanTrigger && DelayExpired())
+ {
+ if (layer.GifImage != null)
+ layer.GifImage.CurrentFrame = 0;
+ }
- MustTrigger = false;
- MustDraw = true;
- keyboardProperties.AnimationProgress = 0.0;
- if (layer.GifImage != null)
- layer.GifImage.CurrentFrame = 0;
+ base.TriggerEvent(layer);
}
public override bool MustStop(LayerModel layer)
{
- var keyboardProperties = layer.Properties as KeyboardPropertiesModel;
- if (keyboardProperties == null)
- throw new ArgumentException("Layer's properties cannot be null " +
- "and must be of type KeyboardPropertiesModel");
+ if (ExpirationType != ExpirationType.Animation)
+ return base.MustStop(layer);
- switch (ExpirationType)
- {
- case ExpirationType.Time:
- if (AnimationStart == DateTime.MinValue)
- return false;
- return DateTime.Now - Length > AnimationStart;
- case ExpirationType.Animation:
- if (layer.LayerType is KeyboardGifType)
- return layer.GifImage?.CurrentFrame >= layer.GifImage?.FrameCount - 1;
- return layer.LayerAnimation == null || layer.LayerAnimation.MustExpire(layer);
- default:
- return true;
- }
+ if (layer.LayerType is KeyboardGifType)
+ return layer.GifImage?.CurrentFrame >= layer.GifImage?.FrameCount - 1;
+ return (layer.LayerAnimation == null) || layer.LayerAnimation.MustExpire(layer);
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs b/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs
index 68d968013..e3bd0b529 100644
--- a/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs
+++ b/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs
@@ -242,5 +242,13 @@ namespace Artemis.Profiles.Layers.Models
}
#endregion
+
+ public void SetupCondition()
+ {
+ if (IsEvent && !(LayerCondition is EventCondition))
+ LayerCondition = new EventCondition();
+ else if (!IsEvent && !(LayerCondition is DataModelCondition))
+ LayerCondition = new DataModelCondition();
+ }
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericPropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericPropertiesView.xaml
index 9747459ea..c31f063c2 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericPropertiesView.xaml
+++ b/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericPropertiesView.xaml
@@ -1,9 +1,10 @@
-
@@ -23,54 +24,46 @@
+ VerticalAlignment="Center"
+ Height="18" />
+ Height="22">
-
+
+ VerticalAlignment="Center" Height="18" />
+ TickPlacement="None" TickFrequency="0.05"
+ Value="{Binding LayerModel.Properties.AnimationSpeed, Mode=TwoWay}" Minimum="0.05" Maximum="3"
+ SmallChange="0" IsSnapToTickEnabled="True" Margin="10,12,10,2" Height="24" />
+ VerticalAlignment="Top" Height="18" Width="130" />
-
+ BorderThickness="1" SnapsToDevicePixels="True" ToolTip="Click to edit">
+
+ Content="Dynamic" Width="97" VerticalAlignment="Bottom" />
-
-
-
-
-
-
-
-
+ Foreground="{DynamicResource HighlightBrush}"
+ VerticalAlignment="Top" Height="Auto" TextWrapping="Wrap">
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericPropertiesViewModel.cs b/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericPropertiesViewModel.cs
index 80c7aa4ec..ae0d4a389 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericPropertiesViewModel.cs
+++ b/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericPropertiesViewModel.cs
@@ -1,13 +1,16 @@
-using System.Linq;
+using System.Collections.Generic;
+using System.Linq;
using Artemis.Profiles.Layers.Abstract;
using Artemis.Profiles.Layers.Interfaces;
using Artemis.ViewModels.Profiles;
using Caliburn.Micro;
+using ColorBox;
namespace Artemis.Profiles.Layers.Types.Generic
{
public class GenericPropertiesViewModel : LayerPropertiesViewModel
{
+ private IEnumerable _availableBrushTypes;
private ILayerAnimation _selectedLayerAnimation;
public GenericPropertiesViewModel(LayerEditorViewModel editorVm) : base(editorVm)
diff --git a/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesView.xaml
index 9e582617b..85ee67746 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesView.xaml
+++ b/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesView.xaml
@@ -60,7 +60,7 @@
VerticalAlignment="Top" Height="18" Width="130" />
-
+
diff --git a/Artemis/Artemis/Properties/AssemblyInfo.cs b/Artemis/Artemis/Properties/AssemblyInfo.cs
index 8bdcdc28e..7be9c3d37 100644
--- a/Artemis/Artemis/Properties/AssemblyInfo.cs
+++ b/Artemis/Artemis/Properties/AssemblyInfo.cs
@@ -52,5 +52,5 @@ using System.Windows;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.3.3.0")]
-[assembly: AssemblyFileVersion("1.3.3.0")]
\ No newline at end of file
+[assembly: AssemblyVersion("1.4.0.0")]
+[assembly: AssemblyFileVersion("1.4.0.0")]
\ No newline at end of file
diff --git a/Artemis/Artemis/Resources/Keyboards/default-profiles.zip b/Artemis/Artemis/Resources/Keyboards/default-profiles.zip
index 6dc6e025f..ac8cd394b 100644
Binary files a/Artemis/Artemis/Resources/Keyboards/default-profiles.zip and b/Artemis/Artemis/Resources/Keyboards/default-profiles.zip differ
diff --git a/Artemis/Artemis/Settings/GeneralSettings.cs b/Artemis/Artemis/Settings/GeneralSettings.cs
index 2717b7be6..189bb025f 100644
--- a/Artemis/Artemis/Settings/GeneralSettings.cs
+++ b/Artemis/Artemis/Settings/GeneralSettings.cs
@@ -27,6 +27,10 @@ namespace Artemis.Settings
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public string LastKeyboard { get; set; }
+ [DefaultValue("Qwerty")]
+ [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
+ public string Layout { get; set; }
+
[DefaultValue(true)]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public bool EnablePointersUpdate { get; set; }
diff --git a/Artemis/Artemis/Settings/OffsetSettings.cs b/Artemis/Artemis/Settings/OffsetSettings.cs
index 68ec07922..14a63bee0 100644
--- a/Artemis/Artemis/Settings/OffsetSettings.cs
+++ b/Artemis/Artemis/Settings/OffsetSettings.cs
@@ -7,6 +7,7 @@ namespace Artemis.Settings
public class OffsetSettings : IArtemisSettings
{
public GamePointersCollection RocketLeague { get; set; }
+ public GamePointersCollection WorldOfWarcraft { get; set; }
public void Save()
{
diff --git a/Artemis/Artemis/Styles/ColorBox.xaml b/Artemis/Artemis/Styles/ColorBox.xaml
index bbd797280..6c8f49fea 100644
--- a/Artemis/Artemis/Styles/ColorBox.xaml
+++ b/Artemis/Artemis/Styles/ColorBox.xaml
@@ -207,7 +207,7 @@
+ ItemsSource="{Binding AvailableBrushTypes, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center">
@@ -219,7 +219,7 @@
+ Padding="0,3" Margin="3,0">
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -649,14 +758,6 @@
Value="{Binding EndY, RelativeSource={RelativeSource TemplatedParent}}" />
-
-
-
-
@@ -676,17 +777,15 @@
-
+
-
-
-
+
@@ -707,14 +806,6 @@
-
-
-
-
diff --git a/Artemis/Artemis/Utilities/Logging.cs b/Artemis/Artemis/Utilities/Logging.cs
index 50b2a84b1..8d6040a3b 100644
--- a/Artemis/Artemis/Utilities/Logging.cs
+++ b/Artemis/Artemis/Utilities/Logging.cs
@@ -27,9 +27,10 @@ namespace Artemis.Utilities
debuggerTarget.Layout = @"${logger:shortName=True} - ${uppercase:${level}}: ${message}";
fileTarget.FileName = "${specialfolder:folder=MyDocuments}/Artemis/logs/${shortdate}.txt";
fileTarget.Layout = "${longdate}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}";
- fileTarget.ArchiveEvery = FileArchivePeriod.Day;
+ fileTarget.EnableFileDelete = true;
fileTarget.MaxArchiveFiles = 7;
-
+ fileTarget.ArchiveEvery = FileArchivePeriod.Minute;
+
// Step 4. Define rules
var rule1 = new LoggingRule("*", logLevel, debuggerTarget);
config.LoggingRules.Add(rule1);
diff --git a/Artemis/Artemis/Utilities/Updater.cs b/Artemis/Artemis/Utilities/Updater.cs
index 43cb0e242..fe9b5f51d 100644
--- a/Artemis/Artemis/Utilities/Updater.cs
+++ b/Artemis/Artemis/Utilities/Updater.cs
@@ -147,6 +147,8 @@ namespace Artemis.Utilities
// Assign each pointer to the settings file
if (pointers.FirstOrDefault(p => p.Game == "RocketLeague") != null)
offsetSettings.RocketLeague = pointers.FirstOrDefault(p => p.Game == "RocketLeague");
+ if (pointers.FirstOrDefault(p => p.Game == "WorldOfWarcraft") != null)
+ offsetSettings.WorldOfWarcraft = pointers.FirstOrDefault(p => p.Game == "WorldOfWarcraft");
offsetSettings.Save();
}
diff --git a/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs b/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs
index 941165ded..61d9ba4d7 100644
--- a/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs
@@ -86,6 +86,12 @@ namespace Artemis.ViewModels.Flyouts
"Corsair Dark"
};
+ public BindableCollection Layouts => new BindableCollection
+ {
+ "Qwerty",
+ "Azerty"
+ };
+
public string VersionText => "Artemis " + Assembly.GetExecutingAssembly().GetName().Version;
public BindableCollection LogLevels { get; set; }
@@ -101,6 +107,17 @@ namespace Artemis.ViewModels.Flyouts
}
}
+ public string SelectedLayout
+ {
+ get { return GeneralSettings.Layout; }
+ set
+ {
+ if (value == GeneralSettings.Layout) return;
+ GeneralSettings.Layout = value;
+ NotifyOfPropertyChange(() => SelectedLayout);
+ }
+ }
+
public string SelectedLogLevel
{
get { return GeneralSettings.LogLevel; }
diff --git a/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs
index 839e84abc..aac0629c6 100644
--- a/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs
@@ -5,6 +5,7 @@ using System.IO;
using System.Linq;
using Artemis.Models.Interfaces;
using Artemis.Profiles.Layers.Abstract;
+using Artemis.Profiles.Layers.Conditions;
using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Models;
using Artemis.Profiles.Layers.Types.Keyboard;
@@ -175,7 +176,9 @@ namespace Artemis.ViewModels.Profiles
// TODO: EventPropVM must have layer too
if (EventPropertiesViewModel != null)
Layer.EventProperties = EventPropertiesViewModel.GetAppliedProperties();
-
+
+ Layer.SetupCondition();
+
// Don't bother checking for a GIF path unless the type is GIF
if (!(Layer.LayerType is KeyboardGifType))
return;
@@ -215,6 +218,11 @@ namespace Artemis.ViewModels.Profiles
// that would upset the child layers' relations (sounds like Dr. Phil amirite?)
var currentObj = Clone(Layer);
currentObj.Children.Clear();
+
+ // Apply the IsEvent boolean
+ currentObj.SetupCondition();
+ ProposedLayer.SetupCondition();
+
var current = JsonConvert.SerializeObject(currentObj, Formatting.Indented);
var proposed = JsonConvert.SerializeObject(ProposedLayer, Formatting.Indented);
diff --git a/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs
index cbce56fdc..0fd5e12ff 100644
--- a/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs
@@ -546,8 +546,13 @@ namespace Artemis.ViewModels.Profiles
return;
var newProfile = GeneralHelpers.Clone(SelectedProfile);
- newProfile.Name =
- await DialogService.ShowInputDialog("Duplicate profile", "Please enter a unique profile name");
+ newProfile.Name = await DialogService
+ .ShowInputDialog("Duplicate profile", "Please enter a unique profile name");
+
+ // Null when the user cancelled
+ if (string.IsNullOrEmpty(newProfile.Name))
+ return;
+
// Verify the name
while (ProfileProvider.GetAll().Contains(newProfile))
{
@@ -555,7 +560,7 @@ namespace Artemis.ViewModels.Profiles
await DialogService.ShowInputDialog("Name already in use", "Please enter a unique profile name");
// Null when the user cancelled
- if (string.IsNullOrEmpty(SelectedProfile.Name))
+ if (string.IsNullOrEmpty(newProfile.Name))
return;
}
diff --git a/Artemis/Artemis/Views/Flyouts/FlyoutSettingsView.xaml b/Artemis/Artemis/Views/Flyouts/FlyoutSettingsView.xaml
index 34b66d7a6..b61361692 100644
--- a/Artemis/Artemis/Views/Flyouts/FlyoutSettingsView.xaml
+++ b/Artemis/Artemis/Views/Flyouts/FlyoutSettingsView.xaml
@@ -7,7 +7,7 @@
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="300"
- Width="300">
+ Width="270">
@@ -31,23 +31,27 @@
-
+
-
+ Content="Auto startup:" />
+
+
-
+
-
+
-
+
+
+
+
+
-
-
-
-
-
+ Content="Auto-update:" />
+
+
-
diff --git a/Artemis/Artemis/Views/ShellView.xaml b/Artemis/Artemis/Views/ShellView.xaml
index 4370449be..2e86ff657 100644
--- a/Artemis/Artemis/Views/ShellView.xaml
+++ b/Artemis/Artemis/Views/ShellView.xaml
@@ -17,7 +17,31 @@
+ Geometry="M1518 3378 c-48 -63 -61 -101 -66 -184 -4 -70 -1 -91 27
+ -170 l31 -89 -27 -20 c-32 -24 -849 -601 -981 -693 l-93 -64 -87 40
+ c-48 22 -91 37 -95 32 -5 -4 9 -41 29 -83 l37 -75 -28 -24 c-23 -20
+ -29 -35 -33 -81 l-4 -56 -82 -19 c-109 -25 -109 -41 4 -91 l85 -38 7
+ -64 c15 -137 90 -1279 85 -1293 -3 -7 -35 -24 -70 -35 -159 -53 -257
+ -168 -257 -302 0 -35 2 -38 47 -53 54 -18 185 -21 232 -5 29 10 31
+ 14 31 58 0 26 6 56 14 66 13 18 15 18 46 -8 44 -37 78 -35 119 7 l34
+ 35 -17 41 c-9 23 -12 39 -6 35 6 -4 43 -1 83 6 39 6 219 14 398 18
+ l327 6 113 57 c158 78 256 166 317 282 24 46 27 62 27 152 0 98 -1
+ 103 -41 184 l-42 83 44 69 c24 37 51 68 59 68 9 0 44 -14 78 -32 l62
+ -31 -93 -44 c-58 -26 -92 -48 -90 -55 9 -27 353 -68 570 -68 108 0
+ 108 0 108 24 0 34 -105 171 -220 286 -122 122 -238 216 -250 204 -6
+ -6 -1 -42 16 -98 14 -49 23 -91 19 -94 -3 -3 -36 9 -73 27 l-69 33 24
+ 71 c13 39 23 76 23 82 0 6 28 17 63 24 279 58 399 300 314 632 -32
+ 121 -49 155 -134 255 -37 45 -106 126 -152 180 -73 87 -241 326 -241
+ 343 0 3 15 13 32 21 21 10 35 25 40 45 15 60 -16 103 -81 108 -43 3
+ -39 22 14 74 l45 43 -25 50 c-35 69 -77 114 -130 139 -63 30 -88 27
+ -117 -11z m215 -835 c188 -279 250 -417 250 -548 0 -133 -74 -214 -243
+ -265 l-55 -16 -37 -138 c-21 -76 -39 -140 -40 -141 -6 -5 -814 377 -823
+ 390 -6 7 -19 46 -29 86 -10 41 -25 81 -33 91 -8 9 -57 35 -109 59 -52
+ 23 -93 46 -92 51 2 4 233 169 513 366 l510 358 26 -46 c15 -25 88 -136
+ 162 -247z m-1108 -898 c61 21 88 26 107 19 14 -5 204 -92 421 -194 l395
+ -185 -27 -35 c-15 -19 -53 -72 -84 -117 l-57 -81 30 -90 c39 -117 40
+ -179 2 -253 -45 -90 -147 -145 -347 -189 -71 -15 -435 -59 -600 -73 l
+ -29 -2 -37 540 c-20 297 -40 581 -43 632 l-7 92 98 -46 97 -46 81 28z" />
@@ -32,6 +56,9 @@
+
+
+
diff --git a/Artemis/Artemis/lib/ColorBox.dll b/Artemis/Artemis/lib/ColorBox.dll
deleted file mode 100644
index 176d3f50b..000000000
Binary files a/Artemis/Artemis/lib/ColorBox.dll and /dev/null differ
diff --git a/Artemis/Artemis/packages.config b/Artemis/Artemis/packages.config
index e8320cba4..bc7832355 100644
--- a/Artemis/Artemis/packages.config
+++ b/Artemis/Artemis/packages.config
@@ -4,16 +4,15 @@
-
-
-
-
-
+
+
+
+
-
+
-
+
@@ -21,11 +20,11 @@
-
-
-
+
+
+
-
+
diff --git a/Artemis/ColorBox/AlphaSelector.cs b/Artemis/ColorBox/AlphaSelector.cs
new file mode 100644
index 000000000..5c4eea0dc
--- /dev/null
+++ b/Artemis/ColorBox/AlphaSelector.cs
@@ -0,0 +1,134 @@
+/***************** NCore Softwares Pvt. Ltd., India **************************
+
+ ColorBox
+
+ Copyright (C) 2013 NCore Softwares Pvt. Ltd.
+
+ This program is provided to you under the terms of the Microsoft Public
+ License (Ms-PL) as published at http://colorbox.codeplex.com/license
+
+***********************************************************************************/
+
+using System;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+
+namespace ColorBox
+{
+ public class AlphaSelector : BaseSelector
+ {
+ public static readonly DependencyProperty AlphaProperty =
+ DependencyProperty.Register("Alpha", typeof(double), typeof(AlphaSelector),
+ new FrameworkPropertyMetadata(1.0, AlphaChanged, AlphaCoerce));
+
+ public static readonly DependencyProperty AlphaOffsetProperty =
+ DependencyProperty.Register("AlphaOffset", typeof(double), typeof(AlphaSelector),
+ new UIPropertyMetadata(0.0));
+
+ public double Alpha
+ {
+ get { return (double) GetValue(AlphaProperty); }
+ set { SetValue(AlphaProperty, value); }
+ }
+
+
+ public double AlphaOffset
+ {
+ get { return (double) GetValue(AlphaOffsetProperty); }
+ private set { SetValue(AlphaOffsetProperty, value); }
+ }
+
+ public static void AlphaChanged(object o, DependencyPropertyChangedEventArgs e)
+ {
+ var h = (AlphaSelector) o;
+ h.SetAlphaOffset();
+ h.SetColor();
+ }
+
+ public static object AlphaCoerce(DependencyObject d, object brightness)
+ {
+ var v = (double) brightness;
+ if (v < 0) return 0.0;
+ if (v > 1) return 1.0;
+ return v;
+ }
+
+
+ protected override void OnMouseMove(MouseEventArgs e)
+ {
+ if (e.LeftButton == MouseButtonState.Pressed)
+ {
+ var p = e.GetPosition(this);
+
+ if (Orientation == Orientation.Vertical)
+ Alpha = 1 - p.Y/ActualHeight;
+ else
+ Alpha = 1 - p.X/ActualWidth;
+ }
+ base.OnMouseMove(e);
+ }
+
+ protected override void OnMouseDown(MouseButtonEventArgs e)
+ {
+ if (e.LeftButton == MouseButtonState.Pressed)
+ {
+ var p = e.GetPosition(this);
+
+ if (Orientation == Orientation.Vertical)
+ Alpha = 1 - p.Y/ActualHeight;
+ else
+ Alpha = 1 - p.X/ActualWidth;
+ }
+ Mouse.Capture(this);
+ base.OnMouseMove(e);
+ }
+
+ protected override void OnMouseUp(MouseButtonEventArgs e)
+ {
+ ReleaseMouseCapture();
+ base.OnMouseUp(e);
+ }
+
+ protected override void OnRender(DrawingContext dc)
+ {
+ var lb = new LinearGradientBrush();
+
+ lb.StartPoint = new Point(0, 0);
+
+ if (Orientation == Orientation.Vertical)
+ lb.EndPoint = new Point(0, 1);
+ else
+ lb.EndPoint = new Point(1, 0);
+
+ lb.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x00, 0x00, 0x00), 0.00));
+ lb.GradientStops.Add(new GradientStop(Color.FromArgb(0x00, 0x00, 0x00, 0x00), 1.00));
+
+ dc.DrawRectangle(lb, null, new Rect(0, 0, ActualWidth, ActualHeight));
+
+ SetAlphaOffset();
+ }
+
+ protected override Size ArrangeOverride(Size finalSize)
+ {
+ SetAlphaOffset();
+ return base.ArrangeOverride(finalSize);
+ }
+
+
+ private void SetAlphaOffset()
+ {
+ var length = ActualHeight;
+ if (Orientation == Orientation.Horizontal)
+ length = ActualWidth;
+ AlphaOffset = length - length*Alpha;
+ }
+
+ private void SetColor()
+ {
+ Color = Color.FromArgb((byte) Math.Round(Alpha*255), 0, 0, 0);
+ //Brush = new SolidColorBrush(Color);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/ColorBox/BaseSelector.cs b/Artemis/ColorBox/BaseSelector.cs
new file mode 100644
index 000000000..59fa829b8
--- /dev/null
+++ b/Artemis/ColorBox/BaseSelector.cs
@@ -0,0 +1,39 @@
+/***************** NCore Softwares Pvt. Ltd., India **************************
+
+ ColorBox
+
+ Copyright (C) 2013 NCore Softwares Pvt. Ltd.
+
+ This program is provided to you under the terms of the Microsoft Public
+ License (Ms-PL) as published at http://colorbox.codeplex.com/license
+
+***********************************************************************************/
+
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+
+namespace ColorBox
+{
+ public abstract class BaseSelector : FrameworkElement
+ {
+ public static readonly DependencyProperty OrientationProperty =
+ DependencyProperty.Register("Orientation", typeof(Orientation), typeof(BaseSelector),
+ new UIPropertyMetadata(Orientation.Vertical));
+
+ public static readonly DependencyProperty ColorProperty =
+ DependencyProperty.Register("Color", typeof(Color), typeof(BaseSelector), new UIPropertyMetadata(Colors.Red));
+
+ public Orientation Orientation
+ {
+ get { return (Orientation) GetValue(OrientationProperty); }
+ set { SetValue(OrientationProperty, value); }
+ }
+
+ public Color Color
+ {
+ get { return (Color) GetValue(ColorProperty); }
+ protected set { SetValue(ColorProperty, value); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/ColorBox/BrushTypes.cs b/Artemis/ColorBox/BrushTypes.cs
new file mode 100644
index 000000000..48cfa5a28
--- /dev/null
+++ b/Artemis/ColorBox/BrushTypes.cs
@@ -0,0 +1,24 @@
+/***************** NCore Softwares Pvt. Ltd., India **************************
+
+ ColorBox
+
+ Copyright (C) 2013 NCore Softwares Pvt. Ltd.
+
+ This program is provided to you under the terms of the Microsoft Public
+ License (Ms-PL) as published at http://colorbox.codeplex.com/license
+
+***********************************************************************************/
+
+using System;
+
+namespace ColorBox
+{
+ [Flags]
+ public enum BrushTypes
+ {
+ None,
+ Solid,
+ Linear,
+ Radial
+ }
+}
\ No newline at end of file
diff --git a/Artemis/ColorBox/ColorBox.cs b/Artemis/ColorBox/ColorBox.cs
new file mode 100644
index 000000000..1543b9a5a
--- /dev/null
+++ b/Artemis/ColorBox/ColorBox.cs
@@ -0,0 +1,1024 @@
+/***************** NCore Softwares Pvt. Ltd., India **************************
+
+ ColorBox
+
+ Copyright (C) 2013 NCore Softwares Pvt. Ltd.
+
+ This program is provided to you under the terms of the Microsoft Public
+ License (Ms-PL) as published at http://colorbox.codeplex.com/license
+
+***********************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+
+namespace ColorBox
+{
+ [TemplatePart(Name = PartCurrentColor, Type = typeof(TextBox))]
+ public class ColorBox : Control
+ {
+ internal const string PartCurrentColor = "PART_CurrentColor";
+
+ public static RoutedCommand RemoveGradientStop = new RoutedCommand();
+ public static RoutedCommand ReverseGradientStop = new RoutedCommand();
+ public static RoutedCommand DirectionHorizontal = new RoutedCommand();
+ public static RoutedCommand DirectionVertical = new RoutedCommand();
+ public static RoutedCommand DirectionTopLeftBottomRight = new RoutedCommand();
+ public static RoutedCommand DirectionTopRightBottomLeft = new RoutedCommand();
+ public static RoutedCommand SelectPreset = new RoutedCommand();
+ internal bool BrushSetInternally;
+ internal bool BrushTypeSetInternally;
+
+ //internal bool _GradientStopSetInternally = false;
+ internal bool HsbSetInternally;
+ internal bool RgbSetInternally;
+ internal bool UpdateBrush = true;
+
+ static ColorBox()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorBox), new FrameworkPropertyMetadata(typeof(ColorBox)));
+ }
+
+ internal TextBox CurrentColorTextBox { get; private set; }
+
+ public override void OnApplyTemplate()
+ {
+ base.OnApplyTemplate();
+
+ CurrentColorTextBox = GetTemplateChild(PartCurrentColor) as TextBox;
+ if (CurrentColorTextBox != null)
+ CurrentColorTextBox.PreviewKeyDown += CurrentColorTextBox_PreviewKeyDown;
+
+ CommandBindings.Add(new CommandBinding(RemoveGradientStop, RemoveGradientStop_Executed));
+ CommandBindings.Add(new CommandBinding(ReverseGradientStop, ReverseGradientStop_Executed));
+ CommandBindings.Add(new CommandBinding(DirectionHorizontal, DirectionHorizontal_Executed));
+ CommandBindings.Add(new CommandBinding(DirectionVertical, DirectionVertical_Executed));
+ CommandBindings.Add(new CommandBinding(DirectionTopLeftBottomRight, DirectionTopLeftBottomRight_Executed));
+ CommandBindings.Add(new CommandBinding(DirectionTopRightBottomLeft, DirectionTopRightBottomLeft_Executed));
+ CommandBindings.Add(new CommandBinding(SelectPreset, SelectPreset_Executed));
+ }
+
+ private void SelectPreset_Executed(object sender, ExecutedRoutedEventArgs e)
+ {
+ var presetBrush = (LinearGradientBrush) e.Parameter;
+ if (presetBrush == null)
+ return;
+
+ UpdateBrush = false;
+ BrushSetInternally = true;
+
+ Gradients.Clear();
+ foreach (var presetBrushGradientStop in presetBrush.GradientStops)
+ Gradients.Add(presetBrushGradientStop.CloneCurrentValue());
+ StartX = presetBrush.StartPoint.X;
+ StartY = presetBrush.StartPoint.Y;
+ EndX = presetBrush.EndPoint.X;
+ EndY = presetBrush.EndPoint.Y;
+
+ UpdateBrush = true;
+ BrushSetInternally = false;
+ SetBrush();
+ }
+
+ private void CurrentColorTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Enter)
+ {
+ var be = CurrentColorTextBox.GetBindingExpression(TextBox.TextProperty);
+ if (be != null)
+ be.UpdateSource();
+ }
+ }
+
+ private void RemoveGradientStop_Executed(object sender, ExecutedRoutedEventArgs e)
+ {
+ if ((Gradients != null) && (Gradients.Count > 2))
+ {
+ Gradients.Remove(SelectedGradient);
+ SetBrush();
+ }
+ }
+
+ private void ReverseGradientStop_Executed(object sender, ExecutedRoutedEventArgs e)
+ {
+ UpdateBrush = false;
+ BrushSetInternally = true;
+ foreach (var gs in Gradients)
+ gs.Offset = 1.0 - gs.Offset;
+ UpdateBrush = true;
+ BrushSetInternally = false;
+ SetBrush();
+ }
+
+ private void DirectionHorizontal_Executed(object sender, ExecutedRoutedEventArgs e)
+ {
+ UpdateBrush = false;
+ BrushSetInternally = true;
+
+ StartX = 0.5;
+ StartY = 0.0;
+ EndX = 0.5;
+ EndY = 1.0;
+
+ UpdateBrush = true;
+ BrushSetInternally = false;
+ SetBrush();
+ }
+
+ private void DirectionVertical_Executed(object sender, ExecutedRoutedEventArgs e)
+ {
+ UpdateBrush = false;
+ BrushSetInternally = true;
+
+ StartX = 0.0;
+ StartY = 0.5;
+ EndX = 1.0;
+ EndY = 0.5;
+
+ UpdateBrush = true;
+ BrushSetInternally = false;
+ SetBrush();
+ }
+
+ private void DirectionTopLeftBottomRight_Executed(object sender, ExecutedRoutedEventArgs e)
+ {
+ UpdateBrush = false;
+ BrushSetInternally = true;
+
+ StartX = 0.0;
+ StartY = 1.0;
+ EndX = 1.0;
+ EndY = 0.0;
+
+ UpdateBrush = true;
+ BrushSetInternally = false;
+ SetBrush();
+ }
+
+ private void DirectionTopRightBottomLeft_Executed(object sender, ExecutedRoutedEventArgs e)
+ {
+ UpdateBrush = false;
+ BrushSetInternally = true;
+
+ StartX = 0.0;
+ StartY = 0.0;
+ EndX = 1.0;
+ EndY = 1.0;
+
+ UpdateBrush = true;
+ BrushSetInternally = false;
+ SetBrush();
+ }
+
+ private void InitTransform()
+ {
+ if ((Brush.Transform == null) || Brush.Transform.Value.IsIdentity)
+ {
+ BrushSetInternally = true;
+
+ var tg = new TransformGroup();
+ tg.Children.Add(new RotateTransform());
+ tg.Children.Add(new ScaleTransform());
+ tg.Children.Add(new SkewTransform());
+ tg.Children.Add(new TranslateTransform());
+ Brush.Transform = tg;
+
+ BrushSetInternally = false;
+ }
+ }
+
+ ///
+ /// Shared property changed callback to update the Color property
+ ///
+ public static void UpdateColorHsb(object o, DependencyPropertyChangedEventArgs e)
+ {
+ var c = (ColorBox) o;
+ var n = ColorHelper.ColorFromAhsb(c.Alpha, c.Hue, c.Saturation, c.Brightness);
+
+ c.HsbSetInternally = true;
+
+ c.Color = n;
+
+ if (c.SelectedGradient != null)
+ c.SelectedGradient.Color = n;
+
+ c.SetBrush();
+
+ c.HsbSetInternally = false;
+ }
+
+ ///
+ /// Shared property changed callback to update the Color property
+ ///
+ public static void UpdateColorRgb(object o, DependencyPropertyChangedEventArgs e)
+ {
+ var c = (ColorBox) o;
+ var n = Color.FromArgb((byte) c.A, (byte) c.R, (byte) c.G, (byte) c.B);
+
+ c.RgbSetInternally = true;
+
+ c.Color = n;
+
+ if (c.SelectedGradient != null)
+ c.SelectedGradient.Color = n;
+
+ c.SetBrush();
+
+ c.RgbSetInternally = false;
+ }
+
+ internal void SetBrush()
+ {
+ if (!UpdateBrush)
+ return;
+
+ BrushSetInternally = true;
+
+ // retain old opacity
+ double opacity = 1;
+ TransformGroup tempTg = null;
+ if (Brush != null)
+ {
+ opacity = Brush.Opacity;
+ tempTg = Brush.Transform as TransformGroup;
+ }
+
+ switch (BrushType)
+ {
+ case BrushTypes.None:
+ Brush = null;
+ break;
+
+ case BrushTypes.Solid:
+
+ Brush = new SolidColorBrush(Color);
+
+ break;
+
+ case BrushTypes.Linear:
+
+ var brush = new LinearGradientBrush();
+ foreach (var g in Gradients)
+ brush.GradientStops.Add(new GradientStop(g.Color, g.Offset));
+ brush.StartPoint = new Point(StartX, StartY);
+ brush.EndPoint = new Point(EndX, EndY);
+ brush.MappingMode = MappingMode;
+ brush.SpreadMethod = SpreadMethod;
+ Brush = brush;
+
+ break;
+
+ case BrushTypes.Radial:
+
+ var brush1 = new RadialGradientBrush();
+ foreach (var g in Gradients)
+ brush1.GradientStops.Add(new GradientStop(g.Color, g.Offset));
+ brush1.GradientOrigin = new Point(GradientOriginX, GradientOriginY);
+ brush1.Center = new Point(CenterX, CenterY);
+ brush1.RadiusX = RadiusX;
+ brush1.RadiusY = RadiusY;
+ brush1.MappingMode = MappingMode;
+ brush1.SpreadMethod = SpreadMethod;
+ Brush = brush1;
+
+ break;
+ }
+
+ if (BrushType != BrushTypes.None)
+ {
+ Brush.Opacity = opacity; // retain old opacity
+ if (tempTg != null)
+ Brush.Transform = tempTg;
+ }
+
+ BrushSetInternally = false;
+ }
+
+ #region Private Properties
+
+ private double StartX
+ {
+ get { return (double) GetValue(StartXProperty); }
+ set { SetValue(StartXProperty, value); }
+ }
+
+ private static readonly DependencyProperty StartXProperty =
+ DependencyProperty.Register("StartX", typeof(double), typeof(ColorBox),
+ new PropertyMetadata(0.5, StartXChanged));
+
+ private static void StartXChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
+ {
+ var cp = property as ColorBox;
+ if (cp.Brush is LinearGradientBrush)
+ {
+ cp.BrushSetInternally = true;
+ (cp.Brush as LinearGradientBrush).StartPoint = new Point((double) args.NewValue,
+ (cp.Brush as LinearGradientBrush).StartPoint.Y);
+ cp.BrushSetInternally = false;
+ }
+ }
+
+ private double StartY
+ {
+ get { return (double) GetValue(StartYProperty); }
+ set { SetValue(StartYProperty, value); }
+ }
+
+ private static readonly DependencyProperty StartYProperty =
+ DependencyProperty.Register("StartY", typeof(double), typeof(ColorBox),
+ new PropertyMetadata(0.0, StartYChanged));
+
+ private static void StartYChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
+ {
+ var cp = property as ColorBox;
+ if (cp.Brush is LinearGradientBrush)
+ {
+ cp.BrushSetInternally = true;
+ (cp.Brush as LinearGradientBrush).StartPoint = new Point(
+ (cp.Brush as LinearGradientBrush).StartPoint.X, (double) args.NewValue);
+ cp.BrushSetInternally = false;
+ }
+ }
+
+ private double EndX
+ {
+ get { return (double) GetValue(EndXProperty); }
+ set { SetValue(EndXProperty, value); }
+ }
+
+ private static readonly DependencyProperty EndXProperty =
+ DependencyProperty.Register("EndX", typeof(double), typeof(ColorBox), new PropertyMetadata(0.5, EndXChanged));
+
+ private static void EndXChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
+ {
+ var cp = property as ColorBox;
+ if (cp.Brush is LinearGradientBrush)
+ {
+ cp.BrushSetInternally = true;
+ (cp.Brush as LinearGradientBrush).EndPoint = new Point((double) args.NewValue,
+ (cp.Brush as LinearGradientBrush).EndPoint.Y);
+ cp.BrushSetInternally = false;
+ }
+ }
+
+ private double EndY
+ {
+ get { return (double) GetValue(EndYProperty); }
+ set { SetValue(EndYProperty, value); }
+ }
+
+ private static readonly DependencyProperty EndYProperty =
+ DependencyProperty.Register("EndY", typeof(double), typeof(ColorBox), new PropertyMetadata(1.0, EndYChanged));
+
+ private static void EndYChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
+ {
+ var cp = property as ColorBox;
+ if (cp.Brush is LinearGradientBrush)
+ {
+ cp.BrushSetInternally = true;
+ (cp.Brush as LinearGradientBrush).EndPoint = new Point((cp.Brush as LinearGradientBrush).EndPoint.X,
+ (double) args.NewValue);
+ cp.BrushSetInternally = false;
+ }
+ }
+
+
+ private double GradientOriginX
+ {
+ get { return (double) GetValue(GradientOriginXProperty); }
+ set { SetValue(GradientOriginXProperty, value); }
+ }
+
+ private static readonly DependencyProperty GradientOriginXProperty =
+ DependencyProperty.Register("GradientOriginX", typeof(double), typeof(ColorBox),
+ new PropertyMetadata(0.5, GradientOriginXChanged));
+
+ private static void GradientOriginXChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
+ {
+ var cp = property as ColorBox;
+ if (cp.Brush is RadialGradientBrush)
+ {
+ cp.BrushSetInternally = true;
+ (cp.Brush as RadialGradientBrush).GradientOrigin = new Point((double) args.NewValue,
+ (cp.Brush as RadialGradientBrush).GradientOrigin.Y);
+ cp.BrushSetInternally = false;
+ }
+ }
+
+ private double GradientOriginY
+ {
+ get { return (double) GetValue(GradientOriginYProperty); }
+ set { SetValue(GradientOriginYProperty, value); }
+ }
+
+ private static readonly DependencyProperty GradientOriginYProperty =
+ DependencyProperty.Register("GradientOriginY", typeof(double), typeof(ColorBox),
+ new PropertyMetadata(0.5, GradientOriginYChanged));
+
+ private static void GradientOriginYChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
+ {
+ var cp = property as ColorBox;
+ if (cp.Brush is RadialGradientBrush)
+ {
+ cp.BrushSetInternally = true;
+ (cp.Brush as RadialGradientBrush).GradientOrigin =
+ new Point((cp.Brush as RadialGradientBrush).GradientOrigin.X, (double) args.NewValue);
+ cp.BrushSetInternally = false;
+ }
+ }
+
+ private double CenterX
+ {
+ get { return (double) GetValue(CenterXProperty); }
+ set { SetValue(CenterXProperty, value); }
+ }
+
+ private static readonly DependencyProperty CenterXProperty =
+ DependencyProperty.Register("CenterX", typeof(double), typeof(ColorBox),
+ new PropertyMetadata(0.5, CenterXChanged));
+
+ private static void CenterXChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
+ {
+ var cp = property as ColorBox;
+ if (cp.Brush is RadialGradientBrush)
+ {
+ cp.BrushSetInternally = true;
+ (cp.Brush as RadialGradientBrush).Center = new Point((double) args.NewValue,
+ (cp.Brush as RadialGradientBrush).Center.Y);
+ cp.BrushSetInternally = false;
+ }
+ }
+
+ private double CenterY
+ {
+ get { return (double) GetValue(CenterYProperty); }
+ set { SetValue(CenterYProperty, value); }
+ }
+
+ private static readonly DependencyProperty CenterYProperty =
+ DependencyProperty.Register("CenterY", typeof(double), typeof(ColorBox),
+ new PropertyMetadata(0.5, CenterYChanged));
+
+ private static void CenterYChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
+ {
+ var cp = property as ColorBox;
+ if (cp.Brush is RadialGradientBrush)
+ {
+ cp.BrushSetInternally = true;
+ (cp.Brush as RadialGradientBrush).Center = new Point((cp.Brush as RadialGradientBrush).Center.X,
+ (double) args.NewValue);
+ cp.BrushSetInternally = false;
+ }
+ }
+
+ private double RadiusX
+ {
+ get { return (double) GetValue(RadiusXProperty); }
+ set { SetValue(RadiusXProperty, value); }
+ }
+
+ private static readonly DependencyProperty RadiusXProperty =
+ DependencyProperty.Register("RadiusX", typeof(double), typeof(ColorBox),
+ new PropertyMetadata(0.5, RadiusXChanged));
+
+ private static void RadiusXChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
+ {
+ var cp = property as ColorBox;
+ if (cp.Brush is RadialGradientBrush)
+ {
+ cp.BrushSetInternally = true;
+ (cp.Brush as RadialGradientBrush).RadiusX = (double) args.NewValue;
+ cp.BrushSetInternally = false;
+ }
+ }
+
+ private double RadiusY
+ {
+ get { return (double) GetValue(RadiusYProperty); }
+ set { SetValue(RadiusYProperty, value); }
+ }
+
+ private static readonly DependencyProperty RadiusYProperty =
+ DependencyProperty.Register("RadiusY", typeof(double), typeof(ColorBox),
+ new PropertyMetadata(0.5, RadiusYChanged));
+
+ private static void RadiusYChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
+ {
+ var cp = property as ColorBox;
+ if (cp.Brush is RadialGradientBrush)
+ {
+ cp.BrushSetInternally = true;
+ (cp.Brush as RadialGradientBrush).RadiusY = (double) args.NewValue;
+ cp.BrushSetInternally = false;
+ }
+ }
+
+ private double BrushOpacity
+ {
+ get { return (double) GetValue(BrushOpacityProperty); }
+ set { SetValue(BrushOpacityProperty, value); }
+ }
+
+ private static readonly DependencyProperty BrushOpacityProperty =
+ DependencyProperty.Register("BrushOpacity", typeof(double), typeof(ColorBox), new PropertyMetadata(1.0));
+
+ //static void BrushOpacityChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
+ //{
+ // ColorBox cp = property as ColorBox;
+ // cp._BrushSetInternally = true;
+ // cp.Brush.Opacity = (double)args.NewValue;
+ // cp._BrushSetInternally = false;
+ //}
+
+ private GradientSpreadMethod SpreadMethod
+ {
+ get { return (GradientSpreadMethod) GetValue(SpreadMethodProperty); }
+ set { SetValue(SpreadMethodProperty, value); }
+ }
+
+ private static readonly DependencyProperty SpreadMethodProperty =
+ DependencyProperty.Register("SpreadMethod", typeof(GradientSpreadMethod), typeof(ColorBox),
+ new PropertyMetadata(GradientSpreadMethod.Pad, SpreadMethodChanged));
+
+ private static void SpreadMethodChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
+ {
+ var cp = property as ColorBox;
+ if (cp.Brush is GradientBrush)
+ {
+ cp.BrushSetInternally = true;
+ (cp.Brush as GradientBrush).SpreadMethod = (GradientSpreadMethod) args.NewValue;
+ cp.BrushSetInternally = false;
+ }
+ }
+
+ private BrushMappingMode MappingMode
+ {
+ get { return (BrushMappingMode) GetValue(MappingModeProperty); }
+ set { SetValue(MappingModeProperty, value); }
+ }
+
+ private static readonly DependencyProperty MappingModeProperty =
+ DependencyProperty.Register("MappingMode", typeof(BrushMappingMode), typeof(ColorBox),
+ new PropertyMetadata(BrushMappingMode.RelativeToBoundingBox, MappingModeChanged));
+
+ private static void MappingModeChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
+ {
+ var cp = property as ColorBox;
+ if (cp.Brush is GradientBrush)
+ {
+ cp.BrushSetInternally = true;
+ (cp.Brush as GradientBrush).MappingMode = (BrushMappingMode) args.NewValue;
+ cp.BrushSetInternally = false;
+ }
+ }
+
+ #endregion
+
+ #region Internal Properties
+
+ internal ObservableCollection Gradients
+ {
+ get { return (ObservableCollection) GetValue(GradientsProperty); }
+ set { SetValue(GradientsProperty, value); }
+ }
+
+ internal static readonly DependencyProperty GradientsProperty =
+ DependencyProperty.Register("Gradients", typeof(ObservableCollection), typeof(ColorBox));
+
+ internal GradientStop SelectedGradient
+ {
+ get { return (GradientStop) GetValue(SelectedGradientProperty); }
+ set { SetValue(SelectedGradientProperty, value); }
+ }
+
+ internal static readonly DependencyProperty SelectedGradientProperty =
+ DependencyProperty.Register("SelectedGradient", typeof(GradientStop), typeof(ColorBox));
+
+ internal BrushTypes BrushType
+ {
+ get { return (BrushTypes) GetValue(BrushTypeProperty); }
+ set { SetValue(BrushTypeProperty, value); }
+ }
+
+ internal static readonly DependencyProperty BrushTypeProperty =
+ DependencyProperty.Register("BrushType", typeof(BrushTypes), typeof(ColorBox),
+ new FrameworkPropertyMetadata(BrushTypes.None, BrushTypeChanged));
+
+ private static void BrushTypeChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
+ {
+ var c = property as ColorBox;
+ if (!c.BrushTypeSetInternally)
+ {
+ if (c.Gradients == null)
+ {
+ c.Gradients = new ObservableCollection();
+ c.Gradients.Add(new GradientStop(Colors.Black, 0));
+ c.Gradients.Add(new GradientStop(Colors.White, 1));
+ }
+
+ c.SetBrush();
+ }
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ public IEnumerable SpreadMethodTypes
+ {
+ get
+ {
+ var temp = GradientSpreadMethod.Pad | GradientSpreadMethod.Reflect | GradientSpreadMethod.Repeat;
+ foreach (Enum value in Enum.GetValues(temp.GetType()))
+ if (temp.HasFlag(value))
+ yield return value;
+ }
+ }
+
+ public IEnumerable MappingModeTypes
+ {
+ get
+ {
+ var temp = BrushMappingMode.Absolute | BrushMappingMode.RelativeToBoundingBox;
+ foreach (Enum value in Enum.GetValues(temp.GetType()))
+ if (temp.HasFlag(value))
+ yield return value;
+ }
+ }
+
+ public IEnumerable AvailableBrushTypes
+ {
+ get
+ {
+ if (ShowNone)
+ yield return BrushTypes.None;
+ if (ShowSolid)
+ yield return BrushTypes.Solid;
+ if (ShowLinear)
+ yield return BrushTypes.Linear;
+ if (ShowRadial)
+ yield return BrushTypes.Radial;
+ }
+ }
+
+ public Brush Brush
+ {
+ get { return (Brush) GetValue(BrushProperty); }
+ set { SetValue(BrushProperty, value); }
+ }
+
+ public bool ShowNone
+ {
+ get { return (bool) GetValue(ShowNoneProperty); }
+ set { SetValue(ShowNoneProperty, value); }
+ }
+
+ public bool ShowSolid
+ {
+ get { return (bool) GetValue(ShowSolidProperty); }
+ set { SetValue(ShowSolidProperty, value); }
+ }
+
+ public bool ShowLinear
+ {
+ get { return (bool) GetValue(ShowLinearProperty); }
+ set { SetValue(ShowLinearProperty, value); }
+ }
+
+ public bool ShowRadial
+ {
+ get { return (bool) GetValue(ShowRadialProperty); }
+ set { SetValue(ShowRadialProperty, value); }
+ }
+
+ public static readonly DependencyProperty ShowNoneProperty = DependencyProperty.Register("ShowNone",
+ typeof(bool), typeof(ColorBox), new FrameworkPropertyMetadata(true));
+
+ public static readonly DependencyProperty ShowSolidProperty = DependencyProperty.Register("ShowSolid",
+ typeof(bool), typeof(ColorBox), new FrameworkPropertyMetadata(true));
+
+ public static readonly DependencyProperty ShowLinearProperty = DependencyProperty.Register("ShowLinear",
+ typeof(bool), typeof(ColorBox), new FrameworkPropertyMetadata(true));
+
+ public static readonly DependencyProperty ShowRadialProperty = DependencyProperty.Register("ShowRadial",
+ typeof(bool), typeof(ColorBox), new FrameworkPropertyMetadata(true));
+
+ public static readonly DependencyProperty BrushProperty = DependencyProperty.Register("Brush", typeof(Brush),
+ typeof(ColorBox), new FrameworkPropertyMetadata(null, BrushChanged));
+
+ private static void BrushChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
+ {
+ var c = property as ColorBox;
+ var brush = args.NewValue as Brush;
+
+ if (!c.BrushSetInternally)
+ {
+ c.BrushTypeSetInternally = true;
+
+ if (brush == null)
+ {
+ c.BrushType = BrushTypes.None;
+ }
+ else if (brush is SolidColorBrush)
+ {
+ c.BrushType = BrushTypes.Solid;
+ c.Color = (brush as SolidColorBrush).Color;
+ }
+ else if (brush is LinearGradientBrush)
+ {
+ var lgb = brush as LinearGradientBrush;
+ //c.Opacity = lgb.Opacity;
+ c.StartX = lgb.StartPoint.X;
+ c.StartY = lgb.StartPoint.Y;
+ c.EndX = lgb.EndPoint.X;
+ c.EndY = lgb.EndPoint.Y;
+ c.MappingMode = lgb.MappingMode;
+ c.SpreadMethod = lgb.SpreadMethod;
+ c.Gradients = new ObservableCollection(lgb.GradientStops);
+ c.BrushType = BrushTypes.Linear;
+ //c.Color = lgb.GradientStops.OrderBy(x => x.Offset).Last().Color;
+ //c.SelectedGradient = lgb.GradientStops.OrderBy(x => x.Offset).Last();
+ }
+ else
+ {
+ var rgb = brush as RadialGradientBrush;
+ c.GradientOriginX = rgb.GradientOrigin.X;
+ c.GradientOriginY = rgb.GradientOrigin.Y;
+ c.RadiusX = rgb.RadiusX;
+ c.RadiusY = rgb.RadiusY;
+ c.CenterX = rgb.Center.X;
+ c.CenterY = rgb.Center.Y;
+ c.MappingMode = rgb.MappingMode;
+ c.SpreadMethod = rgb.SpreadMethod;
+ c.Gradients = new ObservableCollection(rgb.GradientStops);
+ c.BrushType = BrushTypes.Radial;
+ //c.Color = rgb.GradientStops.OrderBy(x => x.Offset).Last().Color;
+ //c.SelectedGradient = rgb.GradientStops.OrderBy(x => x.Offset).Last();
+ }
+
+ c.BrushTypeSetInternally = false;
+ }
+ }
+
+ public Color Color
+ {
+ get { return (Color) GetValue(ColorProperty); }
+ set { SetValue(ColorProperty, value); }
+ }
+
+ public static readonly DependencyProperty ColorProperty =
+ DependencyProperty.Register("Color", typeof(Color), typeof(ColorBox),
+ new UIPropertyMetadata(Colors.Black, OnColorChanged));
+
+ public static void OnColorChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
+ {
+ var c = (ColorBox) o;
+
+ if (e.NewValue is Color)
+ {
+ var color = (Color) e.NewValue;
+
+ if (!c.HsbSetInternally)
+ {
+ // update HSB value based on new value of color
+
+ double h = 0;
+ double s = 0;
+ double b = 0;
+ ColorHelper.HsbFromColor(color, ref h, ref s, ref b);
+
+ c.HsbSetInternally = true;
+
+ c.Alpha = color.A/255d;
+ c.Hue = h;
+ c.Saturation = s;
+ c.Brightness = b;
+
+ c.HsbSetInternally = false;
+ }
+
+ if (!c.RgbSetInternally)
+ {
+ // update RGB value based on new value of color
+
+ c.RgbSetInternally = true;
+
+ c.A = color.A;
+ c.R = color.R;
+ c.G = color.G;
+ c.B = color.B;
+
+ c.RgbSetInternally = false;
+ }
+
+ c.RaiseColorChangedEvent((Color) e.NewValue);
+ }
+ }
+
+ #endregion
+
+ #region Color Specific Properties
+
+ private double Hue
+ {
+ get { return (double) GetValue(HueProperty); }
+ set { SetValue(HueProperty, value); }
+ }
+
+ private static readonly DependencyProperty HueProperty =
+ DependencyProperty.Register("Hue", typeof(double), typeof(ColorBox),
+ new FrameworkPropertyMetadata(1.0, UpdateColorHsb, HueCoerce));
+
+ private static object HueCoerce(DependencyObject d, object hue)
+ {
+ var v = (double) hue;
+ if (v < 0) return 0.0;
+ if (v > 1) return 1.0;
+ return v;
+ }
+
+
+ private double Brightness
+ {
+ get { return (double) GetValue(BrightnessProperty); }
+ set { SetValue(BrightnessProperty, value); }
+ }
+
+ private static readonly DependencyProperty BrightnessProperty =
+ DependencyProperty.Register("Brightness", typeof(double), typeof(ColorBox),
+ new FrameworkPropertyMetadata(0.0, UpdateColorHsb, BrightnessCoerce));
+
+ private static object BrightnessCoerce(DependencyObject d, object brightness)
+ {
+ var v = (double) brightness;
+ if (v < 0) return 0.0;
+ if (v > 1) return 1.0;
+ return v;
+ }
+
+
+ private double Saturation
+ {
+ get { return (double) GetValue(SaturationProperty); }
+ set { SetValue(SaturationProperty, value); }
+ }
+
+ private static readonly DependencyProperty SaturationProperty =
+ DependencyProperty.Register("Saturation", typeof(double), typeof(ColorBox),
+ new FrameworkPropertyMetadata(0.0, UpdateColorHsb, SaturationCoerce));
+
+ private static object SaturationCoerce(DependencyObject d, object saturation)
+ {
+ var v = (double) saturation;
+ if (v < 0) return 0.0;
+ if (v > 1) return 1.0;
+ return v;
+ }
+
+
+ private double Alpha
+ {
+ get { return (double) GetValue(AlphaProperty); }
+ set { SetValue(AlphaProperty, value); }
+ }
+
+ private static readonly DependencyProperty AlphaProperty =
+ DependencyProperty.Register("Alpha", typeof(double), typeof(ColorBox),
+ new FrameworkPropertyMetadata(1.0, UpdateColorHsb, AlphaCoerce));
+
+ private static object AlphaCoerce(DependencyObject d, object alpha)
+ {
+ var v = (double) alpha;
+ if (v < 0) return 0.0;
+ if (v > 1) return 1.0;
+ return v;
+ }
+
+
+ private int A
+ {
+ get { return (int) GetValue(AProperty); }
+ set { SetValue(AProperty, value); }
+ }
+
+ private static readonly DependencyProperty AProperty =
+ DependencyProperty.Register("A", typeof(int), typeof(ColorBox),
+ new FrameworkPropertyMetadata(255, UpdateColorRgb, RgbCoerce));
+
+
+ private int R
+ {
+ get { return (int) GetValue(RProperty); }
+ set { SetValue(RProperty, value); }
+ }
+
+ private static readonly DependencyProperty RProperty =
+ DependencyProperty.Register("R", typeof(int), typeof(ColorBox),
+ new FrameworkPropertyMetadata(default(int), UpdateColorRgb, RgbCoerce));
+
+
+ private int G
+ {
+ get { return (int) GetValue(GProperty); }
+ set { SetValue(GProperty, value); }
+ }
+
+ private static readonly DependencyProperty GProperty =
+ DependencyProperty.Register("G", typeof(int), typeof(ColorBox),
+ new FrameworkPropertyMetadata(default(int), UpdateColorRgb, RgbCoerce));
+
+
+ private int B
+ {
+ get { return (int) GetValue(BProperty); }
+ set { SetValue(BProperty, value); }
+ }
+
+ public static LinearGradientBrush RainbowPreset => new LinearGradientBrush(
+ new GradientStopCollection(new[]
+ {
+ new GradientStop(Colors.Red, 0),
+ new GradientStop(Colors.Yellow, 0.2),
+ new GradientStop(Colors.LawnGreen, 0.4),
+ new GradientStop(Colors.Blue, 0.6),
+ new GradientStop(Colors.Purple, 0.8),
+ new GradientStop(Colors.Red, 1)
+ }), new Point(0, 0.5), new Point(1, 0.5));
+
+ public static LinearGradientBrush PolicePreset => new LinearGradientBrush(
+ new GradientStopCollection(new[]
+ {
+ new GradientStop(Colors.Red, 0),
+ new GradientStop(Colors.Blue, 0.5),
+ new GradientStop(Colors.Red, 1)
+ }), new Point(0, 0.5), new Point(1, 0.5));
+
+ public static LinearGradientBrush ArtemisPreset => new LinearGradientBrush(
+ new GradientStopCollection(new[]
+ {
+ new GradientStop(Color.FromArgb(255, 7, 144, 142), 0.1),
+ new GradientStop(Color.FromArgb(255, 105, 255, 29), 0.3),
+ new GradientStop(Color.FromArgb(255, 255, 203, 16), 0.5),
+ new GradientStop(Color.FromArgb(255, 156, 0, 255), 0.7),
+ new GradientStop(Color.FromArgb(255, 7, 144, 142), 0.9)
+ }), new Point(0, 0), new Point(1, 1));
+
+ public static LinearGradientBrush HelloKittyPreset => new LinearGradientBrush(
+ new GradientStopCollection(new[]
+ {
+ new GradientStop(Color.FromArgb(255, 255, 93, 255), 0),
+ new GradientStop(Color.FromArgb(255, 255, 220, 255), 0.5),
+ new GradientStop(Color.FromArgb(255, 255, 93, 255), 1)
+ }), new Point(0.5, 0), new Point(0.5, 1));
+
+ public static LinearGradientBrush GreenToRedPreset => new LinearGradientBrush(
+ new GradientStopCollection(new[]
+ {
+ new GradientStop(Colors.LawnGreen, 0),
+ new GradientStop(Colors.Orange, 0.5),
+ new GradientStop(Colors.Red, 1)
+ }), new Point(0.5, 0), new Point(0.5, 1));
+
+ private static readonly DependencyProperty BProperty =
+ DependencyProperty.Register("B", typeof(int), typeof(ColorBox),
+ new FrameworkPropertyMetadata(default(int), UpdateColorRgb, RgbCoerce));
+
+
+ private static object RgbCoerce(DependencyObject d, object value)
+ {
+ var v = (int) value;
+ if (v < 0) return 0;
+ if (v > 255) return 255;
+ return v;
+ }
+
+ #endregion
+
+ #region ColorChanged Event
+
+ public delegate void ColorChangedEventHandler(object sender, ColorChangedEventArgs e);
+
+ public static readonly RoutedEvent ColorChangedEvent =
+ EventManager.RegisterRoutedEvent("ColorChanged", RoutingStrategy.Bubble, typeof(ColorChangedEventHandler),
+ typeof(ColorBox));
+
+ public event ColorChangedEventHandler ColorChanged
+ {
+ add { AddHandler(ColorChangedEvent, value); }
+ remove { RemoveHandler(ColorChangedEvent, value); }
+ }
+
+ private void RaiseColorChangedEvent(Color color)
+ {
+ var newEventArgs = new ColorChangedEventArgs(ColorChangedEvent, color);
+ RaiseEvent(newEventArgs);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Artemis/ColorBox/ColorBox.csproj b/Artemis/ColorBox/ColorBox.csproj
new file mode 100644
index 000000000..cf86e48d7
--- /dev/null
+++ b/Artemis/ColorBox/ColorBox.csproj
@@ -0,0 +1,93 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {40085232-ACED-4CBE-945B-90BA8153C151}
+ Library
+ Properties
+ ColorBox
+ ColorBox
+ v4.0
+ 512
+ SAK
+ SAK
+ SAK
+ SAK
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ true
+
+
+ ColorBox.snk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/ColorBox/ColorBox.snk b/Artemis/ColorBox/ColorBox.snk
new file mode 100644
index 000000000..5f48e75f0
Binary files /dev/null and b/Artemis/ColorBox/ColorBox.snk differ
diff --git a/Artemis/ColorBox/ColorChangedEventArgs.cs b/Artemis/ColorBox/ColorChangedEventArgs.cs
new file mode 100644
index 000000000..a97511476
--- /dev/null
+++ b/Artemis/ColorBox/ColorChangedEventArgs.cs
@@ -0,0 +1,27 @@
+/***************** NCore Softwares Pvt. Ltd., India **************************
+
+ ColorBox
+
+ Copyright (C) 2013 NCore Softwares Pvt. Ltd.
+
+ This program is provided to you under the terms of the Microsoft Public
+ License (Ms-PL) as published at http://colorbox.codeplex.com/license
+
+***********************************************************************************/
+
+using System.Windows;
+using System.Windows.Media;
+
+namespace ColorBox
+{
+ public class ColorChangedEventArgs : RoutedEventArgs
+ {
+ public ColorChangedEventArgs(RoutedEvent routedEvent, Color color)
+ {
+ RoutedEvent = routedEvent;
+ Color = color;
+ }
+
+ public Color Color { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/ColorBox/DoubleUpDown.cs b/Artemis/ColorBox/DoubleUpDown.cs
new file mode 100644
index 000000000..ed7a0c936
--- /dev/null
+++ b/Artemis/ColorBox/DoubleUpDown.cs
@@ -0,0 +1,201 @@
+/*************************************************************************************
+
+ Extended WPF Toolkit
+
+ Copyright (C) 2007-2013 Xceed Software Inc.
+
+ This program is provided to you under the terms of the Microsoft Public
+ License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
+
+ For more features, controls, and fast professional support,
+ pick up the Plus Edition at http://xceed.com/wpf_toolkit
+
+ Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
+
+ ***********************************************************************************/
+
+using System;
+using System.Globalization;
+using System.Windows;
+
+namespace ColorBox
+{
+ public class DoubleUpDown : UpDownBase
+ {
+ private readonly FromDecimal _fromDecimal;
+ private readonly Func _fromGreaterThan;
+ private readonly Func _fromLowerThan;
+
+ private readonly FromText _fromText;
+
+ protected DoubleUpDown(FromText fromText, FromDecimal fromDecimal, Func fromLowerThan,
+ Func fromGreaterThan)
+ {
+ if (fromText == null)
+ throw new ArgumentNullException("parseMethod");
+
+ if (fromDecimal == null)
+ throw new ArgumentNullException("fromDecimal");
+
+ if (fromLowerThan == null)
+ throw new ArgumentNullException("fromLowerThan");
+
+ if (fromGreaterThan == null)
+ throw new ArgumentNullException("fromGreaterThan");
+
+ _fromText = fromText;
+ _fromDecimal = fromDecimal;
+ _fromLowerThan = fromLowerThan;
+ _fromGreaterThan = fromGreaterThan;
+ }
+
+ protected static void UpdateMetadata(Type type, double? increment, double? minValue, double? maxValue)
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(type, new FrameworkPropertyMetadata(type));
+ IncrementProperty.OverrideMetadata(type, new FrameworkPropertyMetadata(increment));
+ MaximumProperty.OverrideMetadata(type, new FrameworkPropertyMetadata(maxValue));
+ MinimumProperty.OverrideMetadata(type, new FrameworkPropertyMetadata(minValue));
+ }
+
+ private bool IsLowerThan(double? value1, double? value2)
+ {
+ if ((value1 == null) || (value2 == null))
+ return false;
+
+ return _fromLowerThan(value1.Value, value2.Value);
+ }
+
+ private bool IsGreaterThan(double? value1, double? value2)
+ {
+ if ((value1 == null) || (value2 == null))
+ return false;
+
+ return _fromGreaterThan(value1.Value, value2.Value);
+ }
+
+ private bool HandleNullSpin()
+ {
+ if (!Value.HasValue)
+ {
+ var forcedValue = DefaultValue.HasValue
+ ? DefaultValue.Value
+ : default(double);
+
+ Value = CoerceValueMinMax(forcedValue);
+
+ return true;
+ }
+ if (!Increment.HasValue)
+ return true;
+
+ return false;
+ }
+
+ private double CoerceValueMinMax(double value)
+ {
+ if (IsLowerThan(value, Minimum))
+ return Minimum;
+ if (IsGreaterThan(value, Maximum))
+ return Maximum;
+ return value;
+ }
+
+ private void ValidateDefaultMinMax(double? value)
+ {
+ if (Equals(value, DefaultValue))
+ return;
+
+ if (IsLowerThan(value, Minimum))
+ throw new ArgumentOutOfRangeException("Minimum",
+ string.Format("Value must be greater than MinValue of {0}", Minimum));
+ if (IsGreaterThan(value, Maximum))
+ throw new ArgumentOutOfRangeException("Maximum",
+ string.Format("Value must be less than MaxValue of {0}", Maximum));
+ }
+
+ protected delegate double FromText(string s, NumberStyles style, IFormatProvider provider);
+
+ protected delegate double FromDecimal(decimal d);
+
+ #region Base Class Overrides
+
+ protected override void OnIncrement()
+ {
+ if (!HandleNullSpin())
+ {
+ double? result = Value.Value + Increment.Value;
+ Value = CoerceValueMinMax(result.Value);
+ }
+ }
+
+ protected override void OnDecrement()
+ {
+ if (!HandleNullSpin())
+ {
+ double? result = Value.Value - Increment.Value;
+ Value = CoerceValueMinMax(result.Value);
+ }
+ }
+
+ protected override string ConvertValueToText()
+ {
+ if (Value == null)
+ return string.Empty;
+
+ return Value.Value.ToString(FormatString, CultureInfo);
+ }
+
+ protected override double? ConvertTextToValue(string text)
+ {
+ double? result = 0;
+
+ if (string.IsNullOrEmpty(text))
+ return result;
+
+ var currentValueText = ConvertValueToText();
+ if (Equals(currentValueText, text))
+ return Value;
+
+ result = FormatString.Contains("P")
+ ? _fromDecimal(ParsePercent(text, CultureInfo))
+ : _fromText(text, ParsingNumberStyle, CultureInfo);
+
+ ValidateDefaultMinMax(result);
+
+ return result;
+ }
+
+ protected override void SetValidSpinDirection()
+ {
+ var validDirections = ValidSpinDirections.None;
+
+ if ((Increment != null) && !IsReadOnly)
+ {
+ if (IsLowerThan(Value, Maximum) || !Value.HasValue)
+ validDirections = validDirections | ValidSpinDirections.Increase;
+
+ if (IsGreaterThan(Value, Minimum) || !Value.HasValue)
+ validDirections = validDirections | ValidSpinDirections.Decrease;
+ }
+
+ if (Spinner != null)
+ Spinner.ValidSpinDirection = validDirections;
+ }
+
+ #endregion
+
+ #region Constructors
+
+ static DoubleUpDown()
+ {
+ UpdateMetadata(typeof(DoubleUpDown), 1d, double.NegativeInfinity, double.PositiveInfinity);
+ }
+
+ public DoubleUpDown()
+ : this(double.Parse, decimal.ToDouble, (v1, v2) => v1 < v2, (v1, v2) => v1 > v2)
+ {
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Artemis/ColorBox/Enums.cs b/Artemis/ColorBox/Enums.cs
new file mode 100644
index 000000000..fa8599f16
--- /dev/null
+++ b/Artemis/ColorBox/Enums.cs
@@ -0,0 +1,43 @@
+/*************************************************************************************
+
+ Extended WPF Toolkit
+
+ Copyright (C) 2007-2013 Xceed Software Inc.
+
+ This program is provided to you under the terms of the Microsoft Public
+ License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
+
+ For more features, controls, and fast professional support,
+ pick up the Plus Edition at http://xceed.com/wpf_toolkit
+
+ Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
+
+ ***********************************************************************************/
+
+namespace ColorBox
+{
+ public enum SpinDirection
+ {
+ Increase,
+ Decrease
+ }
+
+
+ public enum ValidSpinDirections
+ {
+ None,
+ Increase,
+ Decrease
+ }
+
+
+ internal enum AllowedSpecialValues
+ {
+ None = 0,
+ NaN = 1,
+ PositiveInfinity = 2,
+ NegativeInfinity = 4,
+ AnyInfinity = PositiveInfinity | NegativeInfinity,
+ Any = NaN | AnyInfinity
+ }
+}
\ No newline at end of file
diff --git a/Artemis/ColorBox/GradientStopAdder.cs b/Artemis/ColorBox/GradientStopAdder.cs
new file mode 100644
index 000000000..724eb45e7
--- /dev/null
+++ b/Artemis/ColorBox/GradientStopAdder.cs
@@ -0,0 +1,82 @@
+/***************** NCore Softwares Pvt. Ltd., India **************************
+
+ ColorBox
+
+ Copyright (C) 2013 NCore Softwares Pvt. Ltd.
+
+ This program is provided to you under the terms of the Microsoft Public
+ License (Ms-PL) as published at http://colorbox.codeplex.com/license
+
+***********************************************************************************/
+
+using System;
+using System.IO;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+
+namespace ColorBox
+{
+ public class GradientStopAdder : Button
+ {
+ public static readonly DependencyProperty ColorBoxProperty =
+ DependencyProperty.Register("ColorBox", typeof(ColorBox), typeof(GradientStopAdder));
+
+ public ColorBox ColorBox
+ {
+ get { return (ColorBox) GetValue(ColorBoxProperty); }
+ set { SetValue(ColorBoxProperty, value); }
+ }
+
+ protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
+ {
+ base.OnPreviewMouseLeftButtonDown(e);
+
+ if (e.Source is GradientStopAdder && (ColorBox != null))
+ {
+ var btn = e.Source as Button;
+
+ var gs = new GradientStop();
+ gs.Offset = Mouse.GetPosition(btn).X/btn.ActualWidth;
+ //_gs.Color = this.ColorBox.Color;
+ gs.Color = GetColorFromImage(e.GetPosition(this));
+ ColorBox.Gradients.Add(gs);
+ ColorBox.SelectedGradient = gs;
+ ColorBox.Color = gs.Color;
+ ColorBox.SetBrush();
+ }
+ }
+
+ private Color GetColorFromImage(Point p)
+ {
+ try
+ {
+ var bounds = VisualTreeHelper.GetDescendantBounds(this);
+ var rtb = new RenderTargetBitmap((int) bounds.Width, (int) bounds.Height, 96, 96, PixelFormats.Default);
+ rtb.Render(this);
+
+ byte[] arr;
+ var png = new PngBitmapEncoder();
+ png.Frames.Add(BitmapFrame.Create(rtb));
+ using (var stream = new MemoryStream())
+ {
+ png.Save(stream);
+ arr = stream.ToArray();
+ }
+
+ BitmapSource bitmap = BitmapFrame.Create(new MemoryStream(arr));
+
+ var pixels = new byte[4];
+ var cb = new CroppedBitmap(bitmap, new Int32Rect((int) p.X, (int) p.Y, 1, 1));
+ cb.CopyPixels(pixels, 4, 0);
+ return Color.FromArgb(pixels[3], pixels[2], pixels[1], pixels[0]);
+ }
+ catch (Exception)
+ {
+ return ColorBox.Color;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/ColorBox/GradientStopSlider.cs b/Artemis/ColorBox/GradientStopSlider.cs
new file mode 100644
index 000000000..e94098274
--- /dev/null
+++ b/Artemis/ColorBox/GradientStopSlider.cs
@@ -0,0 +1,74 @@
+/***************** NCore Softwares Pvt. Ltd., India **************************
+
+ ColorBox
+
+ Copyright (C) 2013 NCore Softwares Pvt. Ltd.
+
+ This program is provided to you under the terms of the Microsoft Public
+ License (Ms-PL) as published at http://colorbox.codeplex.com/license
+
+***********************************************************************************/
+
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+
+namespace ColorBox
+{
+ public class GradientStopSlider : Slider
+ {
+ public static readonly DependencyProperty ColorBoxProperty =
+ DependencyProperty.Register("ColorBox", typeof(ColorBox), typeof(GradientStopSlider));
+
+ public static readonly DependencyProperty SelectedGradientProperty =
+ DependencyProperty.Register("SelectedGradient", typeof(GradientStop), typeof(GradientStopSlider));
+
+ public ColorBox ColorBox
+ {
+ get { return (ColorBox) GetValue(ColorBoxProperty); }
+ set { SetValue(ColorBoxProperty, value); }
+ }
+
+ public GradientStop SelectedGradient
+ {
+ get { return (GradientStop) GetValue(SelectedGradientProperty); }
+ set { SetValue(SelectedGradientProperty, value); }
+ }
+
+ protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
+ {
+ base.OnPreviewMouseLeftButtonDown(e);
+
+ if (ColorBox != null)
+ {
+ ColorBox.BrushSetInternally = true;
+ ColorBox.UpdateBrush = false;
+
+ ColorBox.SelectedGradient = SelectedGradient;
+ ColorBox.Color = SelectedGradient.Color;
+
+ ColorBox.UpdateBrush = true;
+ //this.ColorBox._BrushSetInternally = false;
+
+ //e.Handled = true;
+ }
+ }
+
+ protected override void OnValueChanged(double oldValue, double newValue)
+ {
+ base.OnValueChanged(oldValue, newValue);
+
+ if (ColorBox != null)
+ {
+ //this.ColorBox._HSBSetInternally = true;
+ //this.ColorBox._RGBSetInternally = true;
+ ColorBox.BrushSetInternally = true;
+ ColorBox.SetBrush();
+ ColorBox.HsbSetInternally = false;
+ //this.ColorBox._RGBSetInternally = false;
+ //this.ColorBox._BrushSetInternally = false;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/ColorBox/HueSelector.cs b/Artemis/ColorBox/HueSelector.cs
new file mode 100644
index 000000000..af802468f
--- /dev/null
+++ b/Artemis/ColorBox/HueSelector.cs
@@ -0,0 +1,138 @@
+/***************** NCore Softwares Pvt. Ltd., India **************************
+
+ ColorBox
+
+ Copyright (C) 2013 NCore Softwares Pvt. Ltd.
+
+ This program is provided to you under the terms of the Microsoft Public
+ License (Ms-PL) as published at http://colorbox.codeplex.com/license
+
+***********************************************************************************/
+
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+
+namespace ColorBox
+{
+ public class HueSelector : BaseSelector
+ {
+ public static readonly DependencyProperty HueProperty =
+ DependencyProperty.Register("Hue", typeof(double), typeof(HueSelector),
+ new FrameworkPropertyMetadata(0.0, HueChanged, HueCoerce));
+
+ public static readonly DependencyProperty HueOffsetProperty =
+ DependencyProperty.Register("HueOffset", typeof(double), typeof(HueSelector), new UIPropertyMetadata(0.0));
+
+ public double Hue
+ {
+ get { return (double) GetValue(HueProperty); }
+ set { SetValue(HueProperty, value); }
+ }
+
+
+ public double HueOffset
+ {
+ get { return (double) GetValue(HueOffsetProperty); }
+ private set { SetValue(HueOffsetProperty, value); }
+ }
+
+ public static void HueChanged(object o, DependencyPropertyChangedEventArgs e)
+ {
+ var h = (HueSelector) o;
+ h.SetHueOffset();
+ h.SetColor();
+ }
+
+ public static object HueCoerce(DependencyObject d, object brightness)
+ {
+ var v = (double) brightness;
+ if (v < 0) return 0.0;
+ if (v > 1) return 1.0;
+ return v;
+ }
+
+
+ protected override void OnMouseMove(MouseEventArgs e)
+ {
+ if (e.LeftButton == MouseButtonState.Pressed)
+ {
+ var p = e.GetPosition(this);
+
+ if (Orientation == Orientation.Vertical)
+ Hue = 1 - p.Y/ActualHeight;
+ else
+ Hue = 1 - p.X/ActualWidth;
+ }
+ base.OnMouseMove(e);
+ }
+
+ protected override void OnMouseDown(MouseButtonEventArgs e)
+ {
+ if (e.LeftButton == MouseButtonState.Pressed)
+ {
+ var p = e.GetPosition(this);
+
+ if (Orientation == Orientation.Vertical)
+ Hue = 1 - p.Y/ActualHeight;
+ else
+ Hue = 1 - p.X/ActualWidth;
+ }
+ Mouse.Capture(this);
+ base.OnMouseMove(e);
+ }
+
+ protected override void OnMouseUp(MouseButtonEventArgs e)
+ {
+ ReleaseMouseCapture();
+ base.OnMouseUp(e);
+ }
+
+ protected override void OnRender(DrawingContext dc)
+ {
+ var lb = new LinearGradientBrush();
+
+ lb.StartPoint = new Point(0, 0);
+
+ if (Orientation == Orientation.Vertical)
+ lb.EndPoint = new Point(0, 1);
+ else
+ lb.EndPoint = new Point(1, 0);
+
+ lb.GradientStops.Add(new GradientStop(Color.FromRgb(0xFF, 0x00, 0x00), 1.00));
+ lb.GradientStops.Add(new GradientStop(Color.FromRgb(0xFF, 0xFF, 0x00), 0.85));
+ lb.GradientStops.Add(new GradientStop(Color.FromRgb(0x00, 0xFF, 0x00), 0.76));
+ lb.GradientStops.Add(new GradientStop(Color.FromRgb(0x00, 0xFF, 0xFF), 0.50));
+ lb.GradientStops.Add(new GradientStop(Color.FromRgb(0x00, 0x00, 0xFF), 0.33));
+ lb.GradientStops.Add(new GradientStop(Color.FromRgb(0xFF, 0x00, 0xFF), 0.16));
+ lb.GradientStops.Add(new GradientStop(Color.FromRgb(0xFF, 0x00, 0x00), 0.00));
+
+ dc.DrawRectangle(lb, null, new Rect(0, 0, ActualWidth, ActualHeight));
+
+ SetHueOffset();
+ }
+
+ protected override Size ArrangeOverride(Size finalSize)
+ {
+ SetHueOffset();
+ return base.ArrangeOverride(finalSize);
+ }
+
+
+ private void SetHueOffset()
+ {
+ var length = ActualHeight;
+ if (Orientation == Orientation.Horizontal)
+ length = ActualWidth;
+
+ HueOffset = length - length*Hue;
+ }
+
+ private void SetColor()
+ {
+ Color = ColorHelper.ColorFromHsb(Hue, 1, 1);
+ //base.Brush = new SolidColorBrush(Color);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/ColorBox/Properties/AssemblyInfo.cs b/Artemis/ColorBox/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..ee8defc77
--- /dev/null
+++ b/Artemis/ColorBox/Properties/AssemblyInfo.cs
@@ -0,0 +1,38 @@
+/***************** NCore Softwares Pvt. Ltd., India **************************
+
+ ColorBox
+
+ Copyright (C) 2013 NCore Softwares Pvt. Ltd.
+
+ This program is provided to you under the terms of the Microsoft Public
+ License (Ms-PL) as published at http://colorbox.codeplex.com/license
+
+***********************************************************************************/
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Windows;
+using System.Windows.Markup;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("ColorBox Library")]
+[assembly:
+ AssemblyDescription(
+ "This assembly implements a solid and gradient brush picker control for Windows Presentation Foundation. ")]
+[assembly: AssemblyCompany("NCore Softwares Pvt. Ltd.")]
+[assembly: AssemblyProduct("ColorBox")]
+[assembly: AssemblyCopyright("Copyright © NCore Softwares Pvt. Ltd. 2013")]
+[assembly: ThemeInfo(ResourceDictionaryLocation.SourceAssembly, ResourceDictionaryLocation.SourceAssembly)]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+[assembly: AssemblyVersion("1.1")]
+[assembly: AssemblyFileVersion("1.1")]
+[assembly: XmlnsPrefix("http://schemas.ncore.com/wpf/xaml/colorbox", "ncore")]
+[assembly: XmlnsDefinition("http://schemas.ncore.com/wpf/xaml/colorbox", "ColorBox")]
\ No newline at end of file
diff --git a/Artemis/ColorBox/SaturationBrightnessSelector.cs b/Artemis/ColorBox/SaturationBrightnessSelector.cs
new file mode 100644
index 000000000..35be1c763
--- /dev/null
+++ b/Artemis/ColorBox/SaturationBrightnessSelector.cs
@@ -0,0 +1,189 @@
+/***************** NCore Softwares Pvt. Ltd., India **************************
+
+ ColorBox
+
+ Copyright (C) 2013 NCore Softwares Pvt. Ltd.
+
+ This program is provided to you under the terms of the Microsoft Public
+ License (Ms-PL) as published at http://colorbox.codeplex.com/license
+
+***********************************************************************************/
+
+using System.Windows;
+using System.Windows.Input;
+using System.Windows.Media;
+
+namespace ColorBox
+{
+ public class SaturationBrightnessSelector : BaseSelector
+ {
+ public static readonly DependencyProperty OffsetPaddingProperty =
+ DependencyProperty.Register("OffsetPadding", typeof(Thickness), typeof(SaturationBrightnessSelector),
+ new UIPropertyMetadata(new Thickness(0.0)));
+
+ public static readonly DependencyProperty HueProperty =
+ DependencyProperty.Register("Hue", typeof(double), typeof(SaturationBrightnessSelector), new
+ FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsRender, HueChanged));
+
+ public static readonly DependencyProperty SaturationOffsetProperty =
+ DependencyProperty.Register("SaturationOffset", typeof(double), typeof(SaturationBrightnessSelector),
+ new UIPropertyMetadata(0.0));
+
+ public static readonly DependencyProperty SaturationProperty =
+ DependencyProperty.Register("Saturation", typeof(double), typeof(SaturationBrightnessSelector),
+ new FrameworkPropertyMetadata(0.0, SaturationChanged, SaturationCoerce));
+
+ public static readonly DependencyProperty BrightnessOffsetProperty =
+ DependencyProperty.Register("BrightnessOffset", typeof(double), typeof(SaturationBrightnessSelector),
+ new UIPropertyMetadata(0.0));
+
+ public static readonly DependencyProperty BrightnessProperty =
+ DependencyProperty.Register("Brightness", typeof(double), typeof(SaturationBrightnessSelector),
+ new FrameworkPropertyMetadata(0.0, BrightnessChanged, BrightnessCoerce));
+
+ public Thickness OffsetPadding
+ {
+ get { return (Thickness) GetValue(OffsetPaddingProperty); }
+ set { SetValue(OffsetPaddingProperty, value); }
+ }
+
+
+ public double Hue
+ {
+ private get { return (double) GetValue(HueProperty); }
+ set { SetValue(HueProperty, value); }
+ }
+
+
+ public double SaturationOffset
+ {
+ get { return (double) GetValue(SaturationOffsetProperty); }
+ set { SetValue(SaturationOffsetProperty, value); }
+ }
+
+
+ public double Saturation
+ {
+ get { return (double) GetValue(SaturationProperty); }
+ set { SetValue(SaturationProperty, value); }
+ }
+
+
+ public double BrightnessOffset
+ {
+ get { return (double) GetValue(BrightnessOffsetProperty); }
+ set { SetValue(BrightnessOffsetProperty, value); }
+ }
+
+
+ public double Brightness
+ {
+ get { return (double) GetValue(BrightnessProperty); }
+ set { SetValue(BrightnessProperty, value); }
+ }
+
+ public static void HueChanged(object o, DependencyPropertyChangedEventArgs e)
+ {
+ var h = (SaturationBrightnessSelector) o;
+ h.SetColor();
+ }
+
+ public static void SaturationChanged(object o, DependencyPropertyChangedEventArgs e)
+ {
+ var h = (SaturationBrightnessSelector) o;
+ h.SetSaturationOffset();
+ }
+
+ public static object SaturationCoerce(DependencyObject d, object brightness)
+ {
+ var v = (double) brightness;
+ if (v < 0) return 0.0;
+ if (v > 1) return 1.0;
+ return v;
+ }
+
+ public static void BrightnessChanged(object o, DependencyPropertyChangedEventArgs e)
+ {
+ var h = (SaturationBrightnessSelector) o;
+ h.SetBrightnessOffset();
+ }
+
+ public static object BrightnessCoerce(DependencyObject d, object brightness)
+ {
+ var v = (double) brightness;
+ if (v < 0) return 0.0;
+ if (v > 1) return 1.0;
+ return v;
+ }
+
+
+ protected override void OnMouseMove(MouseEventArgs e)
+ {
+ if (e.LeftButton == MouseButtonState.Pressed)
+ {
+ var p = e.GetPosition(this);
+ Saturation = p.X/(ActualWidth - OffsetPadding.Right);
+ Brightness = (ActualHeight - OffsetPadding.Bottom - p.Y)/(ActualHeight - OffsetPadding.Bottom);
+ SetColor();
+ }
+ base.OnMouseMove(e);
+ }
+
+ protected override void OnMouseDown(MouseButtonEventArgs e)
+ {
+ var p = e.GetPosition(this);
+ Saturation = p.X/(ActualWidth - OffsetPadding.Right);
+ Brightness = (ActualHeight - OffsetPadding.Bottom - p.Y)/(ActualHeight - OffsetPadding.Bottom);
+ SetColor();
+
+ Mouse.Capture(this);
+ base.OnMouseDown(e);
+ }
+
+ protected override void OnMouseUp(MouseButtonEventArgs e)
+ {
+ ReleaseMouseCapture();
+ base.OnMouseUp(e);
+ }
+
+ protected override void OnRender(DrawingContext dc)
+ {
+ var h = new LinearGradientBrush();
+ h.StartPoint = new Point(0, 0);
+ h.EndPoint = new Point(1, 0);
+ h.GradientStops.Add(new GradientStop(Colors.White, 0.00));
+ h.GradientStops.Add(new GradientStop(ColorHelper.ColorFromHsb(Hue, 1, 1), 1.0));
+ dc.DrawRectangle(h, null, new Rect(0, 0, ActualWidth, ActualHeight));
+
+ var v = new LinearGradientBrush();
+ v.StartPoint = new Point(0, 0);
+ v.EndPoint = new Point(0, 1);
+ v.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0, 0, 0), 1.00));
+ v.GradientStops.Add(new GradientStop(Color.FromArgb(0x80, 0, 0, 0), 0.50));
+ v.GradientStops.Add(new GradientStop(Color.FromArgb(0x00, 0, 0, 0), 0.00));
+ dc.DrawRectangle(v, null, new Rect(0, 0, ActualWidth, ActualHeight));
+
+ SetSaturationOffset();
+ SetBrightnessOffset();
+ }
+
+ private void SetSaturationOffset()
+ {
+ SaturationOffset = OffsetPadding.Left +
+ (ActualWidth - (OffsetPadding.Right + OffsetPadding.Left))*Saturation;
+ }
+
+ private void SetBrightnessOffset()
+ {
+ BrightnessOffset = OffsetPadding.Top +
+ (ActualHeight - (OffsetPadding.Bottom + OffsetPadding.Top) -
+ (ActualHeight - (OffsetPadding.Bottom + OffsetPadding.Top))*Brightness);
+ }
+
+ public void SetColor()
+ {
+ Color = ColorHelper.ColorFromHsb(Hue, Saturation, Brightness);
+ //Brush = new SolidColorBrush(Color);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/ColorBox/SpinEventArgs .cs b/Artemis/ColorBox/SpinEventArgs .cs
new file mode 100644
index 000000000..9362a061b
--- /dev/null
+++ b/Artemis/ColorBox/SpinEventArgs .cs
@@ -0,0 +1,30 @@
+/*************************************************************************************
+
+ Extended WPF Toolkit
+
+ Copyright (C) 2007-2013 Xceed Software Inc.
+
+ This program is provided to you under the terms of the Microsoft Public
+ License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
+
+ For more features, controls, and fast professional support,
+ pick up the Plus Edition at http://xceed.com/wpf_toolkit
+
+ Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
+
+ ***********************************************************************************/
+
+using System.Windows;
+
+namespace ColorBox
+{
+ public class SpinEventArgs : RoutedEventArgs
+ {
+ public SpinEventArgs(SpinDirection direction)
+ {
+ Direction = direction;
+ }
+
+ public SpinDirection Direction { get; private set; }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/ColorBox/Spinner.cs b/Artemis/ColorBox/Spinner.cs
new file mode 100644
index 000000000..5ee76a95c
--- /dev/null
+++ b/Artemis/ColorBox/Spinner.cs
@@ -0,0 +1,56 @@
+/*************************************************************************************
+
+ Extended WPF Toolkit
+
+ Copyright (C) 2007-2013 Xceed Software Inc.
+
+ This program is provided to you under the terms of the Microsoft Public
+ License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
+
+ For more features, controls, and fast professional support,
+ pick up the Plus Edition at http://xceed.com/wpf_toolkit
+
+ Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
+
+ ***********************************************************************************/
+
+using System;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace ColorBox
+{
+ public class Spinner : ContentControl
+ {
+ public static readonly DependencyProperty ValidSpinDirectionProperty =
+ DependencyProperty.Register("ValidSpinDirection", typeof(ValidSpinDirections), typeof(Spinner),
+ new PropertyMetadata(ValidSpinDirections.Increase | ValidSpinDirections.Decrease,
+ OnValidSpinDirectionPropertyChanged));
+
+ static Spinner()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(Spinner), new FrameworkPropertyMetadata(typeof(Spinner)));
+ }
+
+ public ValidSpinDirections ValidSpinDirection
+ {
+ get { return (ValidSpinDirections) GetValue(ValidSpinDirectionProperty); }
+ set { SetValue(ValidSpinDirectionProperty, value); }
+ }
+
+ public static void OnValidSpinDirectionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ var oldvalue = (ValidSpinDirections) e.OldValue;
+ var newvalue = (ValidSpinDirections) e.NewValue;
+ }
+
+ public event EventHandler Spin;
+
+ public virtual void OnSpin(SpinEventArgs e)
+ {
+ var handler = Spin;
+ if (handler != null)
+ handler(this, e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/ColorBox/Themes/Generic.xaml b/Artemis/ColorBox/Themes/Generic.xaml
new file mode 100644
index 000000000..783c18c4a
--- /dev/null
+++ b/Artemis/ColorBox/Themes/Generic.xaml
@@ -0,0 +1,759 @@
+
+
+
+
+ M456.021,227.816L545.590,227.816L456.021,362.171L366.452,362.171L456.021,227.816
+ M384,289.828L384,363L457.171,363M384,363L457.171,289.828M480,267L480,310.011L435.711,267L480,267
+ F1 M 32.0034,13.0019L 35.0033,16.002L 35.0034,24.0019L 27.0033,24.002L 24.0034,21.0019L 29.5944,21.0014C 28.2209,19.4668 26.2249,18.501 24.0033,18.501C 19.8606,18.501 16.5022,21.8593 16.5022,26.002C 16.5022,28.0734 17.3418,29.9486 18.6992,31.3061L 16.2241,33.7812C 14.2332,31.7903 13.0018,29.0399 13.0018,26.0019C 13.0018,19.926 17.9274,15.0004 24.0033,15.0004C 27.1557,15.0004 29.9984,16.3263 32.0042,18.4508L 32.0034,13.0019 Z
+ F1 M 28,13L 36,13L 36,21L 33,24L 33,18.5L 24,27.5L 21.5,25L 30.5,16L 25,16L 28,13 Z M 13,18L 26,18L 23,21L 16,21L 16,33L 28,33L 28,26L 31,23L 31,36L 13,36L 13,18 Z
+ M502.672,272.601C502.672,298.366 481.785,319.252 456.021,319.252 430.257,319.252 409.370,298.366 409.370,272.601 409.370,246.837 430.257,225.950 456.021,225.950 481.785,225.950 502.672,246.837 502.672,272.601zM502.672,272.601C502.672,298.366 481.785,319.252 456.021,319.252 430.257,319.252 409.370,298.366 409.370,272.601 409.370,246.837 430.257,225.950 456.021,225.950 481.785,225.950 502.672,246.837 502.672,272.601zM470.531,272.601C470.531,280.615 464.035,287.111 456.021,287.111 448.007,287.111 441.511,280.615 441.511,272.601 441.511,264.588 448.007,258.091 456.021,258.091 464.035,258.091 470.531,264.588 470.531,272.601z
+ M384,267L384,363L480,363M384,363L459.026,286.973L438,267L479.000,267L479.000,307.000L459.026,286.973
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/ColorBox/UpDownBase.cs b/Artemis/ColorBox/UpDownBase.cs
new file mode 100644
index 000000000..72228437d
--- /dev/null
+++ b/Artemis/ColorBox/UpDownBase.cs
@@ -0,0 +1,653 @@
+/*************************************************************************************
+
+ Extended WPF Toolkit
+
+ Copyright (C) 2007-2013 Xceed Software Inc.
+
+ This program is provided to you under the terms of the Microsoft Public
+ License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
+
+ For more features, controls, and fast professional support,
+ pick up the Plus Edition at http://xceed.com/wpf_toolkit
+
+ Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
+
+ ***********************************************************************************/
+
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Input;
+
+namespace ColorBox
+{
+ [TemplatePart(Name = PartTextBox, Type = typeof(TextBox))]
+ [TemplatePart(Name = PartSpinner, Type = typeof(Spinner))]
+ public abstract class UpDownBase : Control, IValidateInput
+ {
+ #region Event Handlers
+
+ private void OnSpinnerSpin(object sender, SpinEventArgs e)
+ {
+ if (AllowSpin && !IsReadOnly)
+ OnSpin(e);
+ }
+
+ #endregion
+
+ #region Members
+
+ internal const string PartTextBox = "PART_TextBox";
+ internal const string PartSpinner = "PART_Spinner";
+ private bool _isSyncingTextAndValueProperties;
+ private bool _isTextChangedFromUi;
+
+ #endregion
+
+ #region Properties
+
+ internal Spinner Spinner { get; private set; }
+
+ internal TextBox TextBox { get; private set; }
+
+ #region CultureInfo
+
+ public static readonly DependencyProperty CultureInfoProperty = DependencyProperty.Register("CultureInfo",
+ typeof(CultureInfo), typeof(UpDownBase),
+ new UIPropertyMetadata(CultureInfo.CurrentCulture, OnCultureInfoChanged));
+
+ public CultureInfo CultureInfo
+ {
+ get { return (CultureInfo) GetValue(CultureInfoProperty); }
+ set { SetValue(CultureInfoProperty, value); }
+ }
+
+ private static void OnCultureInfoChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
+ {
+ var inputBase = o as UpDownBase;
+ if (inputBase != null)
+ inputBase.OnCultureInfoChanged((CultureInfo) e.OldValue, (CultureInfo) e.NewValue);
+ }
+
+ #endregion //CultureInfo
+
+ #region IsReadOnly
+
+ public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register("IsReadOnly",
+ typeof(bool), typeof(UpDownBase), new UIPropertyMetadata(false, OnReadOnlyChanged));
+
+ public bool IsReadOnly
+ {
+ get { return (bool) GetValue(IsReadOnlyProperty); }
+ set { SetValue(IsReadOnlyProperty, value); }
+ }
+
+ private static void OnReadOnlyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
+ {
+ var inputBase = o as UpDownBase;
+ if (inputBase != null)
+ inputBase.OnReadOnlyChanged((bool) e.OldValue, (bool) e.NewValue);
+ }
+
+ #endregion //IsReadOnly
+
+ #region Text
+
+ public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string),
+ typeof(UpDownBase),
+ new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
+ OnTextChanged, null, false, UpdateSourceTrigger.LostFocus));
+
+ public string Text
+ {
+ get { return (string) GetValue(TextProperty); }
+ set { SetValue(TextProperty, value); }
+ }
+
+ private static void OnTextChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
+ {
+ var inputBase = o as UpDownBase;
+ if (inputBase != null)
+ inputBase.OnTextChanged((string) e.OldValue, (string) e.NewValue);
+ }
+
+ #endregion //Text
+
+ #region FormatString
+
+ public static readonly DependencyProperty FormatStringProperty = DependencyProperty.Register("FormatString",
+ typeof(string), typeof(UpDownBase), new UIPropertyMetadata(string.Empty, OnFormatStringChanged));
+
+ public string FormatString
+ {
+ get { return (string) GetValue(FormatStringProperty); }
+ set { SetValue(FormatStringProperty, value); }
+ }
+
+ private static void OnFormatStringChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
+ {
+ var numericUpDown = o as UpDownBase;
+ if (numericUpDown != null)
+ numericUpDown.OnFormatStringChanged((string) e.OldValue, (string) e.NewValue);
+ }
+
+ protected virtual void OnFormatStringChanged(string oldValue, string newValue)
+ {
+ if (IsInitialized)
+ SyncTextAndValue(false, null);
+ }
+
+ #endregion //FormatString
+
+ #region Increment
+
+ public static readonly DependencyProperty IncrementProperty = DependencyProperty.Register("Increment",
+ typeof(double?), typeof(UpDownBase),
+ new PropertyMetadata(default(double), OnIncrementChanged, OnCoerceIncrement));
+
+ public double? Increment
+ {
+ get { return (double?) GetValue(IncrementProperty); }
+ set { SetValue(IncrementProperty, value); }
+ }
+
+ private static void OnIncrementChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
+ {
+ var numericUpDown = o as UpDownBase;
+ if (numericUpDown != null)
+ numericUpDown.OnIncrementChanged((double) e.OldValue, (double) e.NewValue);
+ }
+
+ protected virtual void OnIncrementChanged(double oldValue, double newValue)
+ {
+ if (IsInitialized)
+ SetValidSpinDirection();
+ }
+
+ private static object OnCoerceIncrement(DependencyObject d, object baseValue)
+ {
+ var numericUpDown = d as UpDownBase;
+ if (numericUpDown != null)
+ return numericUpDown.OnCoerceIncrement((double) baseValue);
+
+ return baseValue;
+ }
+
+ protected virtual double? OnCoerceIncrement(double? baseValue)
+ {
+ return baseValue;
+ }
+
+ #endregion
+
+ #region Maximum
+
+ public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register("Maximum",
+ typeof(double), typeof(UpDownBase),
+ new UIPropertyMetadata(default(double), OnMaximumChanged, OnCoerceMaximum));
+
+ public double Maximum
+ {
+ get { return (double) GetValue(MaximumProperty); }
+ set { SetValue(MaximumProperty, value); }
+ }
+
+ private static void OnMaximumChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
+ {
+ var numericUpDown = o as UpDownBase;
+ if (numericUpDown != null)
+ numericUpDown.OnMaximumChanged((double) e.OldValue, (double) e.NewValue);
+ }
+
+ protected virtual void OnMaximumChanged(double oldValue, double newValue)
+ {
+ if (IsInitialized)
+ SetValidSpinDirection();
+ }
+
+ private static object OnCoerceMaximum(DependencyObject d, object baseValue)
+ {
+ var numericUpDown = d as UpDownBase;
+ if (numericUpDown != null)
+ return numericUpDown.OnCoerceMaximum((double) baseValue);
+
+ return baseValue;
+ }
+
+ protected virtual double OnCoerceMaximum(double baseValue)
+ {
+ return baseValue;
+ }
+
+ #endregion //Maximum
+
+ #region Minimum
+
+ public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register("Minimum",
+ typeof(double), typeof(UpDownBase),
+ new UIPropertyMetadata(default(double), OnMinimumChanged, OnCoerceMinimum));
+
+ public double Minimum
+ {
+ get { return (double) GetValue(MinimumProperty); }
+ set { SetValue(MinimumProperty, value); }
+ }
+
+ private static void OnMinimumChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
+ {
+ var numericUpDown = o as UpDownBase;
+ if (numericUpDown != null)
+ numericUpDown.OnMinimumChanged((double) e.OldValue, (double) e.NewValue);
+ }
+
+ protected virtual void OnMinimumChanged(double oldValue, double newValue)
+ {
+ if (IsInitialized)
+ SetValidSpinDirection();
+ }
+
+ private static object OnCoerceMinimum(DependencyObject d, object baseValue)
+ {
+ var numericUpDown = d as UpDownBase;
+ if (numericUpDown != null)
+ return numericUpDown.OnCoerceMinimum((double) baseValue);
+
+ return baseValue;
+ }
+
+ protected virtual double? OnCoerceMinimum(double baseValue)
+ {
+ return baseValue;
+ }
+
+ #endregion //Minimum
+
+ #region AllowSpin
+
+ public static readonly DependencyProperty AllowSpinProperty = DependencyProperty.Register("AllowSpin",
+ typeof(bool), typeof(UpDownBase), new UIPropertyMetadata(true));
+
+ public bool AllowSpin
+ {
+ get { return (bool) GetValue(AllowSpinProperty); }
+ set { SetValue(AllowSpinProperty, value); }
+ }
+
+ #endregion //AllowSpin
+
+ #region DefaultValue
+
+ public static readonly DependencyProperty DefaultValueProperty = DependencyProperty.Register("DefaultValue",
+ typeof(double?), typeof(UpDownBase), new UIPropertyMetadata(default(double), OnDefaultValueChanged));
+
+ public double? DefaultValue
+ {
+ get { return (double?) GetValue(DefaultValueProperty); }
+ set { SetValue(DefaultValueProperty, value); }
+ }
+
+ private static void OnDefaultValueChanged(DependencyObject source, DependencyPropertyChangedEventArgs args)
+ {
+ ((UpDownBase) source).OnDefaultValueChanged((double) args.OldValue, (double) args.NewValue);
+ }
+
+ private void OnDefaultValueChanged(double oldValue, double newValue)
+ {
+ if (IsInitialized && string.IsNullOrEmpty(Text))
+ SyncTextAndValue(true, Text);
+ }
+
+ #endregion //DefaultValue
+
+ #region AllowInputSpecialValues
+
+ private static readonly DependencyProperty AllowInputSpecialValuesProperty =
+ DependencyProperty.Register("AllowInputSpecialValues", typeof(AllowedSpecialValues), typeof(UpDownBase),
+ new UIPropertyMetadata(AllowedSpecialValues.None));
+
+ private AllowedSpecialValues AllowInputSpecialValues
+ {
+ get { return (AllowedSpecialValues) GetValue(AllowInputSpecialValuesProperty); }
+ set { SetValue(AllowInputSpecialValuesProperty, value); }
+ }
+
+ #endregion //AllowInputSpecialValues
+
+ #region ParsingNumberStyle
+
+ public static readonly DependencyProperty ParsingNumberStyleProperty =
+ DependencyProperty.Register("ParsingNumberStyle", typeof(NumberStyles), typeof(UpDownBase),
+ new UIPropertyMetadata(NumberStyles.Any));
+
+ public NumberStyles ParsingNumberStyle
+ {
+ get { return (NumberStyles) GetValue(ParsingNumberStyleProperty); }
+ set { SetValue(ParsingNumberStyleProperty, value); }
+ }
+
+ #endregion
+
+ #region Value
+
+ public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double?),
+ typeof(UpDownBase),
+ new FrameworkPropertyMetadata(default(double), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
+ OnValueChanged, OnCoerceValue, false, UpdateSourceTrigger.PropertyChanged));
+
+ public double? Value
+ {
+ get { return (double?) GetValue(ValueProperty); }
+ set { SetValue(ValueProperty, value); }
+ }
+
+ private static object OnCoerceValue(DependencyObject o, object basevalue)
+ {
+ return ((UpDownBase) o).OnCoerceValue(basevalue);
+ }
+
+ protected virtual object OnCoerceValue(object newValue)
+ {
+ return newValue;
+ }
+
+ private static void OnValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
+ {
+ var upDownBase = o as UpDownBase;
+ if (upDownBase != null)
+ upDownBase.OnValueChanged((double) e.OldValue, (double) e.NewValue);
+ }
+
+ protected virtual void OnValueChanged(double oldValue, double newValue)
+ {
+ if (IsInitialized)
+ SyncTextAndValue(false, null);
+
+ SetValidSpinDirection();
+
+ var args = new RoutedPropertyChangedEventArgs