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 @@ + + + + + + + + + + + + + + \ 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 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + 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