Fix problems with overlong directory names: phase #1
[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.ToArgb () == ThemeEngine.Current.ColorControl.ToArgb ()) {
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 NewIntensity =  Math.Min (255, I + (int)((255 - I) * 0.5f * per));
216                         
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.ToArgb () == ThemeEngine.Current.ColorControl.ToArgb ()) {
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                         int line_width_top_left = 1;
266                         int line_width_bottom_right = 1;
267                         
268                         if (style == ButtonBorderStyle.Inset)
269                                 line_width_top_left = 2;
270                         if (style == ButtonBorderStyle.Outset) {
271                                 line_width_bottom_right = 2;
272                                 line_width_top_left = 2;
273                         }
274                         
275                         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);
276                 }
277
278                 public static void DrawBorder( Graphics graphics, Rectangle bounds, Color leftColor, int leftWidth,
279                         ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
280                         Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor, int bottomWidth,
281                         ButtonBorderStyle bottomStyle) {
282
283                         ThemeEngine.Current.CPDrawBorder (graphics, bounds, leftColor, leftWidth,
284                                 leftStyle, topColor, topWidth, topStyle, rightColor, rightWidth, rightStyle,
285                                 bottomColor, bottomWidth, bottomStyle);
286                 }
287
288
289                 public static void DrawBorder3D(Graphics graphics, Rectangle rectangle) {
290                         DrawBorder3D(graphics, rectangle, Border3DStyle.Etched, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
291                 }
292
293                 public static void DrawBorder3D(Graphics graphics, Rectangle rectangle, Border3DStyle style) {
294                         DrawBorder3D(graphics, rectangle, style, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
295                 }
296
297                 public static void DrawBorder3D(Graphics graphics, int x, int y, int width, int height) {
298                         DrawBorder3D(graphics, new Rectangle(x, y, width, height), Border3DStyle.Etched, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
299                 }
300
301                 public static void DrawBorder3D(Graphics graphics, int x, int y, int width, int height, Border3DStyle style) {
302                         DrawBorder3D(graphics, new Rectangle(x, y, width, height), style, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
303                 }
304
305                 public static void DrawBorder3D( Graphics graphics, int x, int y, int width, int height, Border3DStyle style,Border3DSide sides) {
306                         DrawBorder3D( graphics, new Rectangle(x, y, width, height), style, sides);
307                 }
308
309                 public static void DrawBorder3D( Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides) {
310
311                         ThemeEngine.Current.CPDrawBorder3D (graphics, rectangle, style, sides);
312                 }
313
314                 public static void DrawButton( Graphics graphics, int x, int y, int width, int height, ButtonState state) {
315                         DrawButton(graphics, new Rectangle(x, y, width, height), state);
316                 }
317
318                 public static void DrawButton( Graphics graphics, Rectangle rectangle, ButtonState state) {
319
320                         ThemeEngine.Current.CPDrawButton (graphics, rectangle, state);
321                 }
322
323
324                 public static void DrawCaptionButton(Graphics graphics, int x, int y, int width, int height, CaptionButton button, ButtonState state) {
325                         DrawCaptionButton(graphics, new Rectangle(x, y, width, height), button, state);
326                 }
327
328                 public static void DrawCaptionButton(Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state) {
329
330                         ThemeEngine.Current.CPDrawCaptionButton (graphics, rectangle, button, state);
331                 }
332
333                 public static void DrawCheckBox(Graphics graphics, int x, int y, int width, int height, ButtonState state) {
334                         DrawCheckBox(graphics, new Rectangle(x, y, width, height), state);
335                 }
336
337                 public static void DrawCheckBox(Graphics graphics, Rectangle rectangle, ButtonState state) {
338
339                         ThemeEngine.Current.CPDrawCheckBox (graphics, rectangle, state);
340                 }
341
342                 public static void DrawComboButton(Graphics graphics, Rectangle rectangle, ButtonState state) {
343
344                         ThemeEngine.Current.CPDrawComboButton (graphics, rectangle,  state);
345                 }
346
347                 public static void DrawComboButton(Graphics graphics, int x, int y, int width, int height, ButtonState state) {
348                         DrawComboButton(graphics, new Rectangle(x, y, width, height), state);
349                 }
350
351                 public static void DrawContainerGrabHandle(Graphics graphics, Rectangle bounds) {
352
353                         ThemeEngine.Current.CPDrawContainerGrabHandle (graphics, bounds);
354                 }
355
356                 public static void DrawFocusRectangle( Graphics graphics, Rectangle rectangle) {
357                         DrawFocusRectangle(graphics, rectangle, SystemColors.Control, SystemColors.ControlText);
358                 }
359
360                 public static void DrawFocusRectangle( Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor) {
361
362                         ThemeEngine.Current.CPDrawFocusRectangle (graphics, rectangle, foreColor, backColor);
363                 }
364
365                 public static void DrawGrabHandle(Graphics graphics, Rectangle rectangle, bool primary, bool enabled) {
366
367                         ThemeEngine.Current.CPDrawGrabHandle (graphics, rectangle, primary, enabled);
368                 }
369
370                 public static void DrawGrid(Graphics graphics, Rectangle area, Size pixelsBetweenDots, Color backColor) {
371
372                         ThemeEngine.Current.CPDrawGrid (graphics, area, pixelsBetweenDots, backColor);
373                 }
374
375                 public static void DrawImageDisabled(Graphics graphics, Image image, int x, int y, Color background) {
376
377                         ThemeEngine.Current.CPDrawImageDisabled (graphics, image, x, y, background);
378                 }
379
380                 public static void DrawLockedFrame(Graphics graphics, Rectangle rectangle, bool primary) {
381
382                         ThemeEngine.Current.CPDrawLockedFrame (graphics, rectangle, primary);
383                 }
384
385                 public static void DrawMenuGlyph(Graphics graphics, Rectangle rectangle, MenuGlyph glyph) {
386
387                         ThemeEngine.Current.CPDrawMenuGlyph (graphics, rectangle, glyph, ThemeEngine.Current.ColorMenuText);
388                 }
389
390                 public static void DrawMenuGlyph(Graphics graphics, int x, int y, int width, int height, MenuGlyph glyph) {
391                         DrawMenuGlyph(graphics, new Rectangle(x, y, width, height), glyph);
392                 }
393
394                 public static void DrawMixedCheckBox(Graphics graphics, Rectangle rectangle, ButtonState state) {
395                         DrawCheckBox(graphics, rectangle, state);
396                 }
397
398                 public static void DrawMixedCheckBox(Graphics graphics, int x, int y, int width, int height, ButtonState state) {
399                         DrawMixedCheckBox(graphics, new Rectangle(x, y, width, height), state);
400                 }
401
402
403                 public static void DrawRadioButton(Graphics graphics, int x, int y, int width, int height, ButtonState state) {
404                         DrawRadioButton(graphics, new Rectangle(x, y, width, height), state);
405                 }
406
407                 public static void DrawRadioButton(Graphics graphics, Rectangle rectangle, ButtonState state) {
408
409                         ThemeEngine.Current.CPDrawRadioButton (graphics, rectangle, state);
410                 }
411
412                 [MonoTODO("Figure out a good System.Drawing way for XOR drawing")]
413                 private static bool DRFNotImpl = false;
414                 public static void DrawReversibleFrame(Rectangle rectangle, Color backColor, FrameStyle style) {
415                         if (!DRFNotImpl) {
416                                 DRFNotImpl = 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 DRLNotImpl = false;
424                 public static void DrawReversibleLine(Point start, Point end, Color backColor) {
425                         if (!DRLNotImpl) {
426                                 DRLNotImpl = true;
427                                 Console.WriteLine("NOT IMPLEMENTED: FillReversibleRectangle(Rectangle rectangle, Color backColor)");
428                         }
429                         //throw new NotImplementedException();
430                 }
431
432                 [MonoTODO("Figure out a good System.Drawing way for XOR drawing")]
433                 private static bool FRRNotImpl = false;
434                 public static void FillReversibleRectangle(Rectangle rectangle, Color backColor) {
435                         if (!FRRNotImpl) {
436                                 FRRNotImpl = true;
437                                 Console.WriteLine("NOT IMPLEMENTED: FillReversibleRectangle(Rectangle rectangle, Color backColor)");
438                         }
439                         //throw new NotImplementedException();
440                 }
441
442
443                 public static void DrawScrollButton (Graphics graphics, int x, int y, int width, int height, ScrollButton button, ButtonState state) {
444                         ThemeEngine.Current.CPDrawScrollButton (graphics, new Rectangle(x, y, width, height), button, state);
445                 }
446
447                 public static void DrawScrollButton (Graphics graphics, Rectangle rectangle, ScrollButton button, ButtonState state) {
448                         ThemeEngine.Current.CPDrawScrollButton (graphics, rectangle, button, state);
449                 }
450
451                 [MonoTODO]
452                 private static bool DSFNotImpl = false;
453                 public static void DrawSelectionFrame(Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect, Color backColor) {
454                         if (!DSFNotImpl) {
455                                 DSFNotImpl = true;
456                                 Console.WriteLine("NOT IMPLEMENTED: DrawSelectionFrame(Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect, Color backColor)");
457                         }
458                         //throw new NotImplementedException();
459                 }
460
461                 public static void DrawSizeGrip (Graphics graphics, Color backColor, Rectangle bounds)
462                 {
463                         ThemeEngine.Current.CPDrawSizeGrip (graphics,  backColor,  bounds);
464                 }
465
466                 public static void DrawSizeGrip(Graphics graphics, Color backColor, int x, int y, int width, int height) {
467                         DrawSizeGrip(graphics, backColor, new Rectangle(x, y, width, height));
468                 }
469
470                 public static void DrawStringDisabled(Graphics graphics, string s, Font font, Color color, RectangleF layoutRectangle, StringFormat format) {
471
472                         ThemeEngine.Current.CPDrawStringDisabled (graphics, s, font, color, layoutRectangle, format);
473                 }
474                 #endregion      // Public Static Methods
475         }
476 }