diff --git a/RainmeterStudio.Core/Model/Property.cs b/RainmeterStudio.Core/Model/Property.cs index 64562843..ccb1ec2c 100644 --- a/RainmeterStudio.Core/Model/Property.cs +++ b/RainmeterStudio.Core/Model/Property.cs @@ -4,6 +4,7 @@ using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Text; +using System.Xml.Serialization; namespace RainmeterStudio.Core.Model { diff --git a/RainmeterStudio.Core/RainmeterStudio.Core.csproj b/RainmeterStudio.Core/RainmeterStudio.Core.csproj index 695d6818..654404fe 100644 --- a/RainmeterStudio.Core/RainmeterStudio.Core.csproj +++ b/RainmeterStudio.Core/RainmeterStudio.Core.csproj @@ -43,6 +43,7 @@ + diff --git a/RainmeterStudio.Core/RainmeterStudioPluginAttribute.cs b/RainmeterStudio.Core/RainmeterStudioPluginAttribute.cs new file mode 100644 index 00000000..2f98be5d --- /dev/null +++ b/RainmeterStudio.Core/RainmeterStudioPluginAttribute.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace RainmeterStudio.Core +{ + /// + /// The assembly will be loaded as a plug-in. + /// + /// RainmeterStudio will load assemblies with this flag as plugins. + [AttributeUsage(AttributeTargets.Assembly)] + public class RainmeterStudioPluginAttribute : Attribute + { + } +} diff --git a/RainmeterStudio/Rainmeter/DataTypes/Action.cs b/RainmeterStudio.Rainmeter/DataTypes/Action.cs similarity index 100% rename from RainmeterStudio/Rainmeter/DataTypes/Action.cs rename to RainmeterStudio.Rainmeter/DataTypes/Action.cs diff --git a/RainmeterStudio/Rainmeter/DataTypes/Bang.cs b/RainmeterStudio.Rainmeter/DataTypes/Bang.cs similarity index 100% rename from RainmeterStudio/Rainmeter/DataTypes/Bang.cs rename to RainmeterStudio.Rainmeter/DataTypes/Bang.cs diff --git a/RainmeterStudio/Rainmeter/Group.cs b/RainmeterStudio.Rainmeter/Group.cs similarity index 100% rename from RainmeterStudio/Rainmeter/Group.cs rename to RainmeterStudio.Rainmeter/Group.cs diff --git a/RainmeterStudio/Rainmeter/Measure.cs b/RainmeterStudio.Rainmeter/Measure.cs similarity index 100% rename from RainmeterStudio/Rainmeter/Measure.cs rename to RainmeterStudio.Rainmeter/Measure.cs diff --git a/RainmeterStudio/Rainmeter/Meter.cs b/RainmeterStudio.Rainmeter/Meter.cs similarity index 100% rename from RainmeterStudio/Rainmeter/Meter.cs rename to RainmeterStudio.Rainmeter/Meter.cs diff --git a/RainmeterStudio.Rainmeter/Properties/AssemblyInfo.cs b/RainmeterStudio.Rainmeter/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..32cb0e3a --- /dev/null +++ b/RainmeterStudio.Rainmeter/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +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("RainmeterStudio.Rainmeter")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RainmeterStudio.Rainmeter")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[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("8a34d129-3bf6-4218-b29f-d353ad8640c9")] + +// 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/RainmeterStudio.Rainmeter/RainmeterStudio.Rainmeter.csproj b/RainmeterStudio.Rainmeter/RainmeterStudio.Rainmeter.csproj new file mode 100644 index 00000000..2411259c --- /dev/null +++ b/RainmeterStudio.Rainmeter/RainmeterStudio.Rainmeter.csproj @@ -0,0 +1,65 @@ + + + + + Debug + AnyCPU + {C641D7F8-DDDC-4EC6-8F5E-233520290642} + Library + Properties + RainmeterStudio.Rainmeter + RainmeterStudio.Rainmeter + v4.0 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + x86 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + {1d2a4896-af31-4e82-a84f-4e218067701f} + RainmeterStudio.Core + + + + + \ No newline at end of file diff --git a/RainmeterStudio/Rainmeter/Section.cs b/RainmeterStudio.Rainmeter/Section.cs similarity index 100% rename from RainmeterStudio/Rainmeter/Section.cs rename to RainmeterStudio.Rainmeter/Section.cs diff --git a/RainmeterStudio.SkinDesigner/Properties/AssemblyInfo.cs b/RainmeterStudio.SkinDesigner/Properties/AssemblyInfo.cs index e6ec8595..2bded609 100644 --- a/RainmeterStudio.SkinDesigner/Properties/AssemblyInfo.cs +++ b/RainmeterStudio.SkinDesigner/Properties/AssemblyInfo.cs @@ -1,6 +1,7 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using RainmeterStudio.Core; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -13,6 +14,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyCopyright("Copyright © 2014")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] +[assembly: RainmeterStudioPlugin] // 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 diff --git a/RainmeterStudio.SkinDesigner/RainmeterStudio.SkinDesignerPlugin.csproj b/RainmeterStudio.SkinDesigner/RainmeterStudio.SkinDesignerPlugin.csproj index 05fba84f..b2948dbf 100644 --- a/RainmeterStudio.SkinDesigner/RainmeterStudio.SkinDesignerPlugin.csproj +++ b/RainmeterStudio.SkinDesigner/RainmeterStudio.SkinDesignerPlugin.csproj @@ -16,7 +16,7 @@ true full false - bin\Debug\Plugins\ + ..\x32-Debug\StudioPlugins\ DEBUG;TRACE prompt 4 @@ -25,7 +25,7 @@ pdbonly true - bin\Release\Plugins\ + bin\Release\StudioPlugins\ TRACE prompt 4 @@ -45,6 +45,21 @@ + + True + True + Graphics.resx + + + True + True + Icons.resx + + + True + True + Strings.resx + SkinDesignerControl.xaml @@ -53,7 +68,7 @@ - + @@ -65,8 +80,26 @@ {1d2a4896-af31-4e82-a84f-4e218067701f} RainmeterStudio.Core + False + + + + + + PublicResXFileCodeGenerator + Graphics.Designer.cs + + + PublicResXFileCodeGenerator + Icons.Designer.cs + + + PublicResXFileCodeGenerator + Strings.Designer.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + /Resources/Graphics/transparent_background.png + + \ No newline at end of file diff --git a/RainmeterStudio.SkinDesigner/Resources/Graphics/transparent_background.png b/RainmeterStudio.SkinDesigner/Resources/Graphics/transparent_background.png new file mode 100644 index 00000000..eb4b6f82 Binary files /dev/null and b/RainmeterStudio.SkinDesigner/Resources/Graphics/transparent_background.png differ diff --git a/RainmeterStudio.SkinDesigner/Resources/Icons.Designer.cs b/RainmeterStudio.SkinDesigner/Resources/Icons.Designer.cs new file mode 100644 index 00000000..d01198d6 --- /dev/null +++ b/RainmeterStudio.SkinDesigner/Resources/Icons.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34014 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace RainmeterStudio.SkinDesignerPlugin.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Icons { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Icons() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RainmeterStudio.SkinDesignerPlugin.Resources.Icons", typeof(Icons).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/RainmeterStudio.SkinDesigner/Resources/Icons.resx b/RainmeterStudio.SkinDesigner/Resources/Icons.resx new file mode 100644 index 00000000..85c90909 --- /dev/null +++ b/RainmeterStudio.SkinDesigner/Resources/Icons.resx @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/RainmeterStudio.SkinDesigner/Resources/Strings.Designer.cs b/RainmeterStudio.SkinDesigner/Resources/Strings.Designer.cs new file mode 100644 index 00000000..9e9761fc --- /dev/null +++ b/RainmeterStudio.SkinDesigner/Resources/Strings.Designer.cs @@ -0,0 +1,72 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34014 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace RainmeterStudio.SkinDesignerPlugin.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Strings { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Strings() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RainmeterStudio.SkinDesignerPlugin.Resources.Strings", typeof(Strings).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Test value. + /// + public static string Test { + get { + return ResourceManager.GetString("Test", resourceCulture); + } + } + } +} diff --git a/RainmeterStudio.SkinDesigner/Resources/Strings.resx b/RainmeterStudio.SkinDesigner/Resources/Strings.resx new file mode 100644 index 00000000..05dd1e09 --- /dev/null +++ b/RainmeterStudio.SkinDesigner/Resources/Strings.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Test value + + \ No newline at end of file diff --git a/RainmeterStudio.SkinDesigner/SkinDesigner.cs b/RainmeterStudio.SkinDesigner/SkinDesigner.cs index 8b2ca122..f7194dd0 100644 --- a/RainmeterStudio.SkinDesigner/SkinDesigner.cs +++ b/RainmeterStudio.SkinDesigner/SkinDesigner.cs @@ -5,13 +5,14 @@ using System.Text; using System.Windows; using RainmeterStudio.Core.Documents; using RainmeterStudio.Core.Model; +using RainmeterStudio.Core.Documents.DocumentEditorFeatures; namespace RainmeterStudio.SkinDesignerPlugin { /// /// Skin designer document editor /// - public class SkinDesigner : IDocumentEditor + public class SkinDesigner : IDocumentEditor //TODO: , ISelectionPropertiesProvider, IToolboxProvider, IUndoSupport { /// /// Gets the document attached to this editor instance @@ -46,6 +47,7 @@ namespace RainmeterStudio.SkinDesignerPlugin public SkinDesigner(SkinDocument document) { AttachedDocument = document; + EditorUI = new SkinDesignerControl(document); } } } diff --git a/RainmeterStudio.SkinDesigner/SkinDesignerControl.xaml b/RainmeterStudio.SkinDesigner/SkinDesignerControl.xaml index 46c16fa0..2a6d62d7 100644 --- a/RainmeterStudio.SkinDesigner/SkinDesignerControl.xaml +++ b/RainmeterStudio.SkinDesigner/SkinDesignerControl.xaml @@ -3,11 +3,23 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:r="clr-namespace:RainmeterStudio.SkinDesignerPlugin.Resources" mc:Ignorable="d" - d:DesignHeight="300" d:DesignWidth="300" + d:DesignHeight="300" d:DesignWidth="500" Title="SkinDesignerControl"> - - + + + + + + + + + + + + diff --git a/RainmeterStudio.SkinDesigner/SkinDesignerControl.xaml.cs b/RainmeterStudio.SkinDesigner/SkinDesignerControl.xaml.cs index f5a5b636..898f8f8e 100644 --- a/RainmeterStudio.SkinDesigner/SkinDesignerControl.xaml.cs +++ b/RainmeterStudio.SkinDesigner/SkinDesignerControl.xaml.cs @@ -19,7 +19,7 @@ namespace RainmeterStudio.SkinDesignerPlugin /// public partial class SkinDesignerControl : Page { - public SkinDesignerControl() + public SkinDesignerControl(SkinDocument document) { InitializeComponent(); } diff --git a/RainmeterStudio.SkinDesigner/SkinDesignerFactory.cs b/RainmeterStudio.SkinDesigner/SkinDesignerFactory.cs index 572408c3..7770bacc 100644 --- a/RainmeterStudio.SkinDesigner/SkinDesignerFactory.cs +++ b/RainmeterStudio.SkinDesigner/SkinDesignerFactory.cs @@ -21,7 +21,7 @@ namespace RainmeterStudio.SkinDesignerPlugin /// A new document editor public IDocumentEditor CreateEditor(IDocument document) { - return new SkinDesigner(document as SkinDocument); + return new SkinDesigner((SkinDocument)document); } /// @@ -31,7 +31,7 @@ namespace RainmeterStudio.SkinDesignerPlugin /// True if the editor can edit the document type public bool CanEdit(Type type) { - return (type == typeof(SkinDocument)); + return type.Equals(typeof(SkinDocument)); } } } diff --git a/RainmeterStudio.SkinDesigner/SkinTemplate.cs b/RainmeterStudio.SkinDesigner/SkinDocumentTemplate.cs similarity index 80% rename from RainmeterStudio.SkinDesigner/SkinTemplate.cs rename to RainmeterStudio.SkinDesigner/SkinDocumentTemplate.cs index 1cfd353c..720e6e56 100644 --- a/RainmeterStudio.SkinDesigner/SkinTemplate.cs +++ b/RainmeterStudio.SkinDesigner/SkinDocumentTemplate.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using RainmeterStudio.Core; using RainmeterStudio.Core.Documents; using RainmeterStudio.Core.Model; @@ -10,12 +11,13 @@ namespace RainmeterStudio.SkinDesignerPlugin /// /// Template of a skin which will be opened in the designer /// - public class SkinTemplate : DocumentTemplate + [PluginExport] + public class SkinDocumentTemplate : DocumentTemplate { /// /// Initializes this skin template /// - public SkinTemplate() + public SkinDocumentTemplate() : base("Skin", "ini") { } diff --git a/RainmeterStudio.TextEditor/Properties/AssemblyInfo.cs b/RainmeterStudio.TextEditor/Properties/AssemblyInfo.cs index f1a24cba..ae66ffaa 100644 --- a/RainmeterStudio.TextEditor/Properties/AssemblyInfo.cs +++ b/RainmeterStudio.TextEditor/Properties/AssemblyInfo.cs @@ -1,6 +1,7 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using RainmeterStudio.Core; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -13,6 +14,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyCopyright("Copyright © 2014")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] +[assembly: RainmeterStudioPlugin] // 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 diff --git a/RainmeterStudio.TextEditor/RainmeterStudio.TextEditorPlugin.csproj b/RainmeterStudio.TextEditor/RainmeterStudio.TextEditorPlugin.csproj index 5a4a9670..b7694993 100644 --- a/RainmeterStudio.TextEditor/RainmeterStudio.TextEditorPlugin.csproj +++ b/RainmeterStudio.TextEditor/RainmeterStudio.TextEditorPlugin.csproj @@ -16,7 +16,7 @@ true full false - bin\Debug\Plugins\ + ..\x32-Debug\StudioPlugins\ DEBUG;TRACE prompt 4 @@ -25,7 +25,7 @@ pdbonly true - bin\Release\Plugins\ + bin\Release\StudioPlugins\ TRACE prompt 4 @@ -58,6 +58,7 @@ {1d2a4896-af31-4e82-a84f-4e218067701f} RainmeterStudio.Core + False diff --git a/RainmeterStudio.sln b/RainmeterStudio.sln index ec30b7f5..7866c990 100644 --- a/RainmeterStudio.sln +++ b/RainmeterStudio.sln @@ -70,6 +70,11 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginWindowMessage", "Plugins\PluginWindowMessage\PluginWindowMessage.vcxproj", "{B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RainmeterStudio", "RainmeterStudio\RainmeterStudio.csproj", "{438D0136-4A27-4E4D-A617-FFACE4554236}" + ProjectSection(ProjectDependencies) = postProject + {9A644478-2F1B-4145-8B31-6F8DBD42EC38} = {9A644478-2F1B-4145-8B31-6F8DBD42EC38} + {E8BD25E9-3055-4688-9E83-ECF684EF30C6} = {E8BD25E9-3055-4688-9E83-ECF684EF30C6} + {C641D7F8-DDDC-4EC6-8F5E-233520290642} = {C641D7F8-DDDC-4EC6-8F5E-233520290642} + EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RainmeterStudio.Tests", "RainmeterStudio.Tests\RainmeterStudio.Tests.csproj", "{845F4BD4-6822-4D92-9DDB-15FD18A47E5A}" EndProject @@ -85,6 +90,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{4CCE EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RainmeterPlugins", "RainmeterPlugins", "{53D952E0-CFD2-4EFF-BAD4-5969E760EFA1}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Native", "Native", "{DBBF3BDB-60DB-4FD2-B9D6-226E63549DA2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RainmeterStudio.Rainmeter", "RainmeterStudio.Rainmeter\RainmeterStudio.Rainmeter.csproj", "{C641D7F8-DDDC-4EC6-8F5E-233520290642}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -559,15 +568,31 @@ Global {9A644478-2F1B-4145-8B31-6F8DBD42EC38}.Release|Mixed Platforms.Build.0 = Release|Any CPU {9A644478-2F1B-4145-8B31-6F8DBD42EC38}.Release|Win32.ActiveCfg = Release|Any CPU {9A644478-2F1B-4145-8B31-6F8DBD42EC38}.Release|x64.ActiveCfg = Release|Any CPU + {C641D7F8-DDDC-4EC6-8F5E-233520290642}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C641D7F8-DDDC-4EC6-8F5E-233520290642}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C641D7F8-DDDC-4EC6-8F5E-233520290642}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {C641D7F8-DDDC-4EC6-8F5E-233520290642}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {C641D7F8-DDDC-4EC6-8F5E-233520290642}.Debug|Win32.ActiveCfg = Debug|Any CPU + {C641D7F8-DDDC-4EC6-8F5E-233520290642}.Debug|x64.ActiveCfg = Debug|Any CPU + {C641D7F8-DDDC-4EC6-8F5E-233520290642}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C641D7F8-DDDC-4EC6-8F5E-233520290642}.Release|Any CPU.Build.0 = Release|Any CPU + {C641D7F8-DDDC-4EC6-8F5E-233520290642}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {C641D7F8-DDDC-4EC6-8F5E-233520290642}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {C641D7F8-DDDC-4EC6-8F5E-233520290642}.Release|Win32.ActiveCfg = Release|Any CPU + {C641D7F8-DDDC-4EC6-8F5E-233520290642}.Release|x64.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {845F4BD4-6822-4D92-9DDB-15FD18A47E5A} = {8469BE7E-BCDB-4AA8-9541-719E8BFB19A7} - {E8BD25E9-3055-4688-9E83-ECF684EF30C6} = {4CCE6052-F43E-4360-B3E2-C046C6C0D86C} - {9A644478-2F1B-4145-8B31-6F8DBD42EC38} = {4CCE6052-F43E-4360-B3E2-C046C6C0D86C} - {EE8EC522-8430-4B46-86A3-D943D77F9E4B} = {53D952E0-CFD2-4EFF-BAD4-5969E760EFA1} + {2FCFBFD2-2720-4BDD-B620-4BDD3DBB8D3D} = {DBBF3BDB-60DB-4FD2-B9D6-226E63549DA2} + {BE9D2400-7F1C-49D6-8498-5CE495491AD6} = {DBBF3BDB-60DB-4FD2-B9D6-226E63549DA2} + {BC25C5DC-AEFB-49F9-8188-3C1B8C8929E6} = {DBBF3BDB-60DB-4FD2-B9D6-226E63549DA2} + {6D61FBE9-6913-4885-A95D-1A8C0C223D82} = {DBBF3BDB-60DB-4FD2-B9D6-226E63549DA2} + {6F5D4C4A-C8C3-41DA-BF44-6D42B76464DA} = {DBBF3BDB-60DB-4FD2-B9D6-226E63549DA2} + {2D8F1DDB-6470-45A1-B95A-3E2960641314} = {DBBF3BDB-60DB-4FD2-B9D6-226E63549DA2} + {53D952E0-CFD2-4EFF-BAD4-5969E760EFA1} = {DBBF3BDB-60DB-4FD2-B9D6-226E63549DA2} + {19312085-AA51-4BD6-BE92-4B6098CCA539} = {DBBF3BDB-60DB-4FD2-B9D6-226E63549DA2} {F32FA418-8DF4-4E94-B92B-EBD502F5DC07} = {53D952E0-CFD2-4EFF-BAD4-5969E760EFA1} {64FDEE97-6B7E-40E5-A489-ECA322825BC8} = {53D952E0-CFD2-4EFF-BAD4-5969E760EFA1} {A221819D-4263-42AA-B22A-C022924842A7} = {53D952E0-CFD2-4EFF-BAD4-5969E760EFA1} @@ -589,5 +614,9 @@ Global {45A34285-56DD-4521-912B-3F884D36FA35} = {53D952E0-CFD2-4EFF-BAD4-5969E760EFA1} {6D032D6B-7656-4743-B454-3388E2921EB0} = {53D952E0-CFD2-4EFF-BAD4-5969E760EFA1} {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4} = {53D952E0-CFD2-4EFF-BAD4-5969E760EFA1} + {EE8EC522-8430-4B46-86A3-D943D77F9E4B} = {53D952E0-CFD2-4EFF-BAD4-5969E760EFA1} + {845F4BD4-6822-4D92-9DDB-15FD18A47E5A} = {8469BE7E-BCDB-4AA8-9541-719E8BFB19A7} + {9A644478-2F1B-4145-8B31-6F8DBD42EC38} = {4CCE6052-F43E-4360-B3E2-C046C6C0D86C} + {E8BD25E9-3055-4688-9E83-ECF684EF30C6} = {4CCE6052-F43E-4360-B3E2-C046C6C0D86C} EndGlobalSection EndGlobal diff --git a/RainmeterStudio/Business/DocumentManager.cs b/RainmeterStudio/Business/DocumentManager.cs index 5e9b60c8..70cc4c4b 100644 --- a/RainmeterStudio/Business/DocumentManager.cs +++ b/RainmeterStudio/Business/DocumentManager.cs @@ -47,6 +47,11 @@ namespace RainmeterStudio.Business /// public IEnumerable Storages { get { return _storages; } } + /// + /// Gets a list of document templates + /// + public IEnumerable DocumentTemplates { get { return _templates; } } + #endregion #region Private fields diff --git a/RainmeterStudio/Business/PluginManager.cs b/RainmeterStudio/Business/PluginManager.cs index f4682e03..981f49f6 100644 --- a/RainmeterStudio/Business/PluginManager.cs +++ b/RainmeterStudio/Business/PluginManager.cs @@ -4,10 +4,12 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; +using System.Resources; using System.Text; using RainmeterStudio.Core; using RainmeterStudio.Core.Documents; using RainmeterStudio.Core.Utils; +using RainmeterStudio.Resources; namespace RainmeterStudio.Business { @@ -16,31 +18,84 @@ namespace RainmeterStudio.Business /// public class PluginManager { - public delegate void RegisterMethod(object objectToRegister); + #region Private fields List _loadedPlugins = new List(); - Dictionary _registerTypes = new Dictionary(); + Dictionary _registerExportTypes = new Dictionary(); + + #endregion + + /// + /// Gets an enumerable of the loaded plugins + /// + public IEnumerable LoadedPlugins + { + get + { + return _loadedPlugins; + } + } + + /// + /// A method which registers an object that was exported by a plugin. + /// + /// Object to register + public delegate void RegisterExportHandler(object objectToRegister); + + #region Constructor + + /// + /// Initializes the plugin manager + /// public PluginManager() { } - public void AddRegisterType(Type interfaceType, RegisterMethod method) + #endregion + + /// + /// Adds a handler that registers exported objects of a specific type. + /// + /// The data type + /// Handler that does the registring + public void AddRegisterExportTypeHandler(Type interfaceType, RegisterExportHandler method) { - _registerTypes.Add(interfaceType, method); + _registerExportTypes.Add(interfaceType, method); } - public void LoadPlugins() + /// + /// Initializes the plugin manager + /// + /// This will load all the plugins from the "StudioPlugins" folder + public void Initialize() { - // Get "Plugins" folder path - var location = Assembly.GetExecutingAssembly().Location; - var pluginsPath = Path.Combine(Path.GetDirectoryName(location), "Plugins"); + // Initialize the executing assembly + InitializePlugin(Assembly.GetExecutingAssembly()); + // Load plugins from StudioPlugins folder + var location = Assembly.GetExecutingAssembly().Location; + var pluginsPath = Path.Combine(Path.GetDirectoryName(location), "StudioPlugins"); + + LoadPlugins(pluginsPath); + } + + /// + /// Loads all the plugins from the specified directory. + /// + /// Directory path + public void LoadPlugins(string pluginsPath) + { // Load all DLLs from "Plugins" folder foreach (var file in Directory.EnumerateFiles(pluginsPath, "*.dll")) LoadPlugin(file); } + /// + /// Tries to load the plugin. + /// + /// File name + /// If plugin is not loaded, the function fails silently. public void LoadPlugin(string file) { Assembly assembly = null; @@ -58,17 +113,19 @@ namespace RainmeterStudio.Business // Loaded, do initialization stuff if (assembly != null) { - _loadedPlugins.Add(assembly); - - Initialize(assembly); - - Debug.WriteLine("Loaded plugin: {0}", assembly.FullName); + // Check for the RainmeterStudioPlugin attribute + if (assembly.GetCustomAttributes(typeof(RainmeterStudioPluginAttribute), false).Count() > 0) + { + _loadedPlugins.Add(assembly); + InitializePlugin(assembly); + Debug.WriteLine("Loaded plugin: {0}", (object)assembly.Location); + } } } - private void Initialize(Assembly assembly) + private void InitializePlugin(Assembly assembly) { - // Register factories and stuff + // Register exports assembly.GetTypes() // Select only the classes @@ -80,7 +137,7 @@ namespace RainmeterStudio.Business // Perform register .ForEach((type) => { - foreach (var pair in _registerTypes) + foreach (var pair in _registerExportTypes) { if (pair.Key.IsAssignableFrom(type)) { @@ -91,13 +148,13 @@ namespace RainmeterStudio.Business } } }); - } - public IEnumerable LoadedPlugins - { - get + // Register .resource files + foreach (var resourceName in assembly.GetManifestResourceNames()) { - return _loadedPlugins; + var name = Path.GetFileNameWithoutExtension(resourceName); + ResourceManager manager = new ResourceManager(name, assembly); + ResourceProvider.RegisterManager(manager, assembly); } } } diff --git a/RainmeterStudio/MainClass.cs b/RainmeterStudio/MainClass.cs index ef750981..f0717720 100644 --- a/RainmeterStudio/MainClass.cs +++ b/RainmeterStudio/MainClass.cs @@ -31,10 +31,10 @@ namespace RainmeterStudio // Initialize plugin manager PluginManager pluginManager = new PluginManager(); - pluginManager.AddRegisterType(typeof(IDocumentStorage), obj => documentManager.RegisterStorage((IDocumentStorage)obj)); - pluginManager.AddRegisterType(typeof(DocumentTemplate), obj => documentManager.RegisterTemplate((DocumentTemplate)obj)); - pluginManager.AddRegisterType(typeof(IDocumentEditorFactory), obj => documentManager.RegisterEditorFactory((IDocumentEditorFactory)obj)); - pluginManager.LoadPlugins(); + pluginManager.AddRegisterExportTypeHandler(typeof(IDocumentStorage), obj => documentManager.RegisterStorage((IDocumentStorage)obj)); + pluginManager.AddRegisterExportTypeHandler(typeof(DocumentTemplate), obj => documentManager.RegisterTemplate((DocumentTemplate)obj)); + pluginManager.AddRegisterExportTypeHandler(typeof(IDocumentEditorFactory), obj => documentManager.RegisterEditorFactory((IDocumentEditorFactory)obj)); + pluginManager.Initialize(); // Create & run app var uiManager = new UIManager(projectManager, documentManager); diff --git a/RainmeterStudio/RainmeterStudio.csproj b/RainmeterStudio/RainmeterStudio.csproj index f8a2ca54..2ebca134 100644 --- a/RainmeterStudio/RainmeterStudio.csproj +++ b/RainmeterStudio/RainmeterStudio.csproj @@ -8,7 +8,7 @@ WinExe Properties RainmeterStudio - RainmeterEditor + RainmeterStudio v4.0 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} @@ -73,17 +73,12 @@ - - - - - - True True Icons.resx + True True diff --git a/RainmeterStudio/Resources/ResourceProvider.cs b/RainmeterStudio/Resources/ResourceProvider.cs new file mode 100644 index 00000000..8b29904c --- /dev/null +++ b/RainmeterStudio/Resources/ResourceProvider.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Resources; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace RainmeterStudio.Resources +{ + /// + /// Manages and provides resources + /// + public static class ResourceProvider + { + /// + /// Holds information about a resource manager + /// + private struct ResourceManagerInfo + { + public ResourceManager Manager; + public Assembly Assembly; + } + + private static List _resourceManagers = new List(); + private static Dictionary _cacheStrings = new Dictionary(); + private static Dictionary _cacheImages = new Dictionary(); + + /// + /// Registers a resource manager + /// + /// The resource manager + /// The assembly which will contain the non-string resources + public static void RegisterManager(ResourceManager manager, Assembly ownerAssembly) + { + _resourceManagers.Add(new ResourceManagerInfo() + { + Manager = manager, + Assembly = ownerAssembly + }); + } + + /// + /// Gets a string from the resource managers + /// + /// Identifier of the resource + /// By default, strings are cached. Setting this to true will bypass the cache. + /// If this parameter is set to true, the obtained string will be cached. + /// The string, or null if not found + public static string GetString(string key, bool bypassCache = false, bool keepInCache = true) + { + string value = null; + + // Look up in cache + if (bypassCache || !_cacheStrings.TryGetValue(key, out value)) + { + // Not found, query resource managers + foreach (var info in _resourceManagers) + { + // Try to get resource + var str = info.Manager.GetString(key); + + // Found? + if (str != null) + { + value = str; + + if (keepInCache) + _cacheStrings[key] = str; + + break; + } + } + } + + // Resource not found + return value; + } + + /// + /// Gets an image from the resource manager. + /// + /// Identifier of the resource + /// By default, images are cached. Setting this to true will bypass the cache. + /// If this parameter is set to true, the obtained image will be cached. + /// The image source, or null if not found + public static ImageSource GetImage(string key, bool bypassCache = false, bool keepInCache = true) + { + ImageSource image = null; + + // Look up in cache + if (bypassCache || !_cacheImages.TryGetValue(key, out image)) + { + // Not found, query resource managers + foreach (var info in _resourceManagers) + { + // Try to get resource + var path = info.Manager.GetString(key); + + // Found + if (path != null) + { + Uri fullPath = new Uri("/" + info.Assembly.GetName().Name + ";component" + path, UriKind.Relative); + image = new BitmapImage(fullPath); + + if (keepInCache) + _cacheImages[key] = image; + + break; + } + } + } + + // Resource not found + return image; + } + + /// + /// Clears the cache + /// + public static void ClearCache() + { + _cacheImages.Clear(); + _cacheStrings.Clear(); + } + } +} diff --git a/RainmeterStudio/UI/Controller/DocumentController.cs b/RainmeterStudio/UI/Controller/DocumentController.cs index 49b0e81d..1bc347ea 100644 --- a/RainmeterStudio/UI/Controller/DocumentController.cs +++ b/RainmeterStudio/UI/Controller/DocumentController.cs @@ -1,9 +1,12 @@ using System; +using System.Collections.Generic; using System.Windows; +using System.Linq; using RainmeterStudio.Business; using RainmeterStudio.Core.Documents; using RainmeterStudio.Core.Model.Events; using RainmeterStudio.UI.Dialogs; +using RainmeterStudio.UI.ViewModel; namespace RainmeterStudio.UI.Controller { @@ -60,7 +63,7 @@ namespace RainmeterStudio.UI.Controller public void CreateWindow(DocumentTemplate defaultFormat = null, string defaultPath = "") { // Show dialog - var dialog = new CreateDocumentDialog() + var dialog = new CreateDocumentDialog(this) { Owner = OwnerWindow, SelectedTemplate = defaultFormat, @@ -84,5 +87,15 @@ namespace RainmeterStudio.UI.Controller DocumentManager.Create(format); } + /// + /// Gets a list of document templates view models + /// + public IEnumerable DocumentTemplates + { + get + { + return DocumentManager.DocumentTemplates.Select(t => new DocumentTemplateViewModel(t)); + } + } } } diff --git a/RainmeterStudio/UI/Controller/IconProvider.cs b/RainmeterStudio/UI/Controller/IconProvider.cs index 11a0b6f3..5004ff4e 100644 --- a/RainmeterStudio/UI/Controller/IconProvider.cs +++ b/RainmeterStudio/UI/Controller/IconProvider.cs @@ -7,29 +7,30 @@ using System.Windows.Data; using System.Windows.Media; using System.Windows.Media.Imaging; using RainmeterStudio.Core.Model; +using RainmeterStudio.Resources; namespace RainmeterStudio.UI.Controller { + /// + /// Provides icons + /// public static class IconProvider { - private static Dictionary _loadedImages = new Dictionary(); - + /// + /// Gets an icon by resource name + /// + /// Resource name + /// The icon public static ImageSource GetIcon(string key) { - if (!_loadedImages.ContainsKey(key)) - { - // Try to get the icon file name - string iconPath = Resources.Icons.ResourceManager.GetString(key); - if (iconPath == null) - return null; - - // Load the image - var uri = new Uri(iconPath, UriKind.RelativeOrAbsolute); - _loadedImages.Add(key, new BitmapImage(uri)); - } - return _loadedImages[key]; + return ResourceProvider.GetImage(key); } + /// + /// Gets an icon by reference + /// + /// The reference + /// The icon public static ImageSource GetProjectItemIcon(Reference item) { // Resource name @@ -51,6 +52,9 @@ namespace RainmeterStudio.UI.Controller } } + /// + /// Icon provider converter, for use in xaml + /// public class IconProviderConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) diff --git a/RainmeterStudio/UI/Dialogs/CreateDocumentDialog.xaml b/RainmeterStudio/UI/Dialogs/CreateDocumentDialog.xaml index e28574e6..6cd39e2a 100644 --- a/RainmeterStudio/UI/Dialogs/CreateDocumentDialog.xaml +++ b/RainmeterStudio/UI/Dialogs/CreateDocumentDialog.xaml @@ -3,16 +3,29 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Create..." Height="250" Width="400" WindowStartupLocation="CenterOwner" - WindowStyle="ToolWindow" ShowInTaskbar="False"> + WindowStyle="ToolWindow" ShowInTaskbar="False" + Background="WhiteSmoke" > - + + + + + + + + + - + + + @@ -26,18 +39,9 @@ - - - - - - - - - - + @@ -49,15 +53,15 @@ Path: - + - - - - + + diff --git a/RainmeterStudio/UI/Dialogs/CreateDocumentDialog.xaml.cs b/RainmeterStudio/UI/Dialogs/CreateDocumentDialog.xaml.cs index d013a08f..2787fcae 100644 --- a/RainmeterStudio/UI/Dialogs/CreateDocumentDialog.xaml.cs +++ b/RainmeterStudio/UI/Dialogs/CreateDocumentDialog.xaml.cs @@ -13,6 +13,7 @@ using System.Windows.Media.Imaging; using System.Windows.Shapes; using RainmeterStudio.Business; using RainmeterStudio.Core.Documents; +using RainmeterStudio.UI.Controller; namespace RainmeterStudio.UI.Dialogs { @@ -21,6 +22,8 @@ namespace RainmeterStudio.UI.Dialogs /// public partial class CreateDocumentDialog : Window { + private DocumentController _documentController; + /// /// Gets or sets the currently selected file format /// @@ -54,20 +57,34 @@ namespace RainmeterStudio.UI.Dialogs /// /// Creates a new instance of CreateDocumentDialog /// - public CreateDocumentDialog() + public CreateDocumentDialog(DocumentController docCtrl) { InitializeComponent(); + _documentController = docCtrl; - PopulateFormats(); + PopulateCategories(); + RepopulateFormats(); Validate(); } - private void PopulateFormats() + private void PopulateCategories() { - //listFormats.ItemsSource = DocumentManager.Instance.DocumentFormats; + listCategories.ItemsSource = _documentController.DocumentTemplates + .Select(template => template.Category) + .Where(cat => cat != null) + .Distinct() + .Concat(new[] { "All" }); - CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(listFormats.ItemsSource); - view.GroupDescriptions.Add(new PropertyGroupDescription("Category")); + listCategories.SelectedIndex = listCategories.Items.Count - 1; + } + + private void RepopulateFormats() + { + if (Object.Equals(listCategories.SelectedItem, "All")) + listFormats.ItemsSource = _documentController.DocumentTemplates; + + else + listFormats.ItemsSource = _documentController.DocumentTemplates.Where(x => Object.Equals(x.Category, listCategories.SelectedItem)); } private void buttonCreate_Click(object sender, RoutedEventArgs e) @@ -90,5 +107,10 @@ namespace RainmeterStudio.UI.Dialogs buttonCreate.IsEnabled = res; } + + private void listCategories_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + RepopulateFormats(); + } } }