diff --git a/Arge.API.Skin/Arge.API.Skin.csproj b/Arge.API.Skin/Arge.API.Skin.csproj
deleted file mode 100644
index 1151613..0000000
--- a/Arge.API.Skin/Arge.API.Skin.csproj
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- {30BAC2D7-4FB2-4464-A573-00DC9F211AFE}
- Library
- Properties
- Arge.API.Skin
- Arge.API.Skin
- v4.5
- 512
-
-
- true
- full
- false
- ..\bin\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- ..\bin\
- TRACE
- prompt
- 4
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Arge.API.Skin/Arge.API.Skin.csproj.DotSettings b/Arge.API.Skin/Arge.API.Skin.csproj.DotSettings
deleted file mode 100644
index d44b148..0000000
--- a/Arge.API.Skin/Arge.API.Skin.csproj.DotSettings
+++ /dev/null
@@ -1,2 +0,0 @@
-
- True
\ No newline at end of file
diff --git a/Arge.API.Skin/Properties/AssemblyInfo.cs b/Arge.API.Skin/Properties/AssemblyInfo.cs
deleted file mode 100644
index 25918da..0000000
--- a/Arge.API.Skin/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// 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("Arge.API.Skin")]
-[assembly: AssemblyDescription("Skin-API of Arge")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Wyrez")]
-[assembly: AssemblyProduct("Arge.API.Skin")]
-[assembly: AssemblyCopyright("Copyright © Wyrez 2017")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// 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)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("30bac2d7-4fb2-4464-a573-00dc9f211afe")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Arge.sln b/Arge.sln
index 1ef95b2..c7c7851 100644
--- a/Arge.sln
+++ b/Arge.sln
@@ -7,8 +7,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Arge", "Arge\Arge.csproj",
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "API", "API", "{D786947A-A8D7-485E-9726-839655841958}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Arge.API.Skin", "Arge.API.Skin\Arge.API.Skin.csproj", "{30BAC2D7-4FB2-4464-A573-00DC9F211AFE}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -19,15 +17,8 @@ Global
{4509B24A-6B26-41B0-8B62-1C4201317692}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4509B24A-6B26-41B0-8B62-1C4201317692}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4509B24A-6B26-41B0-8B62-1C4201317692}.Release|Any CPU.Build.0 = Release|Any CPU
- {30BAC2D7-4FB2-4464-A573-00DC9F211AFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {30BAC2D7-4FB2-4464-A573-00DC9F211AFE}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {30BAC2D7-4FB2-4464-A573-00DC9F211AFE}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {30BAC2D7-4FB2-4464-A573-00DC9F211AFE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {30BAC2D7-4FB2-4464-A573-00DC9F211AFE} = {D786947A-A8D7-485E-9726-839655841958}
- EndGlobalSection
EndGlobal
diff --git a/Arge/App.xaml b/Arge/App.xaml
index 06eb21f..92036f5 100644
--- a/Arge/App.xaml
+++ b/Arge/App.xaml
@@ -1,14 +1,15 @@
+ xmlns:bootstrapper="clr-namespace:Arge.Bootstrapper"
+ xmlns:resources="clr-namespace:Arge.Resources">
+
diff --git a/Arge/Arge.csproj b/Arge/Arge.csproj
index 05dd049..2f570f6 100644
--- a/Arge/Arge.csproj
+++ b/Arge/Arge.csproj
@@ -32,6 +32,9 @@
prompt
4
+
+ Resources\ArgeBee.ico
+
..\packages\Caliburn.Micro.Core.3.0.3\lib\net45\Caliburn.Micro.dll
@@ -54,6 +57,9 @@
..\packages\Unity.4.0.1\lib\net45\Microsoft.Practices.Unity.RegistrationByConvention.dll
+
+ ..\packages\RGB.NET.Core.1.0.0\lib\net45\RGB.NET.Core.dll
+
@@ -85,8 +91,21 @@
App.xaml
Code
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
ShellView.xaml
@@ -120,12 +139,59 @@
-
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ Designer
+ Always
+
Designer
MSBuild:Compile
+
+
+
+
+
+ PreserveNewest
+
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
\ No newline at end of file
diff --git a/Arge/Attributes/FileNameAttribute.cs b/Arge/Attributes/FileNameAttribute.cs
new file mode 100644
index 0000000..0576633
--- /dev/null
+++ b/Arge/Attributes/FileNameAttribute.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace Arge.Attributes
+{
+ public class FileNameAttribute : Attribute
+ {
+ #region Properties & Fields
+
+ public string FileName { get; }
+
+ #endregion
+
+ #region Constructors
+
+ public FileNameAttribute(string fileName)
+ {
+ this.FileName = fileName;
+ }
+
+ #endregion
+ }
+}
diff --git a/Arge/Bootstrapper/ArgeBootstrapper.cs b/Arge/Bootstrapper/ArgeBootstrapper.cs
index fbc6b57..22aaef8 100644
--- a/Arge/Bootstrapper/ArgeBootstrapper.cs
+++ b/Arge/Bootstrapper/ArgeBootstrapper.cs
@@ -1,6 +1,10 @@
using System.Collections.Generic;
using System.Windows;
+using Arge.Configuration;
+using Arge.Themes;
using Arge.ViewModels;
+using Caliburn.Micro;
+using Microsoft.Practices.Unity;
namespace Arge.Bootstrapper
{
@@ -10,14 +14,19 @@ namespace Arge.Bootstrapper
protected override void RegisterTypes()
{
+ RegisterInterface();
+
+ RegisterSingleton();
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
+ Config.Instance.Load();
+ Container.Resolve().LoadTheme(Config.Instance[ConfigEntryType.Theme]);
+
Dictionary settings = new Dictionary
{
{ "Title", "Arge" },
- { "SizeToContent", SizeToContent.Manual },
{ "Width" , 1280 },
{ "Height" , 720 }
};
diff --git a/Arge/Bootstrapper/ArgeWindowManager.cs b/Arge/Bootstrapper/ArgeWindowManager.cs
new file mode 100644
index 0000000..2fdc1f4
--- /dev/null
+++ b/Arge/Bootstrapper/ArgeWindowManager.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Media.Imaging;
+using Arge.Controls;
+using Arge.Misc;
+using Caliburn.Micro;
+
+namespace Arge.Bootstrapper
+{
+ public class ArgeWindowManager : WindowManager
+ {
+ #region Methods
+
+ protected override Window EnsureWindow(object model, object view, bool isDialog)
+ {
+ Window window = view as Window;
+ if (window == null)
+ {
+ window = new BlurredDecorationWindow()
+ {
+ Content = view,
+ SizeToContent = SizeToContent.Manual,
+ Icon = new BitmapImage(new Uri("pack://application:,,,/Arge;component/Resources/ArgeBee.ico")),
+ IconCommand = new ActionCommand(() => Process.Start("http://arge.be"))
+ };
+ window.SetValue(View.IsGeneratedProperty, true);
+ Window owner = InferOwnerOf(window);
+ if (owner != null)
+ {
+ window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
+ window.Owner = owner;
+ }
+ else
+ window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
+ }
+ else
+ {
+ Window owner = InferOwnerOf(window);
+ if ((owner != null) && isDialog)
+ window.Owner = owner;
+ }
+ return window;
+ }
+
+ #endregion
+ }
+}
diff --git a/Arge/Bootstrapper/UnityBootstrapper.cs b/Arge/Bootstrapper/UnityBootstrapper.cs
index 4f52fd8..0fb62ff 100644
--- a/Arge/Bootstrapper/UnityBootstrapper.cs
+++ b/Arge/Bootstrapper/UnityBootstrapper.cs
@@ -28,8 +28,9 @@ namespace Arge.Bootstrapper
{
Container = new UnityContainer();
RegisterSingleton(Container);
- RegisterInterface();
RegisterInterface();
+
+ RegisterTypes();
}
protected abstract void RegisterTypes();
diff --git a/Arge/Configuration/Config.cs b/Arge/Configuration/Config.cs
new file mode 100644
index 0000000..a91d829
--- /dev/null
+++ b/Arge/Configuration/Config.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using Arge.Extensions;
+
+namespace Arge.Configuration
+{
+ public class Config : Dictionary
+ {
+ #region Constants
+
+ private const string DEFAULT_FILE = "arge.config";
+
+ #endregion
+
+ #region Properties & Fields
+
+ public static Config _instance;
+ public static Config Instance => _instance ?? (_instance = new Config());
+
+ private string _currentFile;
+
+ #endregion
+
+ #region Constructors
+
+ private Config()
+ {
+ Initialize();
+ }
+
+ #endregion
+
+ #region Methods
+
+ private void Initialize()
+ {
+ foreach (ConfigEntryType configEntryType in Enum.GetValues(typeof(ConfigEntryType)))
+ this[configEntryType] = configEntryType.GetAttributeOfType()?.Value as string;
+ }
+
+ public void Load(string file = null)
+ {
+ file = file ?? _currentFile ?? DEFAULT_FILE;
+ if (string.IsNullOrWhiteSpace(file)) return;
+
+ Initialize();
+
+ //TODO DarthAffe 14.05.2017: Load Config
+
+ _currentFile = file;
+ }
+
+ public void Save(string file = null)
+ {
+ file = file ?? _currentFile ?? DEFAULT_FILE;
+ if (string.IsNullOrWhiteSpace(file)) return;
+
+ //TODO DarthAffe 14.05.2017: Save Config
+
+ _currentFile = file;
+ }
+
+ public string GetEntry(ConfigEntryType entry)
+ {
+ return this[entry];
+ }
+
+ public T GetEntry(ConfigEntryType entry)
+ {
+ return (T)Convert.ChangeType(GetEntry(entry), typeof(T));
+ }
+
+ #endregion
+ }
+}
diff --git a/Arge/Configuration/ConfigEntryType.cs b/Arge/Configuration/ConfigEntryType.cs
new file mode 100644
index 0000000..7d2b4d1
--- /dev/null
+++ b/Arge/Configuration/ConfigEntryType.cs
@@ -0,0 +1,10 @@
+using System.ComponentModel;
+
+namespace Arge.Configuration
+{
+ public enum ConfigEntryType
+ {
+ [DefaultValue("Default")]
+ Theme,
+ }
+}
diff --git a/Arge/Controls/BlurredDecorationWindow.cs b/Arge/Controls/BlurredDecorationWindow.cs
new file mode 100644
index 0000000..e62203b
--- /dev/null
+++ b/Arge/Controls/BlurredDecorationWindow.cs
@@ -0,0 +1,91 @@
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+
+namespace Arge.Controls
+{
+ [TemplatePart(Name = "PART_Decoration", Type = typeof(FrameworkElement))]
+ [TemplatePart(Name = "PART_Content", Type = typeof(FrameworkElement))]
+ [TemplatePart(Name = "PART_CloseButton", Type = typeof(Button))]
+ [TemplatePart(Name = "PART_MinimizeButton", Type = typeof(Button))]
+ [TemplatePart(Name = "PART_IconButton", Type = typeof(Button))]
+ public class BlurredDecorationWindow : Window
+ {
+ #region DependencyProperties
+ // ReSharper disable InconsistentNaming
+
+ public static readonly DependencyProperty BackgroundImageProperty = DependencyProperty.Register(
+ "BackgroundImage", typeof(ImageSource), typeof(BlurredDecorationWindow), new PropertyMetadata(default(ImageSource)));
+
+ public ImageSource BackgroundImage
+ {
+ get => (ImageSource)GetValue(BackgroundImageProperty);
+ set => SetValue(BackgroundImageProperty, value);
+ }
+
+ public static readonly DependencyProperty DecorationHeightProperty = DependencyProperty.Register(
+ "DecorationHeight", typeof(double), typeof(BlurredDecorationWindow), new PropertyMetadata(20.0));
+
+ public double DecorationHeight
+ {
+ get => (double)GetValue(DecorationHeightProperty);
+ set => SetValue(DecorationHeightProperty, value);
+ }
+
+ public static readonly DependencyProperty IconToolTipProperty = DependencyProperty.Register(
+ "IconToolTip", typeof(string), typeof(BlurredDecorationWindow), new PropertyMetadata(default(string)));
+
+ public string IconToolTip
+ {
+ get => (string)GetValue(IconToolTipProperty);
+ set => SetValue(IconToolTipProperty, value);
+ }
+
+ public static readonly DependencyProperty IconCommandProperty = DependencyProperty.Register(
+ "IconCommand", typeof(ICommand), typeof(BlurredDecorationWindow), new PropertyMetadata(default(ICommand)));
+
+ public ICommand IconCommand
+ {
+ get => (ICommand)GetValue(IconCommandProperty);
+ set => SetValue(IconCommandProperty, value);
+ }
+
+ // ReSharper restore InconsistentNaming
+ #endregion
+
+ #region Constructors
+
+ static BlurredDecorationWindow()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(BlurredDecorationWindow), new FrameworkPropertyMetadata(typeof(BlurredDecorationWindow)));
+ }
+
+ #endregion
+
+ #region Methods
+
+ public override void OnApplyTemplate()
+ {
+ base.OnApplyTemplate();
+
+ FrameworkElement decoration = GetTemplateChild("PART_Decoration") as FrameworkElement;
+ if (decoration != null)
+ decoration.MouseLeftButtonDown += (sender, args) => DragMove();
+
+ Button closeButton = GetTemplateChild("PART_CloseButton") as Button;
+ if (closeButton != null)
+ closeButton.Click += (sender, args) => Application.Current.Shutdown();
+
+ Button minimizeButton = GetTemplateChild("PART_MinimizeButton") as Button;
+ if (minimizeButton != null)
+ minimizeButton.Click += (sender, args) => Application.Current.MainWindow.WindowState = WindowState.Minimized;
+
+ Button iconButton = GetTemplateChild("PART_IconButton") as Button;
+ if (iconButton != null)
+ iconButton.Click += (sender, args) => IconCommand?.Execute(null);
+ }
+
+ #endregion
+ }
+}
diff --git a/Arge/Controls/ImageButton.cs b/Arge/Controls/ImageButton.cs
new file mode 100644
index 0000000..f36ba21
--- /dev/null
+++ b/Arge/Controls/ImageButton.cs
@@ -0,0 +1,51 @@
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+
+namespace Arge.Controls
+{
+ public class ImageButton : Button
+ {
+ #region Properties & Fields
+ // ReSharper disable InconsistentNaming
+
+ public static readonly DependencyProperty ImageProperty = DependencyProperty.Register(
+ "Image", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(default(ImageSource)));
+
+ public ImageSource Image
+ {
+ get => (ImageSource)GetValue(ImageProperty);
+ set => SetValue(ImageProperty, value);
+ }
+
+ public static readonly DependencyProperty HoverImageProperty = DependencyProperty.Register(
+ "HoverImage", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(default(ImageSource)));
+
+ public ImageSource HoverImage
+ {
+ get => (ImageSource)GetValue(HoverImageProperty);
+ set => SetValue(HoverImageProperty, value);
+ }
+
+ public static readonly DependencyProperty PressedImageProperty = DependencyProperty.Register(
+ "PressedImage", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(default(ImageSource)));
+
+ public ImageSource PressedImage
+ {
+ get => (ImageSource)GetValue(PressedImageProperty);
+ set => SetValue(PressedImageProperty, value);
+ }
+
+ // ReSharper restore InconsistentNaming
+ #endregion
+
+ #region Constructors
+
+ static ImageButton()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
+ }
+
+ #endregion
+ }
+}
diff --git a/Arge/Converter/Converter.xaml b/Arge/Converter/Converter.xaml
new file mode 100644
index 0000000..5bfd0e1
--- /dev/null
+++ b/Arge/Converter/Converter.xaml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/Arge/Extensions/EnumExtension.cs b/Arge/Extensions/EnumExtension.cs
new file mode 100644
index 0000000..70179f6
--- /dev/null
+++ b/Arge/Extensions/EnumExtension.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Linq;
+using System.Reflection;
+
+namespace Arge.Extensions
+{
+ public static class EnumExtension
+ {
+ #region Methods
+
+ public static T GetAttributeOfType(this Enum enumVal) where T : Attribute
+ {
+ MemberInfo[] mi = enumVal.GetType().GetMember(enumVal.ToString());
+ return (T)mi[0].GetCustomAttributes(typeof(T), true).FirstOrDefault();
+ }
+
+ #endregion
+ }
+}
diff --git a/Arge/ViewModels/AbstractViewModel.cs b/Arge/Misc/AbstractBindable.cs
similarity index 95%
rename from Arge/ViewModels/AbstractViewModel.cs
rename to Arge/Misc/AbstractBindable.cs
index c2dab7c..f6d25c3 100644
--- a/Arge/ViewModels/AbstractViewModel.cs
+++ b/Arge/Misc/AbstractBindable.cs
@@ -1,9 +1,9 @@
using System.Runtime.CompilerServices;
using Caliburn.Micro;
-namespace Arge.ViewModels
+namespace Arge.Misc
{
- public abstract class AbstractViewModel : PropertyChangedBase
+ public abstract class AbstractBindable : PropertyChangedBase
{
#region Method
diff --git a/Arge/Misc/ActionCommand.cs b/Arge/Misc/ActionCommand.cs
new file mode 100644
index 0000000..45ca310
--- /dev/null
+++ b/Arge/Misc/ActionCommand.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Windows.Input;
+
+namespace Arge.Misc
+{
+ public class ActionCommand : ICommand
+ {
+ #region Properties & Fields
+
+ private readonly Func _canExecute;
+ private readonly Action _command;
+
+ #endregion
+
+ #region Constructors
+
+ public ActionCommand(Action command, Func canExecute = null)
+ {
+ this._command = command;
+ this._canExecute = canExecute;
+ }
+
+ #endregion
+
+ #region Methods
+
+ public bool CanExecute(object parameter)
+ {
+ return _canExecute?.Invoke() ?? true;
+ }
+
+ public void Execute(object parameter)
+ {
+ _command?.Invoke();
+ }
+
+ public void RaiseCanExecuteChanged()
+ {
+ CanExecuteChanged?.Invoke(this, new EventArgs());
+ }
+
+ #endregion
+
+ #region Events
+
+ public event EventHandler CanExecuteChanged;
+
+ #endregion
+ }
+}
diff --git a/Arge/Misc/BindingProxy.cs b/Arge/Misc/BindingProxy.cs
new file mode 100644
index 0000000..fe63b43
--- /dev/null
+++ b/Arge/Misc/BindingProxy.cs
@@ -0,0 +1,28 @@
+using System.Windows;
+
+namespace Arge.Misc
+{
+ public class BindingProxy : Freezable
+ {
+ #region Properties & Fields
+ // ReSharper disable InconsistentNaming
+
+ public static readonly DependencyProperty DataProperty = DependencyProperty.Register(
+ "Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
+
+ public object Data
+ {
+ get => GetValue(DataProperty);
+ set => SetValue(DataProperty, value);
+ }
+
+ // ReSharper restore InconsistentNaming
+ #endregion
+
+ #region Methods
+
+ protected override Freezable CreateInstanceCore() => new BindingProxy();
+
+ #endregion
+ }
+}
diff --git a/Arge/Resources/Arge.xaml b/Arge/Resources/Arge.xaml
new file mode 100644
index 0000000..9c58a17
--- /dev/null
+++ b/Arge/Resources/Arge.xaml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Arge/Resources/ArgeBee.ico b/Arge/Resources/ArgeBee.ico
new file mode 100644
index 0000000..22c8e97
Binary files /dev/null and b/Arge/Resources/ArgeBee.ico differ
diff --git a/Arge.API.Skin/Resources/CachedResourceDictionary.cs b/Arge/Resources/CachedResourceDictionary.cs
similarity index 98%
rename from Arge.API.Skin/Resources/CachedResourceDictionary.cs
rename to Arge/Resources/CachedResourceDictionary.cs
index 658a58a..2f253f1 100644
--- a/Arge.API.Skin/Resources/CachedResourceDictionary.cs
+++ b/Arge/Resources/CachedResourceDictionary.cs
@@ -3,7 +3,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Windows;
-namespace Arge.API.Skin
+namespace Arge.Resources
{
public class CachedResourceDictionary : ResourceDictionary
{
diff --git a/Arge/Resources/ImageSources.cs b/Arge/Resources/ImageSources.cs
new file mode 100644
index 0000000..b476366
--- /dev/null
+++ b/Arge/Resources/ImageSources.cs
@@ -0,0 +1,61 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Windows.Media;
+using Arge.Attributes;
+using Arge.Misc;
+
+namespace Arge.Resources
+{
+ public class ImageSources : AbstractBindable
+ {
+ #region Properties & Fields
+
+ private static ImageSources _instace;
+ public static ImageSources Instance => _instace ?? (_instace = new ImageSources());
+
+ private readonly ImageSourceConverter _imageSourceConverter = new ImageSourceConverter();
+
+ [FileName("background")]
+ public ImageSource WindowBackground { get; private set; }
+
+ [FileName("close")]
+ public ImageSource WindowClose { get; private set; }
+
+ [FileName("minimize")]
+ public ImageSource WindowMinimize { get; private set; }
+
+ #endregion
+
+ #region Constructors
+
+ private ImageSources()
+ { }
+
+ #endregion
+
+ #region Methods
+
+ public void Update(string baseDirectory)
+ {
+ string[] files = Directory.GetFiles(baseDirectory);
+
+ foreach (PropertyInfo propertyInfo in typeof(ImageSources).GetProperties())
+ {
+ string fileName = propertyInfo.GetCustomAttribute()?.FileName;
+ if (string.IsNullOrWhiteSpace(fileName)) continue;
+
+ propertyInfo.SetValue(this, ConvertToImageSource(files.FirstOrDefault(x => string.Equals(Path.GetFileNameWithoutExtension(x), fileName, StringComparison.OrdinalIgnoreCase))));
+ NotifyOfPropertyChange(propertyInfo.Name);
+ }
+ }
+
+ private ImageSource ConvertToImageSource(string path)
+ {
+ return string.IsNullOrWhiteSpace(path) ? null : _imageSourceConverter.ConvertFromString(path) as ImageSource;
+ }
+
+ #endregion
+ }
+}
diff --git a/Arge/Styles/BlurredDecorationWindow.xaml b/Arge/Styles/BlurredDecorationWindow.xaml
new file mode 100644
index 0000000..2a9d2f5
--- /dev/null
+++ b/Arge/Styles/BlurredDecorationWindow.xaml
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Arge/Styles/FrameworkElement.xaml b/Arge/Styles/FrameworkElement.xaml
new file mode 100644
index 0000000..ef51654
--- /dev/null
+++ b/Arge/Styles/FrameworkElement.xaml
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/Arge/Styles/ImageButton.xaml b/Arge/Styles/ImageButton.xaml
new file mode 100644
index 0000000..32b8fc9
--- /dev/null
+++ b/Arge/Styles/ImageButton.xaml
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Arge/Styles/ToolTip.xaml b/Arge/Styles/ToolTip.xaml
new file mode 100644
index 0000000..ae30986
--- /dev/null
+++ b/Arge/Styles/ToolTip.xaml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Arge/Themes/Default/Theme.xaml b/Arge/Themes/Default/Theme.xaml
new file mode 100644
index 0000000..d961af1
--- /dev/null
+++ b/Arge/Themes/Default/Theme.xaml
@@ -0,0 +1,23 @@
+
+
+
+ #FFD0D0D0
+ #111111
+ #A0111111
+ #50000000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Arge/Themes/Default/background.png b/Arge/Themes/Default/background.png
new file mode 100644
index 0000000..3ab6966
Binary files /dev/null and b/Arge/Themes/Default/background.png differ
diff --git a/Arge/Themes/Default/close.png b/Arge/Themes/Default/close.png
new file mode 100644
index 0000000..e166bd7
Binary files /dev/null and b/Arge/Themes/Default/close.png differ
diff --git a/Arge/Themes/Default/minimize.png b/Arge/Themes/Default/minimize.png
new file mode 100644
index 0000000..78910ae
Binary files /dev/null and b/Arge/Themes/Default/minimize.png differ
diff --git a/Arge/Themes/Theme.cs b/Arge/Themes/Theme.cs
new file mode 100644
index 0000000..d562654
--- /dev/null
+++ b/Arge/Themes/Theme.cs
@@ -0,0 +1,24 @@
+using Arge.Misc;
+
+namespace Arge.Themes
+{
+ public class Theme : AbstractBindable
+ {
+ #region Properties & Fields
+
+ public string Name { get; }
+ public string Path { get; }
+
+ #endregion
+
+ #region Constructors
+
+ public Theme(string name, string path)
+ {
+ this.Name = name;
+ this.Path = path;
+ }
+
+ #endregion
+ }
+}
diff --git a/Arge/Themes/ThemeManager.cs b/Arge/Themes/ThemeManager.cs
new file mode 100644
index 0000000..dd4138e
--- /dev/null
+++ b/Arge/Themes/ThemeManager.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Windows;
+using System.Windows.Markup;
+using Arge.Resources;
+using RGB.NET.Core;
+
+namespace Arge.Themes
+{
+ public class ThemeManager
+ {
+ #region Constants
+
+ private const string THEME_FOLDER = "Themes";
+ private const string THEME_FILE = "Theme.xaml";
+
+ #endregion
+
+ #region Properties & Fields
+
+ private List _availableThemes;
+ public IEnumerable AvailableThemes => _availableThemes;
+
+ public Theme CurrentTheme { get; private set; }
+
+ public string CurrentThemeFolder => CurrentTheme == null ? null : Path.Combine(PathHelper.GetAbsolutePath(THEME_FOLDER), CurrentTheme.Name);
+
+ private ResourceDictionary _currentlyLoadedDictionary;
+
+ #endregion
+
+ #region Constructors
+
+ public ThemeManager()
+ {
+ CheckAvailableThemes();
+ }
+
+ #endregion
+
+ #region Methods
+
+ public void LoadTheme(string name)
+ {
+ Theme theme = AvailableThemes.First(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase));
+ LoadTheme(theme);
+ }
+
+ public void LoadTheme(Theme theme)
+ {
+ if (theme == null) return;
+
+ ResourceDictionary themeDictionary;
+ using (FileStream fs = new FileStream(theme.Path, FileMode.Open))
+ themeDictionary = (ResourceDictionary)XamlReader.Load(fs);
+
+ if (themeDictionary == null) return;
+
+ if (_currentlyLoadedDictionary != null)
+ Application.Current.Resources.MergedDictionaries.Remove(_currentlyLoadedDictionary);
+
+ Application.Current.Resources.MergedDictionaries.Add(themeDictionary);
+ _currentlyLoadedDictionary = themeDictionary;
+
+ CurrentTheme = theme;
+
+ ImageSources.Instance.Update(CurrentThemeFolder);
+ }
+
+ public void CheckAvailableThemes()
+ {
+ _availableThemes = Directory.GetDirectories(PathHelper.GetAbsolutePath(THEME_FOLDER))
+ .Select(x => new Theme(Path.GetFileName(x), Path.Combine(x, THEME_FILE)))
+ .ToList();
+ }
+
+ #endregion
+ }
+}
diff --git a/Arge/ViewModels/ShellViewModel.cs b/Arge/ViewModels/ShellViewModel.cs
index 20d537c..6958a8a 100644
--- a/Arge/ViewModels/ShellViewModel.cs
+++ b/Arge/ViewModels/ShellViewModel.cs
@@ -1,6 +1,8 @@
-namespace Arge.ViewModels
+using Arge.Misc;
+
+namespace Arge.ViewModels
{
- public class ShellViewModel : AbstractViewModel
+ public class ShellViewModel : AbstractBindable
{
}
}
diff --git a/Arge/packages.config b/Arge/packages.config
index 6c39799..75a77de 100644
--- a/Arge/packages.config
+++ b/Arge/packages.config
@@ -3,5 +3,6 @@
+
\ No newline at end of file
diff --git a/Images/ArgeBee.svg b/Images/ArgeBee.svg
new file mode 100644
index 0000000..cc49e65
--- /dev/null
+++ b/Images/ArgeBee.svg
@@ -0,0 +1,93 @@
+
+
+
+
diff --git a/Images/Background.xcf b/Images/Background.xcf
new file mode 100644
index 0000000..99c18c5
Binary files /dev/null and b/Images/Background.xcf differ