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 // Jordi Mas i Hernandez, jordi@ximian.com
25 // This is an experimental GTK theme.
28 // - For now we would keep all the themes in the same assembly to have
29 // handy the internals methods.
30 // - We are using Pinovoke for now to access GTK/GDK to avoid adding
31 // gtk-sharp as a SWF dependency
32 // - The ThemeGtk comes from ThemeWin32Classic, we use it as the default
33 // implementation for the methods that we are not taking care of.
34 // - When GDK is initialised it opens its own display. There is not way of changing it,
35 // then we use that display as SWF display
36 // - You can activate this Theme in Linux doing export MONO_THEME=gtk
37 // - GTK paints controls into a window no a device context. We should inverstigate if we
38 // we can encapsulate a dc in a gtkwindow.
42 // $Log: ThemeGtk.cs,v $
43 // Revision 1.6 2004/09/28 18:44:25 pbartok
44 // - Streamlined Theme interfaces:
45 // * Each DrawXXX method for a control now is passed the object for the
46 // control to be drawn in order to allow accessing any state the theme
49 // * ControlPaint methods for the theme now have a CP prefix to avoid
50 // name clashes with the Draw methods for controls
52 // * Every control now retrieves it's DefaultSize from the current theme
54 // Revision 1.5 2004/09/02 16:32:54 jordi
55 // implements resource pool for pens, brushes, and hatchbruses
57 // Revision 1.4 2004/08/24 18:37:02 jordi
58 // fixes formmating, methods signature, and adds missing events
60 // Revision 1.3 2004/08/20 20:39:51 jordi
63 // Revision 1.2 2004/08/20 00:55:28 jordi
66 // Revision 1.1 2004/08/19 22:27:40 jordi
67 // experimental GTK theme support
74 using System
.Drawing
.Drawing2D
;
75 using System
.Drawing
.Imaging
;
76 using System
.Reflection
;
77 using System
.Runtime
.InteropServices
;
79 namespace System
.Windows
.Forms
81 internal class ThemeGtk
: ThemeWin32Classic
84 internal enum StateType
93 internal enum ShadowType
102 internal enum ArrowType
111 [StructLayout(LayoutKind
.Sequential
)]
112 internal struct GdkColorStruct
116 internal short green
;
120 [StructLayout(LayoutKind
.Sequential
)]
121 internal struct GtkStyleStruct
123 [MarshalAs(System
.Runtime
.InteropServices
.UnmanagedType
.ByValArray
, SizeConst
=12)]
124 internal byte[] obj
; /* GObject is 12 bytes*/
125 [MarshalAs(System
.Runtime
.InteropServices
.UnmanagedType
.ByValArray
, SizeConst
=5)]
126 internal GdkColorStruct
[] fg
;
127 [MarshalAs(System
.Runtime
.InteropServices
.UnmanagedType
.ByValArray
, SizeConst
=5)]
128 internal GdkColorStruct
[] bg
;
129 [MarshalAs(System
.Runtime
.InteropServices
.UnmanagedType
.ByValArray
, SizeConst
=5)]
130 internal GdkColorStruct
[] light
;
131 [MarshalAs(System
.Runtime
.InteropServices
.UnmanagedType
.ByValArray
, SizeConst
=5)]
132 internal GdkColorStruct
[] dark
;
133 [MarshalAs(System
.Runtime
.InteropServices
.UnmanagedType
.ByValArray
, SizeConst
=5)]
134 internal GdkColorStruct
[] mid
;
135 [MarshalAs(System
.Runtime
.InteropServices
.UnmanagedType
.ByValArray
, SizeConst
=5)]
136 internal GdkColorStruct
[] text
;
137 [MarshalAs(System
.Runtime
.InteropServices
.UnmanagedType
.ByValArray
, SizeConst
=5)]
138 internal GdkColorStruct
[] baseclr
;
139 [MarshalAs(System
.Runtime
.InteropServices
.UnmanagedType
.ByValArray
, SizeConst
=5)]
140 internal GdkColorStruct
[] text_aa
; /* Halfway between text/base */
142 internal GdkColorStruct black
;
143 internal GdkColorStruct white
;
145 /* TODO: There is more stuff that we will add when we need it*/
150 [DllImport("libgdk-x11-2.0.so")]
151 internal static extern IntPtr
gdk_display_manager_get ();
153 [DllImport("libgdk-x11-2.0.so")]
154 internal static extern IntPtr
gdk_display_manager_get_default_display (IntPtr display_manager
);
156 [DllImport("libgdk-x11-2.0.so")]
157 internal static extern void gdk_display_manager_set_default_display (IntPtr display_manager
, IntPtr display
);
159 [DllImport("libgdk-x11-2.0.so")]
160 internal static extern IntPtr
gdk_x11_display_get_xdisplay (IntPtr display
);
162 [DllImport("libgdk-x11-2.0.so")]
163 static extern IntPtr
gdk_window_foreign_new_for_display (IntPtr display
, uint anid
);
165 [DllImport("libgdk-x11-2.0.so")]
166 static extern bool gdk_init_check(out int argc
, string argv
);
169 [DllImport("libgtk-x11-2.0.so")]
170 static extern bool gtk_init_check (out int argc
, string argv
);
172 [DllImport("libgtk-x11-2.0.so")]
173 static extern IntPtr
gtk_adjustment_new (double value, double lower
, double upper
, double step_increment
, double page_increment
, double page_size
);
175 [DllImport("libgtk-x11-2.0.so")]
176 static extern IntPtr
gtk_rc_get_style (IntPtr widget
);
178 [DllImport("libgtk-x11-2.0.so")]
179 static extern IntPtr
gtk_vscrollbar_new(IntPtr adjustment
);
181 [DllImport("libgtk-x11-2.0.so")]
182 static extern IntPtr
gtk_style_attach (IntPtr raw
, IntPtr window
);
184 [DllImport("libgtk-x11-2.0.so")]
185 static extern IntPtr
gtk_rc_style_new ();
187 [DllImport("libgtk-x11-2.0.so")]
188 static extern IntPtr
gtk_invisible_new ();
190 [DllImport("libgtk-x11-2.0.so")]
191 static extern void gtk_widget_ensure_style (IntPtr raw
);
193 [DllImport("libgtk-x11-2.0.so")]
194 static extern IntPtr
gtk_widget_get_style (IntPtr raw
);
196 [DllImport("libgtk-x11-2.0.so")]
197 static extern void gtk_style_detach (IntPtr raw
);
200 [DllImport("libgtk-x11-2.0.so")]
201 static extern void gtk_paint_handle (IntPtr style
, IntPtr window
, int state_type
, int shadow_type
, IntPtr area
, IntPtr widget
, string detail
, int x
, int y
, int width
, int height
, int orientation
);
203 [DllImport("libgtk-x11-2.0.so")]
204 static extern void gtk_paint_arrow (IntPtr style
, IntPtr window
, int state_type
, int shadow_type
,
205 IntPtr area
, IntPtr widget
, string detail
, int arrow_type
, bool fill
, int x
, int y
, int width
, int height
);
207 [DllImport("libgtk-x11-2.0.so")]
208 static extern void gtk_paint_slider(IntPtr style
, IntPtr window
, int state_type
, int shadow_type
,
209 IntPtr area
, IntPtr widget
, string detail
, int x
, int y
, int width
, int height
, int orientation
);
211 [DllImport("libgtk-x11-2.0.so")]
212 static extern void gtk_paint_box(IntPtr style
, IntPtr window
, int state_type
, int shadow_type
,
213 IntPtr area
, IntPtr widget
, string detail
, int x
, int y
, int width
, int height
);
216 static protected IntPtr dispmgr
;
217 static protected IntPtr gdkdisplay
;
218 static protected IntPtr widget
;
219 static protected IntPtr style
;
220 static protected SolidBrush br_buttonface
;
221 static protected SolidBrush br_buttontext
;
223 public static void InitGtk ()
225 Console
.WriteLine ("ThemeGtk Init");
229 gdk_init_check (out argc
, argv
);
231 dispmgr
= gdk_display_manager_get ();
232 gdkdisplay
= gdk_display_manager_get_default_display (dispmgr
);
233 gtk_init_check (out argc
, argv
);
235 widget
= gtk_invisible_new ();
236 gtk_widget_ensure_style (widget
);
237 style
= gtk_widget_get_style (widget
);
239 XplatUIX11
.SetDisplay (gdk_x11_display_get_xdisplay (gdkdisplay
));
242 public void LoadSysDefaultColors ()
244 GtkStyleStruct style_struct
;
246 style_struct
= (GtkStyleStruct
) Marshal
.PtrToStructure (style
, typeof (GtkStyleStruct
));
247 defaultWindowBackColor
= ColorFromGdkColor (style_struct
.bg
[0]);
248 defaultWindowForeColor
= ColorFromGdkColor (style_struct
.fg
[0]);
251 public ThemeGtk () : base ()
253 Console
.WriteLine ("ThemeGtk constructor");
255 default_font
= new Font (FontFamily
.GenericSansSerif
, 8.25f
);
257 LoadSysDefaultColors ();
259 br_buttonface
= new SolidBrush (defaultWindowBackColor
);
260 br_buttontext
= new SolidBrush (defaultWindowForeColor
);
263 public override bool DoubleBufferingSupported
{
268 public void DrawScrollButton (Graphics dc
, Rectangle area
, ScrollButton type
, ButtonState state
,
269 IntPtr gdkwindow
, IntPtr style
)
271 ArrowType arrow_type
= 0;
273 gtk_paint_box (style
,
275 (int) StateType
.Normal
,
276 (int) ShadowType
.Out
,
281 area
.Width
, area
.Height
);
283 /* Calc arrows coordinates */
285 case ScrollButton
.Up
:
286 arrow_type
= ArrowType
.Up
;
288 case ScrollButton
.Down
:
289 arrow_type
= ArrowType
.Down
;
291 case ScrollButton
.Right
:
292 arrow_type
= ArrowType
.Right
;
294 case ScrollButton
.Left
:
295 arrow_type
= ArrowType
.Left
;
302 gtk_paint_arrow (style
,
304 (int) StateType
.Normal
,
309 (int) arrow_type
, true,
310 area
.X
+ ((area
.Width
- (area
.Width
/2) ) / 2),
311 area
.Y
+ ((area
.Height
- (area
.Height
/2) ) / 2),
312 area
.Width
/ 2, area
.Height
/ 2);
316 public override void DrawScrollBar (Graphics dc
, Rectangle area
, ScrollBar bar
,
317 ref Rectangle thumb_pos
, ref Rectangle first_arrow_area
, ref Rectangle second_arrow_area
,
318 ButtonState first_arrow
, ButtonState second_arrow
, ref int scrollbutton_width
,
319 ref int scrollbutton_height
, bool vert
)
321 IntPtr gdkwindow
= gdk_window_foreign_new_for_display (gdkdisplay
, (uint) bar
.Handle
);
322 IntPtr adj
= gtk_adjustment_new (0, 0, 0, 0, 0, 0);
323 IntPtr scrollbar
= gtk_vscrollbar_new (adj
);
326 style
= gtk_rc_get_style (scrollbar
);
327 style
= gtk_style_attach (style
, gdkwindow
); // need it
330 gtk_paint_box (style
,
332 (int) StateType
.Active
,
338 area
.Width
, area
.Height
);
340 /* See gtk_range_expose */
341 first_arrow_area
.X
= first_arrow_area
. Y
= 0;
342 first_arrow_area
.Width
= scrollbutton_width
;
343 first_arrow_area
.Height
= scrollbutton_height
;
347 second_arrow_area
.X
= 0;
348 second_arrow_area
.Y
= area
.Height
- scrollbutton_height
;
349 second_arrow_area
.Width
= scrollbutton_width
;
350 second_arrow_area
.Height
= scrollbutton_height
;
353 DrawScrollButton (dc
, first_arrow_area
, ScrollButton
.Up
, first_arrow
,
357 DrawScrollButton (dc
, second_arrow_area
, ScrollButton
.Down
, second_arrow
,
362 second_arrow_area
.Y
= 0;
363 second_arrow_area
.X
= area
.Width
- scrollbutton_width
;
364 second_arrow_area
.Width
= scrollbutton_width
;
365 second_arrow_area
.Height
= scrollbutton_height
;
368 DrawScrollButton (dc
, first_arrow_area
, ScrollButton
.Left
, first_arrow
,
372 DrawScrollButton (dc
, second_arrow_area
, ScrollButton
.Right
, second_arrow
,
378 gtk_paint_slider (style
,
380 (int) StateType
.Normal
,
381 (int) ShadowType
.Out
,
385 thumb_pos
.X
, thumb_pos
.Y
,
386 thumb_pos
.Width
, thumb_pos
.Height
,
387 (int) Orientation
.Vertical
);
389 //gtk_style_detach (style);
393 private static Color
ColorFromGdkColor (GdkColorStruct gtkcolor
)
395 return Color
.FromArgb (255,
396 (gtkcolor
.red
>> 8) & 0xff,
397 (gtkcolor
.green
>> 8) & 0xff,
398 (gtkcolor
.blue
>> 8) & 0xff );