aboutsummaryrefslogtreecommitdiff
path: root/source/ShiftUI/System.Windows.Forms.VisualStyles/VisualStyleRenderer.cs
diff options
context:
space:
mode:
authorMichael VanOverbeek <[email protected]>2016-07-25 12:57:52 -0400
committerGitHub <[email protected]>2016-07-25 12:57:52 -0400
commit46c1c31302f111a1f3ec23a70e6f3986a9aa2a27 (patch)
treef00af7ea3f6ad2641fb26fa1d310fd8b7179b39c /source/ShiftUI/System.Windows.Forms.VisualStyles/VisualStyleRenderer.cs
parentaf48e774189596b8d7a058c564a7d6d75205ca03 (diff)
parent6fa16209519896de09949a27425dff00ebf2970a (diff)
downloadshiftos-c--46c1c31302f111a1f3ec23a70e6f3986a9aa2a27.tar.gz
shiftos-c--46c1c31302f111a1f3ec23a70e6f3986a9aa2a27.tar.bz2
shiftos-c--46c1c31302f111a1f3ec23a70e6f3986a9aa2a27.zip
Merge pull request #17 from MichaelTheShifter/shiftui_integration
Shiftui integration
Diffstat (limited to 'source/ShiftUI/System.Windows.Forms.VisualStyles/VisualStyleRenderer.cs')
-rw-r--r--source/ShiftUI/System.Windows.Forms.VisualStyles/VisualStyleRenderer.cs447
1 files changed, 447 insertions, 0 deletions
diff --git a/source/ShiftUI/System.Windows.Forms.VisualStyles/VisualStyleRenderer.cs b/source/ShiftUI/System.Windows.Forms.VisualStyles/VisualStyleRenderer.cs
new file mode 100644
index 0000000..c49e213
--- /dev/null
+++ b/source/ShiftUI/System.Windows.Forms.VisualStyles/VisualStyleRenderer.cs
@@ -0,0 +1,447 @@
+//
+// VisualStyleRenderer.cs
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2006 Novell, Inc.
+//
+// Authors:
+// Jonathan Pobst ([email protected])
+//
+
+using System.Drawing;
+using System;
+
+namespace ShiftUI.VisualStyles
+{
+ public sealed class VisualStyleRenderer
+ {
+ private string class_name;
+ private int part;
+ private int state;
+ private IntPtr theme;
+ private int last_hresult = 0;
+ private ThemeHandleManager theme_handle_manager = new ThemeHandleManager ();
+
+ #region Public Constructors
+ public VisualStyleRenderer (string className, int part, int state)
+ {
+ theme_handle_manager.VisualStyleRenderer = this;
+ this.SetParameters (className, part, state);
+ }
+
+ public VisualStyleRenderer (VisualStyleElement element)
+ : this (element.ClassName, element.Part, element.State) {
+ }
+ #endregion
+
+ #region Public Properties
+ public String Class { get { return this.class_name; } }
+ public IntPtr Handle { get { return this.theme; } }
+ public int LastHResult { get { return this.last_hresult; } }
+ public int Part { get { return this.part; } }
+ public int State { get { return this.state; } }
+
+ public static bool IsSupported {
+ get {
+ if (!VisualStyleInformation.IsEnabledByUser)
+ return false;
+
+ if (Application.VisualStyleState == VisualStyleState.ClientAndNonClientAreasEnabled ||
+ Application.VisualStyleState == VisualStyleState.ClientAreaEnabled)
+ return true;
+
+ return false;
+ }
+ }
+ #endregion
+
+ #region Public Static Methods
+ public static bool IsElementDefined (VisualStyleElement element)
+ {
+ if (!IsSupported)
+ throw new InvalidOperationException ("Visual Styles are not enabled.");
+
+ if (IsElementKnownToBeSupported (element.ClassName, element.Part, element.State))
+ return true;
+
+ IntPtr theme = VisualStyles.UxThemeOpenThemeData (IntPtr.Zero, element.ClassName);
+ if (theme == IntPtr.Zero)
+ return false;
+ bool retval = VisualStyles.UxThemeIsThemePartDefined (theme, element.Part);
+ VisualStyles.UxThemeCloseThemeData (theme);
+
+ return retval;
+ }
+ #endregion
+
+ #region Public Instance Methods
+ public void DrawBackground (IDeviceContext dc, Rectangle bounds)
+ {
+ if (dc == null)
+ throw new ArgumentNullException ("dc");
+
+ last_hresult = VisualStyles.UxThemeDrawThemeBackground (theme, dc, this.part, this.state, bounds);
+ }
+
+ public void DrawBackground (IDeviceContext dc, Rectangle bounds, Rectangle clipRectangle)
+ {
+ if (dc == null)
+ throw new ArgumentNullException ("dc");
+
+ last_hresult = VisualStyles.UxThemeDrawThemeBackground (theme, dc, this.part, this.state, bounds, clipRectangle);
+ }
+
+ public Rectangle DrawEdge (IDeviceContext dc, Rectangle bounds, Edges edges, EdgeStyle style, EdgeEffects effects)
+ {
+ if (dc == null)
+ throw new ArgumentNullException ("dc");
+
+ Rectangle result;
+ last_hresult = VisualStyles.UxThemeDrawThemeEdge (theme, dc, this.part, this.state, bounds, edges, style, effects, out result);
+ return result;
+ }
+
+ public void DrawImage (Graphics g, Rectangle bounds, ImageList imageList, int imageIndex)
+ {
+ if (g == null)
+ throw new ArgumentNullException ("g");
+ if (imageIndex < 0 || imageIndex > imageList.Images.Count - 1)
+ throw new ArgumentOutOfRangeException ("imageIndex");
+ if (imageList.Images[imageIndex] == null)
+ throw new ArgumentNullException ("imageIndex");
+
+ g.DrawImage (imageList.Images[imageIndex], bounds);
+ }
+
+ public void DrawImage (Graphics g, Rectangle bounds, Image image)
+ {
+ if (g == null)
+ throw new ArgumentNullException ("g");
+ if (image == null)
+ throw new ArgumentNullException ("image");
+
+ g.DrawImage (image, bounds);
+ }
+
+ public void DrawParentBackground (IDeviceContext dc, Rectangle bounds, Widget childWidget)
+ {
+ if (dc == null)
+ throw new ArgumentNullException ("dc");
+
+ last_hresult = VisualStyles.UxThemeDrawThemeParentBackground (dc, bounds, childWidget);
+ }
+
+ public void DrawText (IDeviceContext dc, Rectangle bounds, string textToDraw, bool drawDisabled, TextFormatFlags flags)
+ {
+ if (dc == null)
+ throw new ArgumentNullException ("dc");
+
+ last_hresult = VisualStyles.UxThemeDrawThemeText (theme, dc, this.part, this.state, textToDraw, flags, bounds);
+ }
+
+ public void DrawText (IDeviceContext dc, Rectangle bounds, string textToDraw, bool drawDisabled)
+ {
+ this.DrawText (dc, bounds, textToDraw, drawDisabled, TextFormatFlags.Default);
+ }
+
+ public void DrawText (IDeviceContext dc, Rectangle bounds, string textToDraw)
+ {
+ this.DrawText (dc, bounds, textToDraw, false, TextFormatFlags.Default);
+ }
+
+ public Rectangle GetBackgroundContentRectangle (IDeviceContext dc, Rectangle bounds)
+ {
+ if (dc == null)
+ throw new ArgumentNullException ("dc");
+
+ Rectangle result;
+ last_hresult = VisualStyles.UxThemeGetThemeBackgroundContentRect (theme, dc, this.part, this.state, bounds, out result);
+ return result;
+ }
+
+ public Rectangle GetBackgroundExtent (IDeviceContext dc, Rectangle contentBounds)
+ {
+ if (dc == null)
+ throw new ArgumentNullException ("dc");
+
+ Rectangle result;
+ last_hresult = VisualStyles.UxThemeGetThemeBackgroundExtent (theme, dc, this.part, this.state, contentBounds, out result);
+ return result;
+ }
+
+ [System.Security.SuppressUnmanagedCodeSecurity]
+ public Region GetBackgroundRegion (IDeviceContext dc, Rectangle bounds)
+ {
+ if (dc == null)
+ throw new ArgumentNullException ("dc");
+
+ Region result;
+ last_hresult = VisualStyles.UxThemeGetThemeBackgroundRegion (theme, dc, this.part, this.state, bounds, out result);
+ return result;
+ }
+
+ public bool GetBoolean (BooleanProperty prop)
+ {
+ if (!Enum.IsDefined (typeof (BooleanProperty), prop))
+ throw new System.ComponentModel.InvalidEnumArgumentException ("prop", (int)prop, typeof (BooleanProperty));
+
+ bool result;
+ last_hresult = VisualStyles.UxThemeGetThemeBool (theme, this.part, this.state, prop, out result);
+ return result;
+ }
+
+ public Color GetColor (ColorProperty prop)
+ {
+ if (!Enum.IsDefined (typeof (ColorProperty), prop))
+ throw new System.ComponentModel.InvalidEnumArgumentException ("prop", (int)prop, typeof (ColorProperty));
+
+ Color result;
+ last_hresult = VisualStyles.UxThemeGetThemeColor (theme, this.part, this.state, prop, out result);
+ return result;
+ }
+
+ public int GetEnumValue (EnumProperty prop)
+ {
+ if (!Enum.IsDefined (typeof (EnumProperty), prop))
+ throw new System.ComponentModel.InvalidEnumArgumentException ("prop", (int)prop, typeof (EnumProperty));
+
+ int result;
+ last_hresult = VisualStyles.UxThemeGetThemeEnumValue (theme, this.part, this.state, prop, out result);
+ return result;
+ }
+
+ public string GetFilename (FilenameProperty prop)
+ {
+ if (!Enum.IsDefined (typeof (FilenameProperty), prop))
+ throw new System.ComponentModel.InvalidEnumArgumentException ("prop", (int)prop, typeof (FilenameProperty));
+
+ string result;
+ last_hresult = VisualStyles.UxThemeGetThemeFilename (theme, this.part, this.state, prop, out result);
+ return result;
+
+ }
+
+ [MonoTODO(@"I can't get MS's to return anything but null, so I can't really get this one right")]
+ public Font GetFont (IDeviceContext dc, FontProperty prop)
+ {
+ throw new NotImplementedException();
+ //if (dc == null)
+ // throw new ArgumentNullException ("dc");
+ //if (!Enum.IsDefined (typeof (FontProperty), prop))
+ // throw new System.ComponentModel.InvalidEnumArgumentException ("prop", (int)prop, typeof (FontProperty));
+
+ //UXTheme.LOGFONT lf = new UXTheme.LOGFONT();
+
+ //UXTheme.GetThemeFont (theme, dc.GetHdc (), this.part, this.state, (int)prop, out lf);
+ //IntPtr fontPtr = UXTheme.CreateFontIndirect(lf);
+ //dc.ReleaseHdc();
+
+ //return Font.FromLogFont(lf);
+ //return null;
+ }
+
+ public int GetInteger (IntegerProperty prop)
+ {
+ if (!Enum.IsDefined (typeof (IntegerProperty), prop))
+ throw new System.ComponentModel.InvalidEnumArgumentException ("prop", (int)prop, typeof (IntegerProperty));
+
+ int result;
+ last_hresult = VisualStyles.UxThemeGetThemeInt (theme, this.part, this.state, prop, out result);
+ return result;
+ }
+
+ [MonoTODO(@"MS's causes a PInvokeStackUnbalance on me, so this is not verified against MS.")]
+ public Padding GetMargins (IDeviceContext dc, MarginProperty prop)
+ {
+ if (dc == null)
+ throw new ArgumentNullException ("dc");
+ if (!Enum.IsDefined (typeof (MarginProperty), prop))
+ throw new System.ComponentModel.InvalidEnumArgumentException ("prop", (int)prop, typeof (MarginProperty));
+
+ Padding result;
+ last_hresult = VisualStyles.UxThemeGetThemeMargins (theme, dc, this.part, this.state, prop, out result);
+ return result;
+ }
+
+ public Size GetPartSize (IDeviceContext dc, Rectangle bounds, ThemeSizeType type)
+ {
+ if (dc == null)
+ throw new ArgumentNullException ("dc");
+ if (!Enum.IsDefined (typeof (ThemeSizeType), type))
+ throw new System.ComponentModel.InvalidEnumArgumentException ("prop", (int)type, typeof (ThemeSizeType));
+
+ Size result;
+ last_hresult = VisualStyles.UxThemeGetThemePartSize (theme, dc, this.part, this.state, bounds, type, out result);
+ return result;
+ }
+
+ public Size GetPartSize (IDeviceContext dc, ThemeSizeType type)
+ {
+ if (dc == null)
+ throw new ArgumentNullException ("dc");
+ if (!Enum.IsDefined (typeof (ThemeSizeType), type))
+ throw new System.ComponentModel.InvalidEnumArgumentException ("prop", (int)type, typeof (ThemeSizeType));
+
+ Size result;
+ last_hresult = VisualStyles.UxThemeGetThemePartSize (theme, dc, this.part, this.state, type, out result);
+ return result;
+ }
+
+ public Point GetPoint (PointProperty prop)
+ {
+ if (!Enum.IsDefined (typeof (PointProperty), prop))
+ throw new System.ComponentModel.InvalidEnumArgumentException ("prop", (int)prop, typeof (PointProperty));
+
+ Point result;
+ last_hresult = VisualStyles.UxThemeGetThemePosition (theme, this.part, this.state, prop, out result);
+ return result;
+ }
+
+ [MonoTODO(@"Can't find any values that return anything on MS to test against")]
+ public string GetString (StringProperty prop)
+ {
+ if (!Enum.IsDefined (typeof (StringProperty), prop))
+ throw new System.ComponentModel.InvalidEnumArgumentException ("prop", (int)prop, typeof (StringProperty));
+
+ string result;
+ last_hresult = VisualStyles.UxThemeGetThemeString (theme, this.part, this.state, prop, out result);
+ return result;
+ }
+
+ public Rectangle GetTextExtent (IDeviceContext dc, Rectangle bounds, string textToDraw, TextFormatFlags flags)
+ {
+ if (dc == null)
+ throw new ArgumentNullException ("dc");
+
+ Rectangle result;
+ last_hresult = VisualStyles.UxThemeGetThemeTextExtent (theme, dc, this.part, this.state, textToDraw, flags, bounds, out result);
+ return result;
+ }
+
+ public Rectangle GetTextExtent (IDeviceContext dc, string textToDraw, TextFormatFlags flags)
+ {
+ if (dc == null)
+ throw new ArgumentNullException ("dc");
+
+ Rectangle result;
+ last_hresult = VisualStyles.UxThemeGetThemeTextExtent (theme, dc, this.part, this.state, textToDraw, flags, out result);
+ return result;
+ }
+
+ public TextMetrics GetTextMetrics (IDeviceContext dc)
+ {
+ if (dc == null)
+ throw new ArgumentNullException ("dc", "dc cannot be null.");
+
+ TextMetrics result;
+ last_hresult = VisualStyles.UxThemeGetThemeTextMetrics (theme, dc, this.part, this.state, out result);
+ return result;
+ }
+
+ public HitTestCode HitTestBackground (IDeviceContext dc, Rectangle backgroundRectangle, IntPtr hRgn, Point pt, HitTestOptions options)
+ {
+ if (dc == null)
+ throw new ArgumentNullException ("dc");
+
+ HitTestCode result;
+ last_hresult = VisualStyles.UxThemeHitTestThemeBackground(theme, dc, this.part, this.state, options, backgroundRectangle, hRgn, pt, out result);
+ return result;
+ }
+
+ public HitTestCode HitTestBackground (Graphics g, Rectangle backgroundRectangle, Region region, Point pt, HitTestOptions options)
+ {
+ if (g == null)
+ throw new ArgumentNullException ("g");
+
+ IntPtr hRgn = region.GetHrgn(g);
+
+ return this.HitTestBackground(g, backgroundRectangle, hRgn, pt, options);
+ }
+
+ public HitTestCode HitTestBackground (IDeviceContext dc, Rectangle backgroundRectangle, Point pt, HitTestOptions options)
+ {
+ return this.HitTestBackground (dc, backgroundRectangle, IntPtr.Zero, pt, options);
+ }
+
+ public bool IsBackgroundPartiallyTransparent ()
+ {
+ return VisualStyles.UxThemeIsThemeBackgroundPartiallyTransparent (theme, this.part, this.state);
+ }
+
+ public void SetParameters (string className, int part, int state)
+ {
+ if (theme != IntPtr.Zero)
+ last_hresult = VisualStyles.UxThemeCloseThemeData (theme);
+
+ if (!IsSupported)
+ throw new InvalidOperationException ("Visual Styles are not enabled.");
+
+ this.class_name = className;
+ this.part = part;
+ this.state = state;
+ theme = VisualStyles.UxThemeOpenThemeData (IntPtr.Zero, this.class_name);
+
+ if (IsElementKnownToBeSupported (className, part, state))
+ return;
+ if (theme == IntPtr.Zero || !VisualStyles.UxThemeIsThemePartDefined (theme, this.part))
+ throw new ArgumentException ("This element is not supported by the current visual style.");
+ }
+
+ public void SetParameters (VisualStyleElement element)
+ {
+ this.SetParameters (element.ClassName, element.Part, element.State);
+ }
+ #endregion
+
+ #region Private Properties
+ internal static IVisualStyles VisualStyles {
+ get { return VisualStylesEngine.Instance; }
+ }
+ #endregion
+
+ #region Private Instance Methods
+ internal void DrawBackgroundExcludingArea (IDeviceContext dc, Rectangle bounds, Rectangle excludedArea)
+ {
+ VisualStyles.VisualStyleRendererDrawBackgroundExcludingArea (theme, dc, part, state, bounds, excludedArea);
+ }
+ #endregion
+
+ #region Private Static Methods
+ private static bool IsElementKnownToBeSupported (string className, int part, int state)
+ {
+ return className == "STATUS" && part == 0 && state == 0;
+ }
+ #endregion
+
+ #region Private Classes
+ private class ThemeHandleManager
+ {
+ public VisualStyleRenderer VisualStyleRenderer;
+ ~ThemeHandleManager ()
+ {
+ if (VisualStyleRenderer.theme == IntPtr.Zero)
+ return;
+ VisualStyles.UxThemeCloseThemeData (VisualStyleRenderer.theme);
+ }
+ }
+ #endregion
+ }
+}