merge -r 58060:58217
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ControlPaint.cs
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:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
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.
19 //
20 // Copyright (c) 2004 Novell, Inc.
21 //
22 // Authors:
23 //      Peter Bartok    pbartok@novell.com
24 //
25
26
27 // NOT COMPLETE
28
29 using System.Drawing;
30 using System.Drawing.Drawing2D;
31 using System.Drawing.Imaging;
32
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
39
40                 #region Private Enumerations
41
42
43                 #region Constructor
44                 // Prevent a public constructor from being created
45                 private ControlPaint() {
46                 }
47                 #endregion      // Constructor
48
49
50                 #endregion      // Private Enumerations
51
52                 #region Helpers
53                 private static Color Win32ToColor(int Win32Color) {
54                         return(Color.FromArgb(
55                                 (int)(Win32Color) & 0xff0000 >> 16,             // blue
56                                 (int)(Win32Color) & 0xff00 >> 8,                // green
57                                 (int)(Win32Color) & 0xff                        // red
58                         ));
59                 }
60
61                 internal static void Color2HBS(Color color, out int h, out int l, out int s) {
62                         int     r;
63                         int     g;
64                         int     b;
65                         int     cMax;
66                         int     cMin;
67                         int     rDelta;
68                         int     gDelta;
69                         int     bDelta;
70
71                         r=color.R;
72                         g=color.G;
73                         b=color.B;
74
75                         cMax = Math.Max(Math.Max(r, g), b);
76                         cMin = Math.Min(Math.Min(r, g), b);
77
78                         l = (((cMax+cMin)*HLSMax)+RGBMax)/(2*RGBMax);
79
80                         if (cMax==cMin) {               // Achromatic
81                                 h=0;                                    // h undefined
82                                 s=0;
83                                 return;
84                         }
85
86                         /* saturation */
87                         if (l<=(HLSMax/2)) {
88                                 s=(((cMax-cMin)*HLSMax)+((cMax+cMin)/2))/(cMax+cMin);
89                         } else {
90                                 s=(((cMax-cMin)*HLSMax)+((2*RGBMax-cMax-cMin)/2))/(2*RGBMax-cMax-cMin);
91                         }
92
93                         /* hue */
94                         rDelta=(((cMax-r)*(HLSMax/6))+((cMax-cMin)/2))/(cMax-cMin);
95                         gDelta=(((cMax-g)*(HLSMax/6))+((cMax-cMin)/2))/(cMax-cMin);
96                         bDelta=(((cMax-b)*(HLSMax/6))+((cMax-cMin)/2))/(cMax-cMin);
97
98                         if (r == cMax) {
99                                 h=bDelta - gDelta;
100                         } else if (g == cMax) {
101                                 h=(HLSMax/3) + rDelta - bDelta;
102                         } else { /* B == cMax */
103                                 h=((2*HLSMax)/3) + gDelta - rDelta;
104                         }
105
106                         if (h<0) {
107                                 h+=HLSMax;
108                         }
109
110                         if (h>HLSMax) {
111                                 h-=HLSMax;
112                         }
113                 }
114
115                 private static int HueToRGB(int n1, int n2, int hue) {
116                         if (hue<0) {
117                                 hue+=HLSMax;
118                         }
119
120                         if (hue>HLSMax) {
121                                 hue -= HLSMax;
122                         }
123
124                         /* return r,g, or b value from this tridrant */
125                         if (hue<(HLSMax/6)) {
126                                 return(n1+(((n2-n1)*hue+(HLSMax/12))/(HLSMax/6)));
127                         }
128
129                         if (hue<(HLSMax/2)) {
130                                 return(n2);
131                         }
132
133                         if (hue<((HLSMax*2)/3)) {
134                                 return(n1+(((n2-n1)*(((HLSMax*2)/3)-hue)+(HLSMax/12))/(HLSMax/6)));
135                         } else {
136                                 return(n1);
137                         }
138                 }
139
140                 internal static Color HBS2Color(int hue, int lum, int sat) {
141                         int     R;
142                         int     G;
143                         int     B;
144                         int     Magic1;
145                         int     Magic2;
146
147                         if (sat == 0) {            /* Achromatic */
148                                 R=G=B=(lum*RGBMax)/HLSMax;
149                                 // FIXME : Should throw exception if hue!=0
150                         } else {
151                                 if (lum<=(HLSMax/2)) {
152                                         Magic2=(lum*(HLSMax+sat)+(HLSMax/2))/HLSMax;
153                                 } else {
154                                         Magic2=sat+lum-((sat*lum)+(HLSMax/2))/HLSMax;
155                                 }
156                                 Magic1=2*lum-Magic2;
157
158                                 R = Math.Min(255, (HueToRGB(Magic1,Magic2,hue+(HLSMax/3))*RGBMax+(HLSMax/2))/HLSMax);
159                                 G = Math.Min(255, (HueToRGB(Magic1,Magic2,hue)*RGBMax+(HLSMax/2))/HLSMax);
160                                 B = Math.Min(255, (HueToRGB(Magic1,Magic2,hue-(HLSMax/3))*RGBMax+(HLSMax/2))/HLSMax);
161                         }
162                         return(Color.FromArgb(R, G, B));
163                 }
164                 #endregion      // Helpers
165
166                 #region Public Static Properties
167                 public static Color ContrastControlDark {
168                         get { return(SystemColors.ControlDark); }
169                 }
170                 #endregion      // Public Static Properties
171
172                 #region Public Static Methods
173                 public static IntPtr CreateHBitmap16Bit(Bitmap bitmap, Color background){
174                         throw new NotImplementedException ();
175                 }
176
177                 public static IntPtr CreateHBitmapColorMask(Bitmap bitmap, IntPtr monochromeMask){
178                         throw new NotImplementedException ();
179                 }
180
181                 public static IntPtr CreateHBitmapTransparencyMask(Bitmap bitmap){
182                         throw new NotImplementedException ();
183                 }
184
185                 public static Color Light(Color baseColor) {
186                         return Light(baseColor, 0.5f);
187                 }
188
189                 public static Color Light(Color baseColor,float per) {
190                         if (baseColor == ThemeEngine.Current.ColorControl) {
191                                 int r_sub, g_sub, b_sub;
192                                 Color color;
193
194                                 if (per <= 0f)
195                                         return ThemeEngine.Current.ColorControlLight;
196
197                                 if (per == 1.0f)                                        
198                                         return ThemeEngine.Current.ColorControlLightLight;
199                                 
200                                 r_sub = ThemeEngine.Current.ColorControlLightLight.R - ThemeEngine.Current.ColorControlLight.R;
201                                 g_sub = ThemeEngine.Current.ColorControlLightLight.G - ThemeEngine.Current.ColorControlLight.G;
202                                 b_sub = ThemeEngine.Current.ColorControlLightLight.B - ThemeEngine.Current.ColorControlLight.B;
203                                                                 
204                                 color = Color.FromArgb (ThemeEngine.Current.ColorControlLight.A,
205                                                 (int) (ThemeEngine.Current.ColorControlLight.R + (r_sub * per)),
206                                                 (int) (ThemeEngine.Current.ColorControlLight.G + (g_sub * per)),
207                                                 (int) (ThemeEngine.Current.ColorControlLight.B + (b_sub * per)));
208                                 
209                                 return color;
210                         }
211                         
212                         int H, I, S;
213
214                         ControlPaint.Color2HBS(baseColor, out H, out I, out S);                 
215                         int PreIntensity = Math.Min (255, I + (int) (I * 0.5f));
216                         int NewIntensity =  Math.Min (255, PreIntensity + (int) (PreIntensity * per));
217                         return ControlPaint.HBS2Color(H, NewIntensity, S);                      
218                 }
219
220                 public static Color LightLight(Color baseColor) {                       
221                         return Light(baseColor, 1.0f);
222                 }
223
224                 public static Color Dark(Color baseColor) {
225                         return Dark(baseColor, 0.5f);
226                 }
227
228                 public static Color Dark(Color baseColor,float per) {   
229
230                         if (baseColor == ThemeEngine.Current.ColorControl) {
231                                 
232                                 int r_sub, g_sub, b_sub;
233                                 Color color;
234
235                                 if (per <= 0f)
236                                         return ThemeEngine.Current.ColorControlDark;
237
238                                 if (per == 1.0f)
239                                         return ThemeEngine.Current.ColorControlDarkDark;
240                                                                                                         
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;
244                                                                 
245                                 color = Color.FromArgb (ThemeEngine.Current.ColorControlDark.A,
246                                                 (int) (ThemeEngine.Current.ColorControlDark.R + (r_sub * per)),
247                                                 (int) (ThemeEngine.Current.ColorControlDark.G + (g_sub * per)),
248                                                 (int) (ThemeEngine.Current.ColorControlDark.B + (b_sub * per)));
249                                 return color;
250                         }
251                 
252                         int H, I, S;
253
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 * per));
257                         return ControlPaint.HBS2Color(H, NewIntensity, S);
258                 }
259
260                 public static Color DarkDark(Color baseColor) {                 
261                         return Dark(baseColor, 1.0f);
262                 }
263
264                 public static void DrawBorder(Graphics graphics, Rectangle bounds, Color color, ButtonBorderStyle style) {
265                         DrawBorder(graphics, bounds, color, 1, style, color, 1, style, color, 1, style, color, 1, style);
266                 }
267
268                 public static void DrawBorder( Graphics graphics, Rectangle bounds, Color leftColor, int leftWidth,
269                         ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
270                         Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor, int bottomWidth,
271                         ButtonBorderStyle bottomStyle) {
272
273                         ThemeEngine.Current.CPDrawBorder (graphics, bounds, leftColor, leftWidth,
274                                 leftStyle, topColor, topWidth, topStyle, rightColor, rightWidth, rightStyle,
275                                 bottomColor, bottomWidth, bottomStyle);
276                 }
277
278
279                 public static void DrawBorder3D(Graphics graphics, Rectangle rectangle) {
280                         DrawBorder3D(graphics, rectangle, Border3DStyle.Etched, Border3DSide.All);
281                 }
282
283                 public static void DrawBorder3D(Graphics graphics, Rectangle rectangle, Border3DStyle style) {
284                         DrawBorder3D(graphics, rectangle, style, Border3DSide.All);
285                 }
286
287                 public static void DrawBorder3D(Graphics graphics, int x, int y, int width, int height) {
288                         DrawBorder3D(graphics, new Rectangle(x, y, width, height), Border3DStyle.Etched, Border3DSide.All);
289                 }
290
291                 public static void DrawBorder3D(Graphics graphics, int x, int y, int width, int height, Border3DStyle style) {
292                         DrawBorder3D(graphics, new Rectangle(x, y, width, height), style, Border3DSide.All);
293                 }
294
295                 public static void DrawBorder3D( Graphics graphics, int x, int y, int width, int height, Border3DStyle style,Border3DSide sides) {
296                         DrawBorder3D( graphics, new Rectangle(x, y, width, height), style, sides);
297                 }
298
299                 public static void DrawBorder3D( Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides) {
300
301                         ThemeEngine.Current.CPDrawBorder3D (graphics, rectangle, style, sides);
302                 }
303
304                 public static void DrawButton( Graphics graphics, int x, int y, int width, int height, ButtonState state) {
305                         DrawButton(graphics, new Rectangle(x, y, width, height), state);
306                 }
307
308                 public static void DrawButton( Graphics graphics, Rectangle rectangle, ButtonState state) {
309
310                         ThemeEngine.Current.CPDrawButton (graphics, rectangle, state);
311                 }
312
313
314                 public static void DrawCaptionButton(Graphics graphics, int x, int y, int width, int height, CaptionButton button, ButtonState state) {
315                         DrawCaptionButton(graphics, new Rectangle(x, y, width, height), button, state);
316                 }
317
318                 public static void DrawCaptionButton(Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state) {
319
320                         ThemeEngine.Current.CPDrawCaptionButton (graphics, rectangle, button, state);
321                 }
322
323                 public static void DrawCheckBox(Graphics graphics, int x, int y, int width, int height, ButtonState state) {
324                         DrawCheckBox(graphics, new Rectangle(x, y, width, height), state);
325                 }
326
327                 public static void DrawCheckBox(Graphics graphics, Rectangle rectangle, ButtonState state) {
328
329                         ThemeEngine.Current.CPDrawCheckBox (graphics, rectangle, state);
330                 }
331
332                 public static void DrawComboButton(Graphics graphics, Rectangle rectangle, ButtonState state) {
333
334                         ThemeEngine.Current.CPDrawComboButton (graphics, rectangle,  state);
335                 }
336
337                 public static void DrawComboButton(Graphics graphics, int x, int y, int width, int height, ButtonState state) {
338                         DrawComboButton(graphics, new Rectangle(x, y, width, height), state);
339                 }
340
341                 public static void DrawContainerGrabHandle(Graphics graphics, Rectangle bounds) {
342
343                         ThemeEngine.Current.CPDrawContainerGrabHandle (graphics, bounds);
344                 }
345
346                 public static void DrawFocusRectangle( Graphics graphics, Rectangle rectangle) {
347                         DrawFocusRectangle(graphics, rectangle, SystemColors.Control, SystemColors.ControlText);
348                 }
349
350                 public static void DrawFocusRectangle( Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor) {
351
352                         ThemeEngine.Current.CPDrawFocusRectangle (graphics, rectangle, foreColor, backColor);
353                 }
354
355                 public static void DrawGrabHandle(Graphics graphics, Rectangle rectangle, bool primary, bool enabled) {
356
357                         ThemeEngine.Current.CPDrawGrabHandle (graphics, rectangle, primary, enabled);
358                 }
359
360                 public static void DrawGrid(Graphics graphics, Rectangle area, Size pixelsBetweenDots, Color backColor) {
361
362                         ThemeEngine.Current.CPDrawGrid (graphics, area, pixelsBetweenDots, backColor);
363                 }
364
365                 public static void DrawImageDisabled(Graphics graphics, Image image, int x, int y, Color background) {
366
367                         ThemeEngine.Current.CPDrawImageDisabled (graphics, image, x, y, background);
368                 }
369
370                 public static void DrawLockedFrame(Graphics graphics, Rectangle rectangle, bool primary) {
371
372                         ThemeEngine.Current.CPDrawLockedFrame (graphics, rectangle, primary);
373                 }
374
375                 public static void DrawMenuGlyph(Graphics graphics, Rectangle rectangle, MenuGlyph glyph) {
376
377                         ThemeEngine.Current.CPDrawMenuGlyph (graphics, rectangle, glyph);
378                 }
379
380                 public static void DrawMenuGlyph(Graphics graphics, int x, int y, int width, int height, MenuGlyph glyph) {
381                         DrawMenuGlyph(graphics, new Rectangle(x, y, width, height), glyph);
382                 }
383
384                 public static void DrawMixedCheckBox(Graphics graphics, Rectangle rectangle, ButtonState state) {
385                         DrawCheckBox(graphics, rectangle, state);
386                 }
387
388                 public static void DrawMixedCheckBox(Graphics graphics, int x, int y, int width, int height, ButtonState state) {
389                         DrawMixedCheckBox(graphics, new Rectangle(x, y, width, height), state);
390                 }
391
392
393                 public static void DrawRadioButton(Graphics graphics, int x, int y, int width, int height, ButtonState state) {
394                         DrawRadioButton(graphics, new Rectangle(x, y, width, height), state);
395                 }
396
397                 public static void DrawRadioButton(Graphics graphics, Rectangle rectangle, ButtonState state) {
398
399                         ThemeEngine.Current.CPDrawRadioButton (graphics, rectangle, state);
400                 }
401
402                 [MonoTODO("Figure out a good System.Drawing way for XOR drawing")]
403                 private static bool DRFNotImpl = false;
404                 public static void DrawReversibleFrame(Rectangle rectangle, Color backColor, FrameStyle style) {
405                         if (!DRFNotImpl) {
406                                 DRFNotImpl = true;
407                                 Console.WriteLine("NOT IMPLEMENTED: FillReversibleRectangle(Rectangle rectangle, Color backColor)");
408                         }
409                         //throw new NotImplementedException();
410                 }
411
412                 [MonoTODO("Figure out a good System.Drawing way for XOR drawing")]
413                 private static bool DRLNotImpl = false;
414                 public static void DrawReversibleLine(Point start, Point end, Color backColor) {
415                         if (!DRLNotImpl) {
416                                 DRLNotImpl = true;
417                                 Console.WriteLine("NOT IMPLEMENTED: FillReversibleRectangle(Rectangle rectangle, Color backColor)");
418                         }
419                         //throw new NotImplementedException();
420                 }
421
422                 [MonoTODO("Figure out a good System.Drawing way for XOR drawing")]
423                 private static bool FRRNotImpl = false;
424                 public static void FillReversibleRectangle(Rectangle rectangle, Color backColor) {
425                         if (!FRRNotImpl) {
426                                 FRRNotImpl = true;
427                                 Console.WriteLine("NOT IMPLEMENTED: FillReversibleRectangle(Rectangle rectangle, Color backColor)");
428                         }
429                         //throw new NotImplementedException();
430                 }
431
432
433                 public static void DrawScrollButton (Graphics graphics, int x, int y, int width, int height, ScrollButton button, ButtonState state) {
434                         ThemeEngine.Current.CPDrawScrollButton (graphics, new Rectangle(x, y, width, height), button, state);
435                 }
436
437                 public static void DrawScrollButton (Graphics graphics, Rectangle rectangle, ScrollButton button, ButtonState state) {
438                         ThemeEngine.Current.CPDrawScrollButton (graphics, rectangle, button, state);
439                 }
440
441                 [MonoTODO]
442                 private static bool DSFNotImpl = false;
443                 public static void DrawSelectionFrame(Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect, Color backColor) {
444                         if (!DSFNotImpl) {
445                                 DSFNotImpl = true;
446                                 Console.WriteLine("NOT IMPLEMENTED: DrawSelectionFrame(Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect, Color backColor)");
447                         }
448                         //throw new NotImplementedException();
449                 }
450
451                 public static void DrawSizeGrip (Graphics graphics, Color backColor, Rectangle bounds)
452                 {
453                         ThemeEngine.Current.CPDrawSizeGrip (graphics,  backColor,  bounds);
454                 }
455
456                 public static void DrawSizeGrip(Graphics graphics, Color backColor, int x, int y, int width, int height) {
457                         DrawSizeGrip(graphics, backColor, new Rectangle(x, y, width, height));
458                 }
459
460                 public static void DrawStringDisabled(Graphics graphics, string s, Font font, Color color, RectangleF layoutRectangle, StringFormat format) {
461
462                         ThemeEngine.Current.CPDrawStringDisabled (graphics, s, font, color, layoutRectangle, format);
463                 }
464                 #endregion      // Public Static Methods
465         }
466 }