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.5 2004/09/02 16:32:54 jordi
44 // implements resource pool for pens, brushes, and hatchbruses
46 // Revision 1.4 2004/08/24 18:37:02 jordi
47 // fixes formmating, methods signature, and adds missing events
49 // Revision 1.3 2004/08/20 20:39:51 jordi
52 // Revision 1.2 2004/08/20 00:55:28 jordi
55 // Revision 1.1 2004/08/19 22:27:40 jordi
56 // experimental GTK theme support
63 using System.Drawing.Drawing2D;
64 using System.Drawing.Imaging;
65 using System.Reflection;
66 using System.Runtime.InteropServices;
68 namespace System.Windows.Forms
70 internal class ThemeGtk : ThemeWin32Classic
73 internal enum StateType
82 internal enum ShadowType
91 internal enum ArrowType
100 [StructLayout(LayoutKind.Sequential)]
101 internal struct GdkColorStruct
105 internal short green;
109 [StructLayout(LayoutKind.Sequential)]
110 internal struct GtkStyleStruct
112 [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=12)]
113 internal byte[] obj; /* GObject is 12 bytes*/
114 [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
115 internal GdkColorStruct[] fg;
116 [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
117 internal GdkColorStruct[] bg;
118 [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
119 internal GdkColorStruct[] light;
120 [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
121 internal GdkColorStruct[] dark;
122 [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
123 internal GdkColorStruct[] mid;
124 [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
125 internal GdkColorStruct[] text;
126 [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
127 internal GdkColorStruct[] baseclr;
128 [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
129 internal GdkColorStruct[] text_aa; /* Halfway between text/base */
131 internal GdkColorStruct black;
132 internal GdkColorStruct white;
134 /* TODO: There is more stuff that we will add when we need it*/
139 [DllImport("libgdk-x11-2.0.so")]
140 internal static extern IntPtr gdk_display_manager_get ();
142 [DllImport("libgdk-x11-2.0.so")]
143 internal static extern IntPtr gdk_display_manager_get_default_display (IntPtr display_manager);
145 [DllImport("libgdk-x11-2.0.so")]
146 internal static extern void gdk_display_manager_set_default_display (IntPtr display_manager, IntPtr display);
148 [DllImport("libgdk-x11-2.0.so")]
149 internal static extern IntPtr gdk_x11_display_get_xdisplay (IntPtr display);
151 [DllImport("libgdk-x11-2.0.so")]
152 static extern IntPtr gdk_window_foreign_new_for_display (IntPtr display, uint anid);
154 [DllImport("libgdk-x11-2.0.so")]
155 static extern bool gdk_init_check(out int argc, string argv);
158 [DllImport("libgtk-x11-2.0.so")]
159 static extern bool gtk_init_check (out int argc, string argv);
161 [DllImport("libgtk-x11-2.0.so")]
162 static extern IntPtr gtk_adjustment_new (double value, double lower, double upper, double step_increment, double page_increment, double page_size);
164 [DllImport("libgtk-x11-2.0.so")]
165 static extern IntPtr gtk_rc_get_style (IntPtr widget);
167 [DllImport("libgtk-x11-2.0.so")]
168 static extern IntPtr gtk_vscrollbar_new(IntPtr adjustment);
170 [DllImport("libgtk-x11-2.0.so")]
171 static extern IntPtr gtk_style_attach (IntPtr raw, IntPtr window);
173 [DllImport("libgtk-x11-2.0.so")]
174 static extern IntPtr gtk_rc_style_new ();
176 [DllImport("libgtk-x11-2.0.so")]
177 static extern IntPtr gtk_invisible_new ();
179 [DllImport("libgtk-x11-2.0.so")]
180 static extern void gtk_widget_ensure_style (IntPtr raw);
182 [DllImport("libgtk-x11-2.0.so")]
183 static extern IntPtr gtk_widget_get_style (IntPtr raw);
185 [DllImport("libgtk-x11-2.0.so")]
186 static extern void gtk_style_detach (IntPtr raw);
189 [DllImport("libgtk-x11-2.0.so")]
190 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);
192 [DllImport("libgtk-x11-2.0.so")]
193 static extern void gtk_paint_arrow (IntPtr style, IntPtr window, int state_type, int shadow_type,
194 IntPtr area, IntPtr widget, string detail, int arrow_type, bool fill, int x, int y, int width, int height);
196 [DllImport("libgtk-x11-2.0.so")]
197 static extern void gtk_paint_slider(IntPtr style, IntPtr window, int state_type, int shadow_type,
198 IntPtr area, IntPtr widget, string detail, int x, int y, int width, int height, int orientation);
200 [DllImport("libgtk-x11-2.0.so")]
201 static extern void gtk_paint_box(IntPtr style, IntPtr window, int state_type, int shadow_type,
202 IntPtr area, IntPtr widget, string detail, int x, int y, int width, int height);
205 static protected IntPtr dispmgr;
206 static protected IntPtr gdkdisplay;
207 static protected IntPtr widget;
208 static protected IntPtr style;
209 static protected SolidBrush br_buttonface;
210 static protected SolidBrush br_buttontext;
212 public static void InitGtk ()
214 Console.WriteLine ("ThemeGtk Init");
218 gdk_init_check (out argc, argv);
220 dispmgr = gdk_display_manager_get ();
221 gdkdisplay = gdk_display_manager_get_default_display (dispmgr);
222 gtk_init_check (out argc, argv);
224 widget = gtk_invisible_new ();
225 gtk_widget_ensure_style (widget);
226 style = gtk_widget_get_style (widget);
228 XplatUIX11.SetDisplay (gdk_x11_display_get_xdisplay (gdkdisplay));
231 public void LoadSysDefaultColors ()
233 GtkStyleStruct style_struct;
235 style_struct = (GtkStyleStruct) Marshal.PtrToStructure (style, typeof (GtkStyleStruct));
236 defaultWindowBackColor = ColorFromGdkColor (style_struct.bg[0]);
237 defaultWindowForeColor = ColorFromGdkColor (style_struct.fg[0]);
240 public ThemeGtk () : base ()
242 Console.WriteLine ("ThemeGtk constructor");
244 default_font = new Font (FontFamily.GenericSansSerif, 8.25f);
246 LoadSysDefaultColors ();
248 br_buttonface = new SolidBrush (defaultWindowBackColor);
249 br_buttontext = new SolidBrush (defaultWindowForeColor);
252 public override bool WriteToWindow {
257 public void DrawScrollButton (Graphics dc, Rectangle area, ScrollButton type, ButtonState state,
258 IntPtr gdkwindow, IntPtr style)
260 ArrowType arrow_type = 0;
262 gtk_paint_box (style,
264 (int) StateType.Normal,
265 (int) ShadowType.Out,
270 area.Width, area.Height);
272 /* Calc arrows coordinates */
274 case ScrollButton.Up:
275 arrow_type = ArrowType.Up;
277 case ScrollButton.Down:
278 arrow_type = ArrowType.Down;
280 case ScrollButton.Right:
281 arrow_type = ArrowType.Right;
283 case ScrollButton.Left:
284 arrow_type = ArrowType.Left;
291 gtk_paint_arrow (style,
293 (int) StateType.Normal,
298 (int) arrow_type, true,
299 area.X + ((area.Width - (area.Width/2) ) / 2),
300 area.Y + ((area.Height - (area.Height/2) ) / 2),
301 area.Width / 2, area.Height / 2);
305 public override void DrawScrollBar (Graphics dc, Rectangle area, ScrollBar bar,
306 ref Rectangle thumb_pos, ref Rectangle first_arrow_area, ref Rectangle second_arrow_area,
307 ButtonState first_arrow, ButtonState second_arrow, ref int scrollbutton_width,
308 ref int scrollbutton_height, bool vert)
310 IntPtr gdkwindow = gdk_window_foreign_new_for_display (gdkdisplay, (uint) bar.Handle);
311 IntPtr adj = gtk_adjustment_new (0, 0, 0, 0, 0, 0);
312 IntPtr scrollbar = gtk_vscrollbar_new (adj);
315 style = gtk_rc_get_style (scrollbar);
316 style = gtk_style_attach (style, gdkwindow); // need it
319 gtk_paint_box (style,
321 (int) StateType.Active,
327 area.Width, area.Height);
329 /* See gtk_range_expose */
330 first_arrow_area.X = first_arrow_area. Y = 0;
331 first_arrow_area.Width = scrollbutton_width;
332 first_arrow_area.Height = scrollbutton_height;
336 second_arrow_area.X = 0;
337 second_arrow_area.Y = area.Height - scrollbutton_height;
338 second_arrow_area.Width = scrollbutton_width;
339 second_arrow_area.Height = scrollbutton_height;
342 DrawScrollButton (dc, first_arrow_area, ScrollButton.Up, first_arrow,
346 DrawScrollButton (dc, second_arrow_area, ScrollButton.Down, second_arrow,
351 second_arrow_area.Y = 0;
352 second_arrow_area.X = area.Width - scrollbutton_width;
353 second_arrow_area.Width = scrollbutton_width;
354 second_arrow_area.Height = scrollbutton_height;
357 DrawScrollButton (dc, first_arrow_area, ScrollButton.Left, first_arrow,
361 DrawScrollButton (dc, second_arrow_area, ScrollButton.Right, second_arrow,
367 gtk_paint_slider (style,
369 (int) StateType.Normal,
370 (int) ShadowType.Out,
374 thumb_pos.X, thumb_pos.Y,
375 thumb_pos.Width, thumb_pos.Height,
376 (int) Orientation.Vertical);
378 //gtk_style_detach (style);
382 private static Color ColorFromGdkColor (GdkColorStruct gtkcolor)
384 return Color.FromArgb (255,
385 (gtkcolor.red >> 8) & 0xff,
386 (gtkcolor.green >> 8) & 0xff,
387 (gtkcolor.blue >> 8) & 0xff );