1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2004 Novell, Inc.
23 // Peter Bartok pbartok@novell.com
30 using System.Drawing.Drawing2D;
31 using System.Drawing.Imaging;
33 namespace System.Windows.Forms {
34 public sealed class ControlPaint {
35 #region Local Variables
36 static int RGBMax=255;
37 static int HLSMax=255;
38 #endregion // Local Variables
40 #region Private Enumerations
44 // Prevent a public constructor from being created
45 private ControlPaint() {
47 #endregion // Constructor
50 #endregion // Private Enumerations
53 internal static void Color2HBS(Color color, out int h, out int l, out int s) {
67 cMax = Math.Max(Math.Max(r, g), b);
68 cMin = Math.Min(Math.Min(r, g), b);
70 l = (((cMax+cMin)*HLSMax)+RGBMax)/(2*RGBMax);
72 if (cMax==cMin) { // Achromatic
80 s=(((cMax-cMin)*HLSMax)+((cMax+cMin)/2))/(cMax+cMin);
82 s=(((cMax-cMin)*HLSMax)+((2*RGBMax-cMax-cMin)/2))/(2*RGBMax-cMax-cMin);
86 rDelta=(((cMax-r)*(HLSMax/6))+((cMax-cMin)/2))/(cMax-cMin);
87 gDelta=(((cMax-g)*(HLSMax/6))+((cMax-cMin)/2))/(cMax-cMin);
88 bDelta=(((cMax-b)*(HLSMax/6))+((cMax-cMin)/2))/(cMax-cMin);
92 } else if (g == cMax) {
93 h=(HLSMax/3) + rDelta - bDelta;
94 } else { /* B == cMax */
95 h=((2*HLSMax)/3) + gDelta - rDelta;
107 private static int HueToRGB(int n1, int n2, int hue) {
116 /* return r,g, or b value from this tridrant */
117 if (hue<(HLSMax/6)) {
118 return(n1+(((n2-n1)*hue+(HLSMax/12))/(HLSMax/6)));
121 if (hue<(HLSMax/2)) {
125 if (hue<((HLSMax*2)/3)) {
126 return(n1+(((n2-n1)*(((HLSMax*2)/3)-hue)+(HLSMax/12))/(HLSMax/6)));
132 internal static Color HBS2Color(int hue, int lum, int sat) {
139 if (sat == 0) { /* Achromatic */
140 R=G=B=(lum*RGBMax)/HLSMax;
141 // FIXME : Should throw exception if hue!=0
143 if (lum<=(HLSMax/2)) {
144 Magic2=(lum*(HLSMax+sat)+(HLSMax/2))/HLSMax;
146 Magic2=sat+lum-((sat*lum)+(HLSMax/2))/HLSMax;
150 R = Math.Min(255, (HueToRGB(Magic1,Magic2,hue+(HLSMax/3))*RGBMax+(HLSMax/2))/HLSMax);
151 G = Math.Min(255, (HueToRGB(Magic1,Magic2,hue)*RGBMax+(HLSMax/2))/HLSMax);
152 B = Math.Min(255, (HueToRGB(Magic1,Magic2,hue-(HLSMax/3))*RGBMax+(HLSMax/2))/HLSMax);
154 return (Color.FromArgb(R, G, B));
156 #endregion // Helpers
158 #region Public Static Properties
159 public static Color ContrastControlDark {
160 get { return(SystemColors.ControlDark); }
162 #endregion // Public Static Properties
164 #region Public Static Methods
165 [MonoTODO ("Not implemented, will throw NotImplementedException")]
166 public static IntPtr CreateHBitmap16Bit (Bitmap bitmap, Color background)
168 throw new NotImplementedException ();
171 [MonoTODO ("Not implemented, will throw NotImplementedException")]
172 public static IntPtr CreateHBitmapColorMask (Bitmap bitmap, IntPtr monochromeMask)
174 throw new NotImplementedException ();
177 [MonoTODO ("Not implemented, will throw NotImplementedException")]
178 public static IntPtr CreateHBitmapTransparencyMask (Bitmap bitmap)
180 throw new NotImplementedException ();
183 public static Color Light(Color baseColor) {
184 return Light(baseColor, 0.5f);
187 public static Color Light (Color baseColor, float percOfLightLight)
189 if (baseColor.ToArgb () == ThemeEngine.Current.ColorControl.ToArgb ()) {
190 int r_sub, g_sub, b_sub;
193 if (percOfLightLight <= 0f)
194 return ThemeEngine.Current.ColorControlLight;
196 if (percOfLightLight == 1.0f)
197 return ThemeEngine.Current.ColorControlLightLight;
199 r_sub = ThemeEngine.Current.ColorControlLightLight.R - ThemeEngine.Current.ColorControlLight.R;
200 g_sub = ThemeEngine.Current.ColorControlLightLight.G - ThemeEngine.Current.ColorControlLight.G;
201 b_sub = ThemeEngine.Current.ColorControlLightLight.B - ThemeEngine.Current.ColorControlLight.B;
203 color = Color.FromArgb (ThemeEngine.Current.ColorControlLight.A,
204 (int) (ThemeEngine.Current.ColorControlLight.R + (r_sub * percOfLightLight)),
205 (int) (ThemeEngine.Current.ColorControlLight.G + (g_sub * percOfLightLight)),
206 (int) (ThemeEngine.Current.ColorControlLight.B + (b_sub * percOfLightLight)));
212 ControlPaint.Color2HBS (baseColor, out H, out I, out S);
213 int NewIntensity = Math.Min (255, I + (int) ((255 - I) * 0.5f * percOfLightLight));
215 return ControlPaint.HBS2Color (H, NewIntensity, S);
218 public static Color LightLight (Color baseColor)
220 return Light(baseColor, 1.0f);
223 public static Color Dark (Color baseColor)
225 return Dark(baseColor, 0.5f);
228 public static Color Dark (Color baseColor, float percOfDarkDark)
230 if (baseColor.ToArgb () == ThemeEngine.Current.ColorControl.ToArgb ()) {
232 int r_sub, g_sub, b_sub;
235 if (percOfDarkDark <= 0f)
236 return ThemeEngine.Current.ColorControlDark;
238 if (percOfDarkDark == 1.0f)
239 return ThemeEngine.Current.ColorControlDarkDark;
241 r_sub = ThemeEngine.Current.ColorControlDarkDark.R - ThemeEngine.Current.ColorControlDark.R;
242 g_sub = ThemeEngine.Current.ColorControlDarkDark.G - ThemeEngine.Current.ColorControlDark.G;
243 b_sub = ThemeEngine.Current.ColorControlDarkDark.B - ThemeEngine.Current.ColorControlDark.B;
245 color = Color.FromArgb (ThemeEngine.Current.ColorControlDark.A,
246 (int) (ThemeEngine.Current.ColorControlDark.R + (r_sub * percOfDarkDark)),
247 (int) (ThemeEngine.Current.ColorControlDark.G + (g_sub * percOfDarkDark)),
248 (int) (ThemeEngine.Current.ColorControlDark.B + (b_sub * percOfDarkDark)));
254 ControlPaint.Color2HBS(baseColor, out H, out I, out S);
255 int PreIntensity = Math.Max (0, I - (int) (I * 0.333f));
256 int NewIntensity = Math.Max (0, PreIntensity - (int) (PreIntensity * percOfDarkDark));
257 return ControlPaint.HBS2Color(H, NewIntensity, S);
260 public static Color DarkDark (Color baseColor)
262 return Dark(baseColor, 1.0f);
265 public static void DrawBorder (Graphics graphics, Rectangle bounds, Color color, ButtonBorderStyle style)
267 int line_width_top_left = 1;
268 int line_width_bottom_right = 1;
270 if (style == ButtonBorderStyle.Inset)
271 line_width_top_left = 2;
272 if (style == ButtonBorderStyle.Outset) {
273 line_width_bottom_right = 2;
274 line_width_top_left = 2;
277 DrawBorder(graphics, bounds, color, line_width_top_left, style, color, line_width_top_left, style, color, line_width_bottom_right, style, color, line_width_bottom_right, style);
280 internal static void DrawBorder (Graphics graphics, RectangleF bounds, Color color, ButtonBorderStyle style)
282 int line_width_top_left = 1;
283 int line_width_bottom_right = 1;
285 if (style == ButtonBorderStyle.Inset)
286 line_width_top_left = 2;
287 if (style == ButtonBorderStyle.Outset) {
288 line_width_bottom_right = 2;
289 line_width_top_left = 2;
292 ThemeEngine.Current.CPDrawBorder (graphics, bounds, color, line_width_top_left, style, color, line_width_top_left, style, color, line_width_bottom_right, style, color, line_width_bottom_right, style);
295 public static void DrawBorder( Graphics graphics, Rectangle bounds, Color leftColor, int leftWidth,
296 ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
297 Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor, int bottomWidth,
298 ButtonBorderStyle bottomStyle) {
300 ThemeEngine.Current.CPDrawBorder (graphics, bounds, leftColor, leftWidth,
301 leftStyle, topColor, topWidth, topStyle, rightColor, rightWidth, rightStyle,
302 bottomColor, bottomWidth, bottomStyle);
306 public static void DrawBorder3D(Graphics graphics, Rectangle rectangle) {
307 DrawBorder3D(graphics, rectangle, Border3DStyle.Etched, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
310 public static void DrawBorder3D(Graphics graphics, Rectangle rectangle, Border3DStyle style) {
311 DrawBorder3D(graphics, rectangle, style, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
314 public static void DrawBorder3D(Graphics graphics, int x, int y, int width, int height) {
315 DrawBorder3D(graphics, new Rectangle(x, y, width, height), Border3DStyle.Etched, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
318 public static void DrawBorder3D(Graphics graphics, int x, int y, int width, int height, Border3DStyle style) {
319 DrawBorder3D(graphics, new Rectangle(x, y, width, height), style, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
322 public static void DrawBorder3D( Graphics graphics, int x, int y, int width, int height, Border3DStyle style,Border3DSide sides) {
323 DrawBorder3D( graphics, new Rectangle(x, y, width, height), style, sides);
326 public static void DrawBorder3D( Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides) {
328 ThemeEngine.Current.CPDrawBorder3D (graphics, rectangle, style, sides);
331 public static void DrawButton( Graphics graphics, int x, int y, int width, int height, ButtonState state) {
332 DrawButton(graphics, new Rectangle(x, y, width, height), state);
335 public static void DrawButton( Graphics graphics, Rectangle rectangle, ButtonState state) {
337 ThemeEngine.Current.CPDrawButton (graphics, rectangle, state);
341 public static void DrawCaptionButton(Graphics graphics, int x, int y, int width, int height, CaptionButton button, ButtonState state) {
342 DrawCaptionButton(graphics, new Rectangle(x, y, width, height), button, state);
345 public static void DrawCaptionButton(Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state) {
347 ThemeEngine.Current.CPDrawCaptionButton (graphics, rectangle, button, state);
350 public static void DrawCheckBox(Graphics graphics, int x, int y, int width, int height, ButtonState state) {
351 DrawCheckBox(graphics, new Rectangle(x, y, width, height), state);
354 public static void DrawCheckBox(Graphics graphics, Rectangle rectangle, ButtonState state) {
356 ThemeEngine.Current.CPDrawCheckBox (graphics, rectangle, state);
359 public static void DrawComboButton(Graphics graphics, Rectangle rectangle, ButtonState state) {
361 ThemeEngine.Current.CPDrawComboButton (graphics, rectangle, state);
364 public static void DrawComboButton(Graphics graphics, int x, int y, int width, int height, ButtonState state) {
365 DrawComboButton(graphics, new Rectangle(x, y, width, height), state);
368 public static void DrawContainerGrabHandle(Graphics graphics, Rectangle bounds) {
370 ThemeEngine.Current.CPDrawContainerGrabHandle (graphics, bounds);
373 public static void DrawFocusRectangle( Graphics graphics, Rectangle rectangle) {
374 DrawFocusRectangle(graphics, rectangle, SystemColors.Control, SystemColors.ControlText);
377 public static void DrawFocusRectangle( Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor) {
379 ThemeEngine.Current.CPDrawFocusRectangle (graphics, rectangle, foreColor, backColor);
382 public static void DrawGrabHandle(Graphics graphics, Rectangle rectangle, bool primary, bool enabled) {
384 ThemeEngine.Current.CPDrawGrabHandle (graphics, rectangle, primary, enabled);
387 public static void DrawGrid(Graphics graphics, Rectangle area, Size pixelsBetweenDots, Color backColor) {
389 ThemeEngine.Current.CPDrawGrid (graphics, area, pixelsBetweenDots, backColor);
392 public static void DrawImageDisabled(Graphics graphics, Image image, int x, int y, Color background) {
394 ThemeEngine.Current.CPDrawImageDisabled (graphics, image, x, y, background);
397 public static void DrawLockedFrame(Graphics graphics, Rectangle rectangle, bool primary) {
399 ThemeEngine.Current.CPDrawLockedFrame (graphics, rectangle, primary);
402 public static void DrawMenuGlyph(Graphics graphics, Rectangle rectangle, MenuGlyph glyph) {
404 ThemeEngine.Current.CPDrawMenuGlyph (graphics, rectangle, glyph, ThemeEngine.Current.ColorMenuText, Color.Empty);
407 public static void DrawMenuGlyph (Graphics graphics, Rectangle rectangle, MenuGlyph glyph, Color foreColor, Color backColor)
409 ThemeEngine.Current.CPDrawMenuGlyph (graphics, rectangle, glyph, foreColor, backColor);
412 public static void DrawMenuGlyph(Graphics graphics, int x, int y, int width, int height, MenuGlyph glyph) {
413 DrawMenuGlyph(graphics, new Rectangle(x, y, width, height), glyph);
416 public static void DrawMenuGlyph (Graphics graphics, int x, int y, int width, int height, MenuGlyph glyph, Color foreColor, Color backColor)
418 DrawMenuGlyph (graphics, new Rectangle (x, y, width, height), glyph, foreColor, backColor);
421 public static void DrawMixedCheckBox(Graphics graphics, Rectangle rectangle, ButtonState state) {
422 ThemeEngine.Current.CPDrawMixedCheckBox (graphics, rectangle, state);
425 public static void DrawMixedCheckBox(Graphics graphics, int x, int y, int width, int height, ButtonState state) {
426 DrawMixedCheckBox(graphics, new Rectangle(x, y, width, height), state);
430 public static void DrawRadioButton(Graphics graphics, int x, int y, int width, int height, ButtonState state) {
431 DrawRadioButton(graphics, new Rectangle(x, y, width, height), state);
434 public static void DrawRadioButton(Graphics graphics, Rectangle rectangle, ButtonState state) {
436 ThemeEngine.Current.CPDrawRadioButton (graphics, rectangle, state);
439 public static void DrawReversibleFrame(Rectangle rectangle, Color backColor, FrameStyle style) {
440 XplatUI.DrawReversibleFrame (rectangle, backColor, style);
443 public static void DrawReversibleLine(Point start, Point end, Color backColor) {
444 XplatUI.DrawReversibleLine (start, end, backColor);
447 public static void FillReversibleRectangle(Rectangle rectangle, Color backColor) {
448 XplatUI.FillReversibleRectangle (rectangle, backColor);
451 public static void DrawScrollButton (Graphics graphics, int x, int y, int width, int height, ScrollButton button, ButtonState state) {
452 ThemeEngine.Current.CPDrawScrollButton (graphics, new Rectangle(x, y, width, height), button, state);
455 public static void DrawScrollButton (Graphics graphics, Rectangle rectangle, ScrollButton button, ButtonState state) {
456 ThemeEngine.Current.CPDrawScrollButton (graphics, rectangle, button, state);
459 [MonoTODO ("Stub, does nothing")]
460 private static bool DSFNotImpl = false;
461 public static void DrawSelectionFrame(Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect, Color backColor) {
464 Console.WriteLine("NOT IMPLEMENTED: DrawSelectionFrame(Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect, Color backColor)");
466 //throw new NotImplementedException();
469 public static void DrawSizeGrip (Graphics graphics, Color backColor, Rectangle bounds)
471 ThemeEngine.Current.CPDrawSizeGrip (graphics, backColor, bounds);
474 public static void DrawSizeGrip(Graphics graphics, Color backColor, int x, int y, int width, int height) {
475 DrawSizeGrip(graphics, backColor, new Rectangle(x, y, width, height));
478 public static void DrawStringDisabled(Graphics graphics, string s, Font font, Color color, RectangleF layoutRectangle, StringFormat format) {
480 ThemeEngine.Current.CPDrawStringDisabled (graphics, s, font, color, layoutRectangle, format);
483 public static void DrawStringDisabled (IDeviceContext dc, string s, Font font, Color color, Rectangle layoutRectangle, TextFormatFlags format)
485 ThemeEngine.Current.CPDrawStringDisabled (dc, s, font, color, layoutRectangle, format);
488 public static void DrawVisualStyleBorder (Graphics graphics, Rectangle bounds)
490 ThemeEngine.Current.CPDrawVisualStyleBorder (graphics, bounds);
492 #endregion // Public Static Methods