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 public static IntPtr
CreateHBitmap16Bit(Bitmap bitmap
, Color background
){
166 throw new NotImplementedException ();
169 public static IntPtr
CreateHBitmapColorMask(Bitmap bitmap
, IntPtr monochromeMask
){
170 throw new NotImplementedException ();
173 public static IntPtr
CreateHBitmapTransparencyMask(Bitmap bitmap
){
174 throw new NotImplementedException ();
177 public static Color
Light(Color baseColor
) {
178 return Light(baseColor
, 0.5f
);
181 public static Color
Light(Color baseColor
,float per
) {
182 if (baseColor
.ToArgb () == ThemeEngine
.Current
.ColorControl
.ToArgb ()) {
183 int r_sub
, g_sub
, b_sub
;
187 return ThemeEngine
.Current
.ColorControlLight
;
190 return ThemeEngine
.Current
.ColorControlLightLight
;
192 r_sub
= ThemeEngine
.Current
.ColorControlLightLight
.R
- ThemeEngine
.Current
.ColorControlLight
.R
;
193 g_sub
= ThemeEngine
.Current
.ColorControlLightLight
.G
- ThemeEngine
.Current
.ColorControlLight
.G
;
194 b_sub
= ThemeEngine
.Current
.ColorControlLightLight
.B
- ThemeEngine
.Current
.ColorControlLight
.B
;
196 color
= Color
.FromArgb (ThemeEngine
.Current
.ColorControlLight
.A
,
197 (int) (ThemeEngine
.Current
.ColorControlLight
.R
+ (r_sub
* per
)),
198 (int) (ThemeEngine
.Current
.ColorControlLight
.G
+ (g_sub
* per
)),
199 (int) (ThemeEngine
.Current
.ColorControlLight
.B
+ (b_sub
* per
)));
206 ControlPaint
.Color2HBS(baseColor
, out H
, out I
, out S
);
207 int NewIntensity
= Math
.Min (255, I
+ (int)((255 - I
) * 0.5f
* per
));
209 return ControlPaint
.HBS2Color(H
, NewIntensity
, S
);
212 public static Color
LightLight(Color baseColor
) {
213 return Light(baseColor
, 1.0f
);
216 public static Color
Dark(Color baseColor
) {
217 return Dark(baseColor
, 0.5f
);
220 public static Color
Dark(Color baseColor
,float per
) {
222 if (baseColor
.ToArgb () == ThemeEngine
.Current
.ColorControl
.ToArgb ()) {
224 int r_sub
, g_sub
, b_sub
;
228 return ThemeEngine
.Current
.ColorControlDark
;
231 return ThemeEngine
.Current
.ColorControlDarkDark
;
233 r_sub
= ThemeEngine
.Current
.ColorControlDarkDark
.R
- ThemeEngine
.Current
.ColorControlDark
.R
;
234 g_sub
= ThemeEngine
.Current
.ColorControlDarkDark
.G
- ThemeEngine
.Current
.ColorControlDark
.G
;
235 b_sub
= ThemeEngine
.Current
.ColorControlDarkDark
.B
- ThemeEngine
.Current
.ColorControlDark
.B
;
237 color
= Color
.FromArgb (ThemeEngine
.Current
.ColorControlDark
.A
,
238 (int) (ThemeEngine
.Current
.ColorControlDark
.R
+ (r_sub
* per
)),
239 (int) (ThemeEngine
.Current
.ColorControlDark
.G
+ (g_sub
* per
)),
240 (int) (ThemeEngine
.Current
.ColorControlDark
.B
+ (b_sub
* per
)));
246 ControlPaint
.Color2HBS(baseColor
, out H
, out I
, out S
);
247 int PreIntensity
= Math
.Max (0, I
- (int) (I
* 0.333f
));
248 int NewIntensity
= Math
.Max (0, PreIntensity
- (int) (PreIntensity
* per
));
249 return ControlPaint
.HBS2Color(H
, NewIntensity
, S
);
252 public static Color
DarkDark(Color baseColor
) {
253 return Dark(baseColor
, 1.0f
);
256 public static void DrawBorder(Graphics graphics
, Rectangle bounds
, Color color
, ButtonBorderStyle style
) {
257 int line_width_top_left
= 1;
258 int line_width_bottom_right
= 1;
260 if (style
== ButtonBorderStyle
.Inset
)
261 line_width_top_left
= 2;
262 if (style
== ButtonBorderStyle
.Outset
) {
263 line_width_bottom_right
= 2;
264 line_width_top_left
= 2;
267 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
);
270 public static void DrawBorder( Graphics graphics
, Rectangle bounds
, Color leftColor
, int leftWidth
,
271 ButtonBorderStyle leftStyle
, Color topColor
, int topWidth
, ButtonBorderStyle topStyle
,
272 Color rightColor
, int rightWidth
, ButtonBorderStyle rightStyle
, Color bottomColor
, int bottomWidth
,
273 ButtonBorderStyle bottomStyle
) {
275 ThemeEngine
.Current
.CPDrawBorder (graphics
, bounds
, leftColor
, leftWidth
,
276 leftStyle
, topColor
, topWidth
, topStyle
, rightColor
, rightWidth
, rightStyle
,
277 bottomColor
, bottomWidth
, bottomStyle
);
281 public static void DrawBorder3D(Graphics graphics
, Rectangle rectangle
) {
282 DrawBorder3D(graphics
, rectangle
, Border3DStyle
.Etched
, Border3DSide
.Left
| Border3DSide
.Right
| Border3DSide
.Top
| Border3DSide
.Bottom
);
285 public static void DrawBorder3D(Graphics graphics
, Rectangle rectangle
, Border3DStyle style
) {
286 DrawBorder3D(graphics
, rectangle
, style
, Border3DSide
.Left
| Border3DSide
.Right
| Border3DSide
.Top
| Border3DSide
.Bottom
);
289 public static void DrawBorder3D(Graphics graphics
, int x
, int y
, int width
, int height
) {
290 DrawBorder3D(graphics
, new Rectangle(x
, y
, width
, height
), Border3DStyle
.Etched
, Border3DSide
.Left
| Border3DSide
.Right
| Border3DSide
.Top
| Border3DSide
.Bottom
);
293 public static void DrawBorder3D(Graphics graphics
, int x
, int y
, int width
, int height
, Border3DStyle style
) {
294 DrawBorder3D(graphics
, new Rectangle(x
, y
, width
, height
), style
, Border3DSide
.Left
| Border3DSide
.Right
| Border3DSide
.Top
| Border3DSide
.Bottom
);
297 public static void DrawBorder3D( Graphics graphics
, int x
, int y
, int width
, int height
, Border3DStyle style
,Border3DSide sides
) {
298 DrawBorder3D( graphics
, new Rectangle(x
, y
, width
, height
), style
, sides
);
301 public static void DrawBorder3D( Graphics graphics
, Rectangle rectangle
, Border3DStyle style
, Border3DSide sides
) {
303 ThemeEngine
.Current
.CPDrawBorder3D (graphics
, rectangle
, style
, sides
);
306 public static void DrawButton( Graphics graphics
, int x
, int y
, int width
, int height
, ButtonState state
) {
307 DrawButton(graphics
, new Rectangle(x
, y
, width
, height
), state
);
310 public static void DrawButton( Graphics graphics
, Rectangle rectangle
, ButtonState state
) {
312 ThemeEngine
.Current
.CPDrawButton (graphics
, rectangle
, state
);
316 public static void DrawCaptionButton(Graphics graphics
, int x
, int y
, int width
, int height
, CaptionButton button
, ButtonState state
) {
317 DrawCaptionButton(graphics
, new Rectangle(x
, y
, width
, height
), button
, state
);
320 public static void DrawCaptionButton(Graphics graphics
, Rectangle rectangle
, CaptionButton button
, ButtonState state
) {
322 ThemeEngine
.Current
.CPDrawCaptionButton (graphics
, rectangle
, button
, state
);
325 public static void DrawCheckBox(Graphics graphics
, int x
, int y
, int width
, int height
, ButtonState state
) {
326 DrawCheckBox(graphics
, new Rectangle(x
, y
, width
, height
), state
);
329 public static void DrawCheckBox(Graphics graphics
, Rectangle rectangle
, ButtonState state
) {
331 ThemeEngine
.Current
.CPDrawCheckBox (graphics
, rectangle
, state
);
334 public static void DrawComboButton(Graphics graphics
, Rectangle rectangle
, ButtonState state
) {
336 ThemeEngine
.Current
.CPDrawComboButton (graphics
, rectangle
, state
);
339 public static void DrawComboButton(Graphics graphics
, int x
, int y
, int width
, int height
, ButtonState state
) {
340 DrawComboButton(graphics
, new Rectangle(x
, y
, width
, height
), state
);
343 public static void DrawContainerGrabHandle(Graphics graphics
, Rectangle bounds
) {
345 ThemeEngine
.Current
.CPDrawContainerGrabHandle (graphics
, bounds
);
348 public static void DrawFocusRectangle( Graphics graphics
, Rectangle rectangle
) {
349 DrawFocusRectangle(graphics
, rectangle
, SystemColors
.Control
, SystemColors
.ControlText
);
352 public static void DrawFocusRectangle( Graphics graphics
, Rectangle rectangle
, Color foreColor
, Color backColor
) {
354 ThemeEngine
.Current
.CPDrawFocusRectangle (graphics
, rectangle
, foreColor
, backColor
);
357 public static void DrawGrabHandle(Graphics graphics
, Rectangle rectangle
, bool primary
, bool enabled
) {
359 ThemeEngine
.Current
.CPDrawGrabHandle (graphics
, rectangle
, primary
, enabled
);
362 public static void DrawGrid(Graphics graphics
, Rectangle area
, Size pixelsBetweenDots
, Color backColor
) {
364 ThemeEngine
.Current
.CPDrawGrid (graphics
, area
, pixelsBetweenDots
, backColor
);
367 public static void DrawImageDisabled(Graphics graphics
, Image image
, int x
, int y
, Color background
) {
369 ThemeEngine
.Current
.CPDrawImageDisabled (graphics
, image
, x
, y
, background
);
372 public static void DrawLockedFrame(Graphics graphics
, Rectangle rectangle
, bool primary
) {
374 ThemeEngine
.Current
.CPDrawLockedFrame (graphics
, rectangle
, primary
);
377 public static void DrawMenuGlyph(Graphics graphics
, Rectangle rectangle
, MenuGlyph glyph
) {
379 ThemeEngine
.Current
.CPDrawMenuGlyph (graphics
, rectangle
, glyph
, ThemeEngine
.Current
.ColorMenuText
);
382 public static void DrawMenuGlyph(Graphics graphics
, int x
, int y
, int width
, int height
, MenuGlyph glyph
) {
383 DrawMenuGlyph(graphics
, new Rectangle(x
, y
, width
, height
), glyph
);
386 public static void DrawMixedCheckBox(Graphics graphics
, Rectangle rectangle
, ButtonState state
) {
387 DrawCheckBox(graphics
, rectangle
, state
);
390 public static void DrawMixedCheckBox(Graphics graphics
, int x
, int y
, int width
, int height
, ButtonState state
) {
391 DrawMixedCheckBox(graphics
, new Rectangle(x
, y
, width
, height
), state
);
395 public static void DrawRadioButton(Graphics graphics
, int x
, int y
, int width
, int height
, ButtonState state
) {
396 DrawRadioButton(graphics
, new Rectangle(x
, y
, width
, height
), state
);
399 public static void DrawRadioButton(Graphics graphics
, Rectangle rectangle
, ButtonState state
) {
401 ThemeEngine
.Current
.CPDrawRadioButton (graphics
, rectangle
, state
);
404 [MonoTODO("Figure out a good System.Drawing way for XOR drawing")]
405 private static bool DRFNotImpl
= false;
406 public static void DrawReversibleFrame(Rectangle rectangle
, Color backColor
, FrameStyle style
) {
409 Console
.WriteLine("NOT IMPLEMENTED: FillReversibleRectangle(Rectangle rectangle, Color backColor)");
411 //throw new NotImplementedException();
414 [MonoTODO("Figure out a good System.Drawing way for XOR drawing")]
415 private static bool DRLNotImpl
= false;
416 public static void DrawReversibleLine(Point start
, Point end
, Color backColor
) {
419 Console
.WriteLine("NOT IMPLEMENTED: FillReversibleRectangle(Rectangle rectangle, Color backColor)");
421 //throw new NotImplementedException();
424 [MonoTODO("Figure out a good System.Drawing way for XOR drawing")]
425 private static bool FRRNotImpl
= false;
426 public static void FillReversibleRectangle(Rectangle rectangle
, Color backColor
) {
429 Console
.WriteLine("NOT IMPLEMENTED: FillReversibleRectangle(Rectangle rectangle, Color backColor)");
431 //throw new NotImplementedException();
435 public static void DrawScrollButton (Graphics graphics
, int x
, int y
, int width
, int height
, ScrollButton button
, ButtonState state
) {
436 ThemeEngine
.Current
.CPDrawScrollButton (graphics
, new Rectangle(x
, y
, width
, height
), button
, state
);
439 public static void DrawScrollButton (Graphics graphics
, Rectangle rectangle
, ScrollButton button
, ButtonState state
) {
440 ThemeEngine
.Current
.CPDrawScrollButton (graphics
, rectangle
, button
, state
);
444 private static bool DSFNotImpl
= false;
445 public static void DrawSelectionFrame(Graphics graphics
, bool active
, Rectangle outsideRect
, Rectangle insideRect
, Color backColor
) {
448 Console
.WriteLine("NOT IMPLEMENTED: DrawSelectionFrame(Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect, Color backColor)");
450 //throw new NotImplementedException();
453 public static void DrawSizeGrip (Graphics graphics
, Color backColor
, Rectangle bounds
)
455 ThemeEngine
.Current
.CPDrawSizeGrip (graphics
, backColor
, bounds
);
458 public static void DrawSizeGrip(Graphics graphics
, Color backColor
, int x
, int y
, int width
, int height
) {
459 DrawSizeGrip(graphics
, backColor
, new Rectangle(x
, y
, width
, height
));
462 public static void DrawStringDisabled(Graphics graphics
, string s
, Font font
, Color color
, RectangleF layoutRectangle
, StringFormat format
) {
464 ThemeEngine
.Current
.CPDrawStringDisabled (graphics
, s
, font
, color
, layoutRectangle
, format
);
466 #endregion // Public Static Methods