diff --git a/RainmeterStudio.Rainmeter/Meters/StringMeter.cs b/RainmeterStudio.Rainmeter/Meters/StringMeter.cs
new file mode 100644
index 00000000..b32b98ba
--- /dev/null
+++ b/RainmeterStudio.Rainmeter/Meters/StringMeter.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RainmeterStudio.Rainmeter.Meters
+{
+ public class StringMeter : Meter
+ {
+ public StringMeter()
+ : base(1)
+ {
+
+ }
+ }
+}
diff --git a/RainmeterStudio.Rainmeter/RainmeterStudio.Rainmeter.csproj b/RainmeterStudio.Rainmeter/RainmeterStudio.Rainmeter.csproj
index dd3488b9..1c936ec4 100644
--- a/RainmeterStudio.Rainmeter/RainmeterStudio.Rainmeter.csproj
+++ b/RainmeterStudio.Rainmeter/RainmeterStudio.Rainmeter.csproj
@@ -34,13 +34,16 @@
false
+
+
+
@@ -48,8 +51,10 @@
+
+
diff --git a/RainmeterStudio.Rainmeter/Skin.cs b/RainmeterStudio.Rainmeter/Skin.cs
new file mode 100644
index 00000000..f813c37d
--- /dev/null
+++ b/RainmeterStudio.Rainmeter/Skin.cs
@@ -0,0 +1,673 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media;
+using RainmeterStudio.Core.Model;
+using RainmeterStudio.Core.Utils;
+using Version = RainmeterStudio.Core.Utils.Version;
+
+namespace RainmeterStudio.Rainmeter
+{
+ ///
+ /// Skin background modes
+ ///
+ [Flags]
+ public enum SkinBackgroundMode
+ {
+ ///
+ /// Image as defined by Background
+ ///
+ Image = 0,
+
+ ///
+ /// Transparent background
+ ///
+ Transparent = 1,
+
+ ///
+ /// Fill with a solid color
+ ///
+ SolidColor = 2,
+
+ ///
+ /// Fill with gradient
+ ///
+ Gradient = 2 + 0x80,
+
+ ///
+ /// Fill by scaling image as defined by Background
+ ///
+ ScaledImage = 3,
+
+ ///
+ /// Fill by tiling image as defined by Background
+ ///
+ TiledImage = 4,
+
+ ///
+ /// Mask used when writing to INI file
+ ///
+ Mask = 0xf
+ }
+
+ ///
+ /// Skin bevel types
+ ///
+ public enum SkinBevelType
+ {
+ None = 0,
+ Raised,
+ Sunken
+ }
+
+ ///
+ /// Context menu item
+ ///
+ public struct ContextItem
+ {
+ public string Title { get; set; }
+ public DataTypes.Action Action { get; set; }
+ }
+
+ public enum BlurRegionType
+ {
+ Disabled,
+ Rectangular,
+ RectangularWithRoundedCorners,
+ Elliptical
+ }
+
+ public struct BlurRegion
+ {
+ BlurRegionType Type { get; set; }
+ Int32Rect Region { get; set; }
+ int Radius { get; set; }
+ }
+
+ ///
+ /// Rainmeter skin
+ ///
+ public class Skin : INotifyPropertyChanged
+ {
+ #region Private fields
+
+ // Metadata
+ string _name, _author, _information, _license;
+ Version _version;
+
+ // General options
+ int _update, _transitionUpdate;
+ bool _accurateText, _dynamicWindowSize, _tooltipHidden;
+ Int32Rect _dragMargins;
+ DataTypes.Action _onRefreshAction, _onUpdateAction, _onCloseAction, _onFocusAction, _onUnfocusAction, _onWakeAction;
+
+ // Background
+ Reference _background;
+ SkinBackgroundMode _backgroundMode;
+ Int32Rect _backgroundMargins;
+ Color _solidColor, _gradientColor1, _gradientColor2;
+ double _gradientAngle;
+ SkinBevelType _bevelType;
+
+ // Aero blur
+ bool _blur;
+
+ #endregion
+
+ ///
+ /// Triggered when the value of a property changes
+ ///
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ #region Properties: Metadata
+
+ ///
+ /// Gets or sets the skin's name
+ ///
+ public string Name
+ {
+ get
+ {
+ return _name;
+ }
+ set
+ {
+ _name = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("Name"));
+ }
+ }
+
+ ///
+ /// Gets or sets the skin's author
+ ///
+ public string Author
+ {
+ get
+ {
+ return _author;
+ }
+ set
+ {
+ _author = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("Author"));
+ }
+ }
+
+ ///
+ /// Gets or sets additional information about this skin
+ ///
+ public string Information
+ {
+ get
+ {
+ return _information;
+ }
+ set
+ {
+ _information = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("Information"));
+ }
+ }
+
+ ///
+ /// Gets or sets licensing information about the skin
+ ///
+ public string License
+ {
+ get
+ {
+ return _license;
+ }
+ set
+ {
+ _license = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("License"));
+ }
+ }
+
+ ///
+ /// Gets or sets licensing information about the skin
+ ///
+ public Version Version
+ {
+ get
+ {
+ return _version;
+ }
+ set
+ {
+ _version = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("Version"));
+ }
+ }
+
+ #endregion
+
+ #region Properties: Content (measures and meters)
+
+ ///
+ /// List of measures
+ ///
+ public ObservableCollection Measures { get; private set; }
+
+ ///
+ /// List of meters
+ ///
+ public ObservableCollection Meters { get; private set; }
+
+ #endregion
+
+ #region Properties: General options
+
+ ///
+ /// Gets or sets the skin's update rate
+ ///
+ public int Update
+ {
+ get
+ {
+ return _update;
+ }
+ set
+ {
+ _update = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("Update"));
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating if String meters are measured and rendered using improved
+ /// padding and character spacing similar to that provided by DiInt32Rect2D.
+ ///
+ public bool AccurateText
+ {
+ get
+ {
+ return _accurateText;
+ }
+ set
+ {
+ _accurateText = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("AccurateText"));
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating if the window size is adjusted on
+ /// each update to fit the meters
+ ///
+ public bool DynamicWindowSize
+ {
+ get
+ {
+ return _dynamicWindowSize;
+ }
+ set
+ {
+ _dynamicWindowSize = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("DynamicWindowSize"));
+ }
+ }
+
+ ///
+ /// Gets or sets the area from where the window can be dragged.
+ ///
+ public Int32Rect DragMargins
+ {
+ get
+ {
+ return _dragMargins;
+ }
+ set
+ {
+ _dragMargins = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("DragMargins"));
+ }
+ }
+
+ ///
+ /// Gets or sets the action that will be executed when the skin is loaded or refreshed.
+ ///
+ public DataTypes.Action OnRefreshAction
+ {
+ get
+ {
+ return _onRefreshAction;
+ }
+ set
+ {
+ _onRefreshAction = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("OnRefreshAction"));
+ }
+ }
+
+ ///
+ /// Gets or sets the action that will be executed on each Update of the skin.
+ ///
+ public DataTypes.Action OnUpdateAction
+ {
+ get
+ {
+ return _onUpdateAction;
+ }
+ set
+ {
+ _onUpdateAction = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("OnUpdateAction"));
+ }
+ }
+
+ ///
+ /// Gets or sets the action that will be executed when the skin is unloaded or when Rainmeter is closed.
+ ///
+ public DataTypes.Action OnCloseAction
+ {
+ get
+ {
+ return _onCloseAction;
+ }
+ set
+ {
+ _onCloseAction = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("OnCloseAction"));
+ }
+ }
+
+ ///
+ /// Gets or sets the action that will be executed when the skin recieves focus in Windows (set by clicking the mouse on the skin).
+ ///
+ public DataTypes.Action OnFocusAction
+ {
+ get
+ {
+ return _onFocusAction;
+ }
+ set
+ {
+ _onFocusAction = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("OnFocusAction"));
+ }
+ }
+
+ ///
+ /// Gets or sets the action that will be executed when the skin loses focus in Windows.
+ ///
+ public DataTypes.Action OnUnfocusAction
+ {
+ get
+ {
+ return _onUnfocusAction;
+ }
+ set
+ {
+ _onUnfocusAction = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("OnUnfocusAction"));
+ }
+ }
+
+ ///
+ /// Gets or sets the action that will be executed when Windows returns from the sleep or hibernate states.
+ ///
+ public DataTypes.Action OnWakeAction
+ {
+ get
+ {
+ return _onWakeAction;
+ }
+ set
+ {
+ _onWakeAction = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("OnWakeAction"));
+ }
+ }
+
+ ///
+ /// Gets or sets the update time in milliseconds for meter transitions.
+ ///
+ public int TransitionUpdate
+ {
+ get
+ {
+ return _transitionUpdate;
+ }
+ set
+ {
+ _transitionUpdate = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("TransitionUpdate"));
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating if all tooltips in the skin will be hidden.
+ ///
+ public bool TooltipHidden
+ {
+ get
+ {
+ return _tooltipHidden;
+ }
+ set
+ {
+ _tooltipHidden = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("TooltipHidden"));
+ }
+ }
+
+ ///
+ /// Gets or sets the groups that the skin belongs to.
+ ///
+ public ObservableCollection Groups { get; private set; }
+
+ #endregion
+
+ #region Properties: Background
+
+ ///
+ /// Gets or sets the background image.
+ ///
+ public Reference Background
+ {
+ get
+ {
+ return _background;
+ }
+ set
+ {
+ _background = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("Background"));
+ }
+ }
+
+ ///
+ /// Gets or sets the background mode for the skin.
+ ///
+ public SkinBackgroundMode BackgroundMode
+ {
+ get
+ {
+ return _backgroundMode;
+ }
+ set
+ {
+ _backgroundMode = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("BackgroundMode"));
+ }
+ }
+
+ ///
+ /// Gets or sets the margins of the Background image that are not scaled.
+ ///
+ public Int32Rect BackgroundMargins
+ {
+ get
+ {
+ return _backgroundMargins;
+ }
+ set
+ {
+ _backgroundMargins = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("BackgroundMargins"));
+ }
+ }
+
+ ///
+ /// Gets or sets the solid background color.
+ ///
+ public Color SolidColor
+ {
+ get
+ {
+ return _solidColor;
+ }
+ set
+ {
+ _solidColor = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("SolidColor"));
+ }
+ }
+
+ ///
+ /// Gets or sets the the first color of the gradient.
+ ///
+ public Color GradientColor1
+ {
+ get
+ {
+ return _gradientColor1;
+ }
+ set
+ {
+ _gradientColor1 = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("GradientColor1"));
+ }
+ }
+
+ ///
+ /// Gets or sets the second color of the gradient.
+ ///
+ public Color GradientColor2
+ {
+ get
+ {
+ return _gradientColor2;
+ }
+ set
+ {
+ _gradientColor2 = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("GradientColor2"));
+ }
+ }
+
+ ///
+ /// Gets or sets the angle of the gradient in degrees.
+ ///
+ public double GradientAngle
+ {
+ get
+ {
+ return _gradientAngle;
+ }
+ set
+ {
+ _gradientAngle = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("GradientAngle"));
+ }
+ }
+
+ ///
+ /// Gets or sets the bevel type.
+ ///
+ ///
+ /// If enabled, draws a bevel around the edges of the entire skin when BackgroundMode=2.
+ ///
+ public SkinBevelType BevelType
+ {
+ get
+ {
+ return _bevelType;
+ }
+ set
+ {
+ _bevelType = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("BevelType"));
+ }
+ }
+
+ #endregion
+
+ #region Properties: Context items
+
+ ///
+ /// Gets the context items
+ ///
+ public ObservableCollection ContextItems { get; private set; }
+
+ #endregion
+
+ #region Properties: aero blur options
+
+ ///
+ /// Gets or sets a value indicating if Aero Blur is enabled.
+ ///
+ public bool Blur
+ {
+ get
+ {
+ return _blur;
+ }
+ set
+ {
+ _blur = value;
+
+ if (PropertyChanged != null)
+ PropertyChanged(this, new PropertyChangedEventArgs("Blur"));
+ }
+ }
+
+ ///
+ /// Gets the blur regions
+ ///
+ public ObservableCollection BlurRegions { get; private set; }
+
+ #endregion
+
+ #region Variables
+
+ ///
+ /// Gets the list of variables
+ ///
+ public ObservableDictionary Variables { get; private set; }
+
+ #endregion
+
+ public Skin()
+ {
+ Measures = new ObservableCollection();
+ Meters = new ObservableCollection();
+ Groups = new ObservableCollection();
+ ContextItems = new ObservableCollection();
+ BlurRegions = new ObservableCollection();
+ Variables = new ObservableDictionary();
+
+ // Set defaults
+ Update = 1000;
+ TransitionUpdate = 100;
+ BackgroundMode = SkinBackgroundMode.Transparent;
+ }
+ }
+}