ThemeGtk.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  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. // Jordi Mas i Hernandez, [email protected]
  24. //
  25. // This is an experimental GTK theme.
  26. //
  27. // Comments:
  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.
  39. //
  40. // $Revision: 1.6 $
  41. // $Modtime: $
  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
  47. // might require
  48. //
  49. // * ControlPaint methods for the theme now have a CP prefix to avoid
  50. // name clashes with the Draw methods for controls
  51. //
  52. // * Every control now retrieves it's DefaultSize from the current theme
  53. //
  54. // Revision 1.5 2004/09/02 16:32:54 jordi
  55. // implements resource pool for pens, brushes, and hatchbruses
  56. //
  57. // Revision 1.4 2004/08/24 18:37:02 jordi
  58. // fixes formmating, methods signature, and adds missing events
  59. //
  60. // Revision 1.3 2004/08/20 20:39:51 jordi
  61. // use style_attach
  62. //
  63. // Revision 1.2 2004/08/20 00:55:28 jordi
  64. // fixes button order
  65. //
  66. // Revision 1.1 2004/08/19 22:27:40 jordi
  67. // experimental GTK theme support
  68. //
  69. //
  70. // NOT COMPLETE
  71. using System;
  72. using System.Drawing;
  73. using System.Drawing.Drawing2D;
  74. using System.Drawing.Imaging;
  75. using System.Reflection;
  76. using System.Runtime.InteropServices;
  77. namespace System.Windows.Forms
  78. {
  79. internal class ThemeGtk : ThemeWin32Classic
  80. {
  81. /* GTK enums */
  82. internal enum StateType
  83. {
  84. Normal,
  85. Active,
  86. Prelight,
  87. Selected,
  88. Insensitive,
  89. }
  90. internal enum ShadowType
  91. {
  92. None,
  93. In,
  94. Out,
  95. EtchedIn,
  96. EtchedOut,
  97. }
  98. internal enum ArrowType
  99. {
  100. Up,
  101. Down,
  102. Left,
  103. Right,
  104. }
  105. /* Structs */
  106. [StructLayout(LayoutKind.Sequential)]
  107. internal struct GdkColorStruct
  108. {
  109. internal int pixel;
  110. internal short red;
  111. internal short green;
  112. internal short blue;
  113. }
  114. [StructLayout(LayoutKind.Sequential)]
  115. internal struct GtkStyleStruct
  116. {
  117. [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=12)]
  118. internal byte[] obj; /* GObject is 12 bytes*/
  119. [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
  120. internal GdkColorStruct[] fg;
  121. [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
  122. internal GdkColorStruct[] bg;
  123. [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
  124. internal GdkColorStruct[] light;
  125. [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
  126. internal GdkColorStruct[] dark;
  127. [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
  128. internal GdkColorStruct[] mid;
  129. [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
  130. internal GdkColorStruct[] text;
  131. [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
  132. internal GdkColorStruct[] baseclr;
  133. [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
  134. internal GdkColorStruct[] text_aa; /* Halfway between text/base */
  135. internal GdkColorStruct black;
  136. internal GdkColorStruct white;
  137. /* TODO: There is more stuff that we will add when we need it*/
  138. }
  139. /* GDK imports */
  140. [DllImport("libgdk-x11-2.0.so")]
  141. 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);
  144. [DllImport("libgdk-x11-2.0.so")]
  145. internal static extern void gdk_display_manager_set_default_display (IntPtr display_manager, IntPtr display);
  146. [DllImport("libgdk-x11-2.0.so")]
  147. internal static extern IntPtr gdk_x11_display_get_xdisplay (IntPtr display);
  148. [DllImport("libgdk-x11-2.0.so")]
  149. static extern IntPtr gdk_window_foreign_new_for_display (IntPtr display, uint anid);
  150. [DllImport("libgdk-x11-2.0.so")]
  151. static extern bool gdk_init_check(out int argc, string argv);
  152. /* GTK imports */
  153. [DllImport("libgtk-x11-2.0.so")]
  154. static extern bool gtk_init_check (out int argc, string argv);
  155. [DllImport("libgtk-x11-2.0.so")]
  156. static extern IntPtr gtk_adjustment_new (double value, double lower, double upper, double step_increment, double page_increment, double page_size);
  157. [DllImport("libgtk-x11-2.0.so")]
  158. static extern IntPtr gtk_rc_get_style (IntPtr widget);
  159. [DllImport("libgtk-x11-2.0.so")]
  160. static extern IntPtr gtk_vscrollbar_new(IntPtr adjustment);
  161. [DllImport("libgtk-x11-2.0.so")]
  162. static extern IntPtr gtk_style_attach (IntPtr raw, IntPtr window);
  163. [DllImport("libgtk-x11-2.0.so")]
  164. static extern IntPtr gtk_rc_style_new ();
  165. [DllImport("libgtk-x11-2.0.so")]
  166. static extern IntPtr gtk_invisible_new ();
  167. [DllImport("libgtk-x11-2.0.so")]
  168. static extern void gtk_widget_ensure_style (IntPtr raw);
  169. [DllImport("libgtk-x11-2.0.so")]
  170. static extern IntPtr gtk_widget_get_style (IntPtr raw);
  171. [DllImport("libgtk-x11-2.0.so")]
  172. static extern void gtk_style_detach (IntPtr raw);
  173. /* GTK Drawing */
  174. [DllImport("libgtk-x11-2.0.so")]
  175. 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);
  176. [DllImport("libgtk-x11-2.0.so")]
  177. static extern void gtk_paint_arrow (IntPtr style, IntPtr window, int state_type, int shadow_type,
  178. IntPtr area, IntPtr widget, string detail, int arrow_type, bool fill, int x, int y, int width, int height);
  179. [DllImport("libgtk-x11-2.0.so")]
  180. static extern void gtk_paint_slider(IntPtr style, IntPtr window, int state_type, int shadow_type,
  181. IntPtr area, IntPtr widget, string detail, int x, int y, int width, int height, int orientation);
  182. [DllImport("libgtk-x11-2.0.so")]
  183. static extern void gtk_paint_box(IntPtr style, IntPtr window, int state_type, int shadow_type,
  184. IntPtr area, IntPtr widget, string detail, int x, int y, int width, int height);
  185. /* Data */
  186. static protected IntPtr dispmgr;
  187. static protected IntPtr gdkdisplay;
  188. static protected IntPtr widget;
  189. static protected IntPtr style;
  190. static protected SolidBrush br_buttonface;
  191. static protected SolidBrush br_buttontext;
  192. public static void InitGtk ()
  193. {
  194. Console.WriteLine ("ThemeGtk Init");
  195. int argc = 0;
  196. string argv = "";
  197. gdk_init_check (out argc, argv);
  198. dispmgr = gdk_display_manager_get ();
  199. gdkdisplay = gdk_display_manager_get_default_display (dispmgr);
  200. gtk_init_check (out argc, argv);
  201. widget = gtk_invisible_new ();
  202. gtk_widget_ensure_style (widget);
  203. style = gtk_widget_get_style (widget);
  204. XplatUIX11.SetDisplay (gdk_x11_display_get_xdisplay (gdkdisplay));
  205. }
  206. public void LoadSysDefaultColors ()
  207. {
  208. GtkStyleStruct style_struct;
  209. style_struct = (GtkStyleStruct) Marshal.PtrToStructure (style, typeof (GtkStyleStruct));
  210. defaultWindowBackColor = ColorFromGdkColor (style_struct.bg[0]);
  211. defaultWindowForeColor = ColorFromGdkColor (style_struct.fg[0]);
  212. }
  213. public ThemeGtk () : base ()
  214. {
  215. Console.WriteLine ("ThemeGtk constructor");
  216. InitGtk ();
  217. default_font = new Font (FontFamily.GenericSansSerif, 8.25f);
  218. LoadSysDefaultColors ();
  219. br_buttonface = new SolidBrush (defaultWindowBackColor);
  220. br_buttontext = new SolidBrush (defaultWindowForeColor);
  221. }
  222. public override bool DoubleBufferingSupported {
  223. get {return false; }
  224. }
  225. public void DrawScrollButton (Graphics dc, Rectangle area, ScrollButton type, ButtonState state,
  226. IntPtr gdkwindow, IntPtr style)
  227. {
  228. ArrowType arrow_type = 0;
  229. gtk_paint_box (style,
  230. gdkwindow,
  231. (int) StateType.Normal,
  232. (int) ShadowType.Out,
  233. IntPtr.Zero,
  234. IntPtr.Zero,
  235. "trough",
  236. area.X, area.Y,
  237. area.Width, area.Height);
  238. /* Calc arrows coordinates */
  239. switch (type) {
  240. case ScrollButton.Up:
  241. arrow_type = ArrowType.Up;
  242. break;
  243. case ScrollButton.Down:
  244. arrow_type = ArrowType.Down;
  245. break;
  246. case ScrollButton.Right:
  247. arrow_type = ArrowType.Right;
  248. break;
  249. case ScrollButton.Left:
  250. arrow_type = ArrowType.Left;
  251. break;
  252. default:
  253. break;
  254. }
  255. gtk_paint_arrow (style,
  256. gdkwindow,
  257. (int) StateType.Normal,
  258. (int) ShadowType.In,
  259. IntPtr.Zero,
  260. IntPtr.Zero,
  261. "",
  262. (int) arrow_type, true,
  263. area.X + ((area.Width - (area.Width/2) ) / 2),
  264. area.Y + ((area.Height - (area.Height/2) ) / 2),
  265. area.Width / 2, area.Height / 2);
  266. }
  267. #if updated
  268. public override void DrawScrollBar (Graphics dc, Rectangle area, ScrollBar bar,
  269. ref Rectangle thumb_pos, ref Rectangle first_arrow_area, ref Rectangle second_arrow_area,
  270. ButtonState first_arrow, ButtonState second_arrow, ref int scrollbutton_width,
  271. ref int scrollbutton_height, bool vert)
  272. {
  273. IntPtr gdkwindow = gdk_window_foreign_new_for_display (gdkdisplay, (uint) bar.Handle);
  274. IntPtr adj = gtk_adjustment_new (0, 0, 0, 0, 0, 0);
  275. IntPtr scrollbar = gtk_vscrollbar_new (adj);
  276. IntPtr style;
  277. style = gtk_rc_get_style (scrollbar);
  278. style = gtk_style_attach (style, gdkwindow); // need it
  279. /* Background */
  280. gtk_paint_box (style,
  281. gdkwindow,
  282. (int) StateType.Active,
  283. (int) ShadowType.In,
  284. IntPtr.Zero,
  285. IntPtr.Zero,
  286. "trough",
  287. area.X, area.Y,
  288. area.Width, area.Height);
  289. /* See gtk_range_expose */
  290. first_arrow_area.X = first_arrow_area. Y = 0;
  291. first_arrow_area.Width = scrollbutton_width;
  292. first_arrow_area.Height = scrollbutton_height;
  293. if (vert) {
  294. second_arrow_area.X = 0;
  295. second_arrow_area.Y = area.Height - scrollbutton_height;
  296. second_arrow_area.Width = scrollbutton_width;
  297. second_arrow_area.Height = scrollbutton_height;
  298. /* First button*/
  299. DrawScrollButton (dc, first_arrow_area, ScrollButton.Up, first_arrow,
  300. gdkwindow, style);
  301. /* Second button*/
  302. DrawScrollButton (dc, second_arrow_area, ScrollButton.Down, second_arrow,
  303. gdkwindow, style);
  304. } else {
  305. second_arrow_area.Y = 0;
  306. second_arrow_area.X = area.Width - scrollbutton_width;
  307. second_arrow_area.Width = scrollbutton_width;
  308. second_arrow_area.Height = scrollbutton_height;
  309. /* First button*/
  310. DrawScrollButton (dc, first_arrow_area, ScrollButton.Left, first_arrow,
  311. gdkwindow, style);
  312. /* Second button*/
  313. DrawScrollButton (dc, second_arrow_area, ScrollButton.Right, second_arrow,
  314. gdkwindow, style);
  315. }
  316. /* Slider */
  317. gtk_paint_slider (style,
  318. gdkwindow,
  319. (int) StateType.Normal,
  320. (int) ShadowType.Out,
  321. IntPtr.Zero,
  322. IntPtr.Zero,
  323. "",
  324. thumb_pos.X, thumb_pos.Y,
  325. thumb_pos.Width, thumb_pos.Height,
  326. (int) Orientation.Vertical);
  327. //gtk_style_detach (style);
  328. }
  329. #endif
  330. private static Color ColorFromGdkColor (GdkColorStruct gtkcolor)
  331. {
  332. return Color.FromArgb (255,
  333. (gtkcolor.red >> 8) & 0xff,
  334. (gtkcolor.green >> 8) & 0xff,
  335. (gtkcolor.blue >> 8) & 0xff );
  336. }
  337. } //class
  338. }