diff options
Diffstat (limited to 'mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeGtk.cs')
-rw-r--r-- | mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeGtk.cs | 1593 |
1 files changed, 1593 insertions, 0 deletions
diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeGtk.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeGtk.cs new file mode 100644 index 00000000000..b5540b6c20a --- /dev/null +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeGtk.cs @@ -0,0 +1,1593 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2004-2006 Novell, Inc. +// +// Authors: +// Jordi Mas i Hernandez, jordi@ximian.com +// Alexander Olk, alex.olk@googlemail.com +// +// This is an experimental GTK theme. +// +// Comments: +// - For now we would keep all the themes in the same assembly to have +// handy the internals methods. +// - We are using Pinovoke for now to access GTK/GDK to avoid adding +// gtk-sharp as a SWF dependency +// - The ThemeGtk comes from ThemeWin32Classic, we use it as the default +// implementation for the methods that we are not taking care of. +// - When GDK is initialised it opens its own display. There is not way of changing it, +// then we use that display as SWF display +// - You can activate this Theme in Linux doing export MONO_THEME=gtk +// - GTK paints controls into a window not a device context. We should inverstigate if we +// we can encapsulate a dc in a gtkwindow. + + +// NOT COMPLETE + +// TODO: - fix position of button focus rectangle +// - fix TrackBar drawing location + + +//#define _EXPERIMENTAL_ + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Reflection; +using System.Runtime.InteropServices; +using System.IO; + +namespace System.Windows.Forms +{ + internal class ThemeGtk : ThemeWin32Classic + { + /* GTK enums */ + internal enum StateType + { + Normal, + Active, + Prelight, + Selected, + Insensitive, + } + + internal enum ShadowType + { + None, + In, + Out, + EtchedIn, + EtchedOut, + } + + internal enum ArrowType + { + Up, + Down, + Left, + Right, + } + + /* Structs */ + [StructLayout(LayoutKind.Sequential)] + internal struct GdkColorStruct + { + internal int pixel; + internal short red; + internal short green; + internal short blue; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct GObjectStruct { + IntPtr Instance; + IntPtr ref_count; + IntPtr data; + } + + + [StructLayout(LayoutKind.Sequential)] + internal struct GtkStyleStruct + { + internal GObjectStruct obj; + [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)] + internal GdkColorStruct[] fg; + [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)] + internal GdkColorStruct[] bg; + [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)] + internal GdkColorStruct[] light; + [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)] + internal GdkColorStruct[] dark; + [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)] + internal GdkColorStruct[] mid; + [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)] + internal GdkColorStruct[] text; + [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)] + internal GdkColorStruct[] baseclr; + [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)] + internal GdkColorStruct[] text_aa; /* Halfway between text/base */ + + internal GdkColorStruct black; + internal GdkColorStruct white; + + /* TODO: There is more stuff that we will add when we need it*/ + } + + /* GDK imports */ + [DllImport("libgdk-x11-2.0.so")] + internal static extern IntPtr gdk_display_manager_get (); + + [DllImport("libgdk-x11-2.0.so")] + internal static extern IntPtr gdk_display_manager_get_default_display (IntPtr display_manager); + + [DllImport("libgdk-x11-2.0.so")] + internal static extern void gdk_display_manager_set_default_display (IntPtr display_manager, IntPtr display); + + [DllImport("libgdk-x11-2.0.so")] + internal static extern IntPtr gdk_x11_display_get_xdisplay (IntPtr display); + + [DllImport("libgdk-x11-2.0.so")] + static extern IntPtr gdk_window_foreign_new_for_display (IntPtr display, uint anid); + + [DllImport("libgdk-x11-2.0.so")] + static extern bool gdk_init_check(out int argc, string argv); + + [DllImport("libgdk-x11-2.0.so")] + static extern IntPtr gdk_pixmap_new (IntPtr drawable, int width, int height, int depth); + + [DllImport("libgdk-x11-2.0.so")] + static extern IntPtr gdk_pixbuf_get_from_drawable (IntPtr dest, IntPtr drawable_src, IntPtr cmap, + int src_x, int src_y, int dest_x, int dest_y, int width, int height); + + [DllImport("libgdk-x11-2.0.so")] + static extern bool gdk_pixbuf_save_to_buffer (IntPtr pixbuf, out IntPtr buffer, out UIntPtr buffer_size, string type, out IntPtr error, IntPtr option_dummy); + + [DllImport("libgdk-x11-2.0.so")] + static extern IntPtr gdk_drawable_get_colormap (IntPtr drawable); + + [DllImport("libgdk-x11-2.0.so")] + static extern IntPtr gdk_colormap_get_system (); + + [DllImport("libgdk-x11-2.0.so")] + static extern IntPtr gdk_pixbuf_new (int colorspace, bool has_alpha, int bits_per_sample, int width, int height); + + [DllImport("libgdk-x11-2.0.so")] + static extern IntPtr gdk_gc_new (IntPtr drawable); + + /* glib imports*/ + [DllImport("libglib-2.0.so")] + static extern void g_free (IntPtr mem); + + [DllImport("libgobject-2.0.so")] + static extern void g_object_unref (IntPtr nativeObject); + + /* GTK imports */ + [DllImport("libgtk-x11-2.0.so")] + static extern bool gtk_init_check (out int argc, string argv); + + [DllImport("libgtk-x11-2.0.so")] + static extern IntPtr gtk_adjustment_new (double value, double lower, double upper, double step_increment, double page_increment, double page_size); + + [DllImport("libgtk-x11-2.0.so")] + static extern IntPtr gtk_rc_get_style (IntPtr widget); + + [DllImport("libgtk-x11-2.0.so")] + static extern IntPtr gtk_vscrollbar_new(IntPtr adjustment); + + [DllImport("libgtk-x11-2.0.so")] + static extern IntPtr gtk_hscrollbar_new(IntPtr adjustment); + + [DllImport("libgtk-x11-2.0.so")] + static extern IntPtr gtk_style_attach (IntPtr raw, IntPtr window); + + [DllImport("libgtk-x11-2.0.so")] + static extern IntPtr gtk_rc_style_new (); + + [DllImport("libgtk-x11-2.0.so")] + static extern IntPtr gtk_invisible_new (); + + [DllImport("libgtk-x11-2.0.so")] + static extern void gtk_widget_ensure_style (IntPtr raw); + + [DllImport("libgtk-x11-2.0.so")] + static extern IntPtr gtk_widget_get_style (IntPtr raw); + + [DllImport("libgtk-x11-2.0.so")] + static extern void gtk_style_detach (IntPtr raw); + + [DllImport("libgtk-x11-2.0.so")] + static extern IntPtr gtk_button_new (); + + [DllImport("libgtk-x11-2.0.so")] + static extern IntPtr gtk_progress_bar_new (); + + [DllImport("libgtk-x11-2.0.so")] + static extern IntPtr gtk_radio_button_new (IntPtr group); + + [DllImport("libgtk-x11-2.0.so")] + static extern IntPtr gtk_check_button_new (); + + [DllImport("libgtk-x11-2.0.so")] + static extern IntPtr gtk_hscale_new (IntPtr adjustment); + + [DllImport("libgtk-x11-2.0.so")] + static extern IntPtr gtk_vscale_new (IntPtr adjustment); + + [DllImport("libgtk-x11-2.0.so")] + static extern void gtk_range_set_range (IntPtr range, double min, double max); + + [DllImport("libgtk-x11-2.0.so")] + static extern void gtk_range_set_value (IntPtr range, double value); + + /* GTK Drawing */ + [DllImport("libgtk-x11-2.0.so")] + 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); + + [DllImport("libgtk-x11-2.0.so")] + static extern void gtk_paint_arrow (IntPtr style, IntPtr window, int state_type, int shadow_type, + IntPtr area, IntPtr widget, string detail, int arrow_type, bool fill, int x, int y, int width, int height); + + [DllImport("libgtk-x11-2.0.so")] + static extern void gtk_paint_slider (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); + + [DllImport("libgtk-x11-2.0.so")] + static extern void gtk_paint_box (IntPtr style, IntPtr window, int state_type, int shadow_type, + IntPtr area, IntPtr widget, string detail, int x, int y, int width, int height); + + [DllImport("libgtk-x11-2.0.so")] + static extern void gtk_paint_flat_box (IntPtr style, IntPtr window, int state_type, int shadow_type, + IntPtr area, IntPtr widget, string detail, int x, int y, int width, int height); + + [DllImport("libgtk-x11-2.0.so")] + static extern void gtk_paint_hline(IntPtr style, IntPtr window, int state_type, IntPtr area, IntPtr widget, string detail, int x1, int x2, int y); + + [DllImport("libgtk-x11-2.0.so")] + static extern void gtk_paint_vline(IntPtr style, IntPtr window, int state_type, IntPtr area, IntPtr widget, string detail, int y1, int y2, int x); + + [DllImport("libgtk-x11-2.0.so")] + static extern void gtk_paint_check(IntPtr style, IntPtr window, int state_type, int shadow_type, IntPtr area, IntPtr widget, string detail, int x, int y, int width, int height); + + [DllImport("libgtk-x11-2.0.so")] + static extern void gtk_paint_focus(IntPtr style, IntPtr window, int state_type, IntPtr area, IntPtr widget, string detail, int x, int y, int width, int height); + + [DllImport("libgtk-x11-2.0.so")] + static extern void gtk_widget_size_allocate (IntPtr widget, ref Rectangle allocation); + + [DllImport("libgtk-x11-2.0.so")] + static extern void gtk_paint_option (IntPtr style, IntPtr window, int state_type, int shadow_type, IntPtr area, IntPtr widget, string detail, int x, int y, int width, int height); + + [DllImport("libgtk-x11-2.0.so")] + static extern void gtk_widget_grab_focus (IntPtr widget); + + /* Data */ + static protected IntPtr dispmgr; + static protected IntPtr gdkdisplay; + static protected IntPtr widget; + static protected IntPtr global_style; + + #if _EXPERIMENTAL_ + static protected IntPtr global_color_map = IntPtr.Zero; + #endif + + static protected IntPtr global_gtk_button = IntPtr.Zero; + static protected IntPtr global_gtk_button_style = IntPtr.Zero; + + static protected IntPtr global_gtk_vscrollbar = IntPtr.Zero; + static protected IntPtr global_gtk_vscrollbar_style = IntPtr.Zero; + + static protected IntPtr global_gtk_hscrollbar = IntPtr.Zero; + static protected IntPtr global_gtk_hscrollbar_style = IntPtr.Zero; + + static protected IntPtr global_gtk_progress_bar = IntPtr.Zero; + static protected IntPtr global_gtk_progress_bar_style = IntPtr.Zero; + + static protected IntPtr global_gtk_radio_button = IntPtr.Zero; + static protected IntPtr global_gtk_radio_button_style = IntPtr.Zero; + + static protected IntPtr global_gtk_check_button = IntPtr.Zero; + static protected IntPtr global_gtk_check_button_style = IntPtr.Zero; + + static protected IntPtr global_gtk_hscale = IntPtr.Zero; + static protected IntPtr global_gtk_hscale_style = IntPtr.Zero; + + static protected IntPtr global_gtk_vscale = IntPtr.Zero; + static protected IntPtr global_gtk_vscale_style = IntPtr.Zero; + + static protected IntPtr current_gdk_drawable = IntPtr.Zero; + static protected IntPtr current_style = IntPtr.Zero; + static protected IntPtr current_widget = IntPtr.Zero; + + public static void InitGtk () + { + Console.WriteLine ("ThemeGtk Init"); + int argc = 0; + string argv = ""; + + gdk_init_check (out argc, argv); + + dispmgr = gdk_display_manager_get (); + gdkdisplay = gdk_display_manager_get_default_display (dispmgr); + gtk_init_check (out argc, argv); + + widget = gtk_invisible_new (); + gtk_widget_ensure_style (widget); + global_style = gtk_widget_get_style (widget); + + XplatUIX11.GetInstance().SetDisplay (gdk_x11_display_get_xdisplay (gdkdisplay)); + + global_gtk_button = gtk_button_new(); + gtk_widget_ensure_style (global_gtk_button); + global_gtk_button_style = gtk_rc_get_style (global_gtk_button); + + IntPtr adj = gtk_adjustment_new (0, 0, 0, 0, 0, 0); + global_gtk_vscrollbar = gtk_vscrollbar_new (adj); + gtk_widget_ensure_style (global_gtk_vscrollbar); + global_gtk_vscrollbar_style = gtk_rc_get_style (global_gtk_vscrollbar); + + global_gtk_hscrollbar = gtk_hscrollbar_new (adj); + gtk_widget_ensure_style (global_gtk_hscrollbar); + global_gtk_hscrollbar_style = gtk_rc_get_style (global_gtk_hscrollbar); + + global_gtk_progress_bar = gtk_progress_bar_new (); + gtk_widget_ensure_style (global_gtk_progress_bar); + global_gtk_progress_bar_style = gtk_rc_get_style (global_gtk_progress_bar); + + global_gtk_radio_button = gtk_radio_button_new (IntPtr.Zero); + gtk_widget_ensure_style (global_gtk_radio_button); + global_gtk_radio_button_style = gtk_rc_get_style (global_gtk_radio_button); + + global_gtk_check_button = gtk_check_button_new (); + gtk_widget_ensure_style (global_gtk_check_button); + global_gtk_check_button_style = gtk_rc_get_style (global_gtk_check_button); + + global_gtk_hscale = gtk_hscale_new (adj); + gtk_widget_ensure_style (global_gtk_hscale); + global_gtk_hscale_style = gtk_rc_get_style (global_gtk_hscale); + + global_gtk_vscale = gtk_vscale_new (adj); + gtk_widget_ensure_style (global_gtk_vscale); + global_gtk_vscale_style = gtk_rc_get_style (global_gtk_vscale); + + #if _EXPERIMENTAL_ + global_color_map = gdk_colormap_get_system (); + #endif + } + + public void LoadSysDefaultColors () + { + GtkStyleStruct style_struct; + + style_struct = (GtkStyleStruct) Marshal.PtrToStructure (global_style, typeof (GtkStyleStruct)); + defaultWindowBackColor = ColorFromGdkColor (style_struct.bg[0]); + defaultWindowForeColor = ColorFromGdkColor (style_struct.fg[0]); + } + + public ThemeGtk () : base () + { + Console.WriteLine ("ThemeGtk constructor"); + InitGtk (); + default_font = new Font (FontFamily.GenericSansSerif, 8.25f); + + LoadSysDefaultColors (); + + always_draw_hotkeys = true; + } + + public override bool DoubleBufferingSupported { + #if _EXPERIMENTAL_ + get {return true; } + #else + get {return false; } + #endif + } + + private void SetDrawableAndStyle (Control control) + { + #if _EXPERIMENTAL_ + if (current_gdk_drawable != IntPtr.Zero) { + g_object_unref (current_gdk_drawable); + current_gdk_drawable = IntPtr.Zero; + } + current_gdk_drawable = gdk_pixmap_new (IntPtr.Zero, control.ClientRectangle.Width, control.ClientRectangle.Height, 24); + #else + current_gdk_drawable = gdk_window_foreign_new_for_display (gdkdisplay, (uint) control.Handle); + #endif + + IntPtr tmp_style = IntPtr.Zero; + + if (control is ButtonBase) { + tmp_style = global_gtk_button_style; + current_widget = global_gtk_button; + } else + if (control is ScrollBar) { + ScrollBar bar = control as ScrollBar; + if (bar.vert) { + tmp_style = global_gtk_vscrollbar_style; + current_widget = global_gtk_vscrollbar; + } else { + tmp_style = global_gtk_hscrollbar_style; + current_widget = global_gtk_hscrollbar; + } + } else + if (control is ProgressBar) { + tmp_style = global_gtk_progress_bar_style; + current_widget = global_gtk_progress_bar; + } else + if (control is RadioButton) { + tmp_style = global_gtk_radio_button_style; + current_widget = global_gtk_radio_button; + } else + if (control is CheckBox) { + tmp_style = global_gtk_check_button_style; + current_widget = global_gtk_check_button; + } else + if (control is TrackBar) { + TrackBar bar = control as TrackBar; + if (bar.Orientation == Orientation.Vertical) { + tmp_style = global_gtk_vscale_style; + current_widget = global_gtk_vscale; + } else { + tmp_style = global_gtk_hscale_style; + current_widget = global_gtk_hscale; + } + } else + tmp_style = global_style; + + current_style = gtk_style_attach (tmp_style, current_gdk_drawable); // need it + } + + #if _EXPERIMENTAL_ + private void SetDrawableAndStyle (Rectangle area, Type type, Orientation orientation) + { + if (current_gdk_drawable != IntPtr.Zero) { + g_object_unref (current_gdk_drawable); + current_gdk_drawable = IntPtr.Zero; + } + current_gdk_drawable = gdk_pixmap_new (IntPtr.Zero, area.Width, area.Height, 24); + + IntPtr tmp_style = IntPtr.Zero; + + if (type == typeof(ButtonBase)) { + tmp_style = global_gtk_button_style; + current_widget = global_gtk_button; + } else + if (type == typeof(ScrollBar)) { + if (orientation == Orientation.Vertical) { + tmp_style = global_gtk_vscrollbar_style; + current_widget = global_gtk_vscrollbar; + } else { + tmp_style = global_gtk_hscrollbar_style; + current_widget = global_gtk_hscrollbar; + } + } else + if (type == typeof(ProgressBar)) { + tmp_style = global_gtk_progress_bar_style; + current_widget = global_gtk_progress_bar; + } else + if (type == typeof(RadioButton)) { + tmp_style = global_gtk_radio_button_style; + current_widget = global_gtk_radio_button; + } else + if (type == typeof(CheckBox)) { + tmp_style = global_gtk_check_button_style; + current_widget = global_gtk_check_button; + } else + if (type == typeof(TrackBar)) { + if (orientation == Orientation.Vertical) { + tmp_style = global_gtk_vscale_style; + current_widget = global_gtk_vscale; + } else { + tmp_style = global_gtk_hscale_style; + current_widget = global_gtk_hscale; + } + } else + tmp_style = global_style; + + current_style = gtk_style_attach (tmp_style, current_gdk_drawable); // need it + } + #endif + + #if _EXPERIMENTAL_ + private void DrawDrawableToDC (Graphics dc, Control control) + { + IntPtr new_pixbuf = gdk_pixbuf_new (0, true, 8, control.ClientRectangle.Width, control.ClientRectangle.Height); + + gdk_pixbuf_get_from_drawable (new_pixbuf, + current_gdk_drawable, + global_color_map, + 0, + 0, + 0, + 0, + -1, + -1); + + IntPtr error = IntPtr.Zero; + IntPtr buffer; + UIntPtr buffer_size_as_ptr; + string type = "png"; + + bool saved = gdk_pixbuf_save_to_buffer (new_pixbuf, out buffer, out buffer_size_as_ptr, type, out error, IntPtr.Zero); + + if (!saved) + return; + + int buffer_size = (int) (uint) buffer_size_as_ptr; + byte[] result = new byte [buffer_size]; + Marshal.Copy (buffer, result, 0, (int) buffer_size); + g_free (buffer); + g_object_unref (new_pixbuf); + + Image image = null; + using (MemoryStream s = new MemoryStream (result)) + image = Image.FromStream (s); + + dc.DrawImage (image, control.ClientRectangle); + } + + private void DrawDrawableToDC (Graphics dc, Rectangle area) + { + IntPtr new_pixbuf = gdk_pixbuf_new (0, true, 8, area.Width, area.Height); + + gdk_pixbuf_get_from_drawable (new_pixbuf, + current_gdk_drawable, + global_color_map, + 0, + 0, + 0, + 0, + -1, + -1); + + IntPtr error = IntPtr.Zero; + IntPtr buffer; + UIntPtr buffer_size_as_ptr; + string type = "png"; + + bool saved = gdk_pixbuf_save_to_buffer (new_pixbuf, out buffer, out buffer_size_as_ptr, type, out error, IntPtr.Zero); + + if (!saved) + return; + + int buffer_size = (int) (uint) buffer_size_as_ptr; + byte[] result = new byte [buffer_size]; + Marshal.Copy (buffer, result, 0, (int) buffer_size); + g_free (buffer); + g_object_unref (new_pixbuf); + + Image image = null; + using (MemoryStream s = new MemoryStream (result)) + image = Image.FromStream (s); + + dc.DrawImage (image, area); + } + #endif + + public override void DrawButtonBase (Graphics dc, Rectangle clip_area, ButtonBase button) + { + SetDrawableAndStyle (button); + + // Draw the button: fill rectangle, draw border, etc. + ButtonBase_DrawButton (button, dc); + + // First, draw the image + if ((button.image != null) || (button.image_list != null)) + ButtonBase_DrawImage (button, dc); + + // Draw the focus rectangle + if (button.has_focus) + ButtonBase_DrawFocus (button, dc); + + #if _EXPERIMENTAL_ + DrawDrawableToDC (dc, button); + #endif + + // Now the text + if (button.text != null && button.text != String.Empty) + ButtonBase_DrawText (button, dc); + } + + protected override void ButtonBase_DrawButton(ButtonBase button, Graphics dc) + { + Rectangle buttonRectangle = button.ClientRectangle; + + StateType state_type = StateType.Normal; + ShadowType shadow_type = button.flat_style == FlatStyle.Flat ? ShadowType.In : ShadowType.Out; + string detail = "buttondefault"; + + if (((button is CheckBox) && (((CheckBox)button).check_state == CheckState.Checked)) || + ((button is RadioButton) && (((RadioButton)button).check_state == CheckState.Checked))) { + state_type = StateType.Active; + shadow_type = ShadowType.In; + detail = "button"; + } else + if (!button.is_enabled) { + state_type = StateType.Insensitive; + } else + if (button.is_pressed) { + state_type = StateType.Active; + shadow_type = ShadowType.In; + detail = "button"; + } else + if (button.is_entered) { + state_type = StateType.Prelight; + } + + if (button.Focused) + gtk_widget_grab_focus (global_gtk_button); + + if (button.flat_style == FlatStyle.Flat) + gtk_paint_flat_box (current_style, + current_gdk_drawable, + (int) state_type, + (int) shadow_type, + IntPtr.Zero, + global_gtk_button, + detail, + buttonRectangle.X, buttonRectangle.Y, + buttonRectangle.Width, buttonRectangle.Height); + else + if (button.flat_style != FlatStyle.Popup || (button.flat_style == FlatStyle.Popup && button.is_entered)) + gtk_paint_box (current_style, + current_gdk_drawable, + (int) state_type, + (int) shadow_type, + IntPtr.Zero, + global_gtk_button, + detail, + buttonRectangle.X, buttonRectangle.Y, + buttonRectangle.Width, buttonRectangle.Height); + } + + protected override void ButtonBase_DrawFocus (ButtonBase button, Graphics dc) + { + if (!button.is_enabled) + return; + + Rectangle focus_rect = new Rectangle (button.ClientRectangle.X + 4, button.ClientRectangle.Y + 4, button.ClientRectangle.Width - 9, button.ClientRectangle.Height - 9); + + gtk_widget_grab_focus (global_gtk_button); + + gtk_paint_focus (current_style, + current_gdk_drawable, + (int) StateType.Active, + IntPtr.Zero, + global_gtk_button, + "button", + focus_rect.X, + focus_rect.Y, + focus_rect.Width, + focus_rect.Height); + } + + #region ScrollBar + public override void DrawScrollBar( Graphics dc, Rectangle clip, ScrollBar bar ) { + int scrollbutton_width = bar.scrollbutton_width; + int scrollbutton_height = bar.scrollbutton_height; + Rectangle first_arrow_area; + Rectangle second_arrow_area; + Rectangle thumb_pos; + + SetDrawableAndStyle (bar); + + Rectangle allocation = new Rectangle (bar.ClientRectangle.X, bar.ClientRectangle.Y, bar.ClientRectangle.Width, bar.ClientRectangle.Height); + + // fix for artefacts + Color fix_color = bar.Parent != null ? bar.Parent.BackColor : ColorControl; + + if (bar.vert) { + gtk_widget_size_allocate (global_gtk_vscrollbar, ref allocation); + + // fix for artefacts + dc.FillRectangle (ResPool.GetSolidBrush (fix_color), + bar.ClientRectangle.X, bar.ClientRectangle.Y, bar.ClientRectangle.Width, 3); + dc.FillRectangle (ResPool.GetSolidBrush (fix_color), + bar.ClientRectangle.X, bar.ClientRectangle.Bottom - 4, bar.ClientRectangle.Width, 3); + } else { + gtk_widget_size_allocate (global_gtk_hscrollbar, ref allocation); + + // fix for artefacts + dc.FillRectangle (ResPool.GetSolidBrush (fix_color), + bar.ClientRectangle.X, bar.ClientRectangle.Y, 3, bar.ClientRectangle.Height); + dc.FillRectangle (ResPool.GetSolidBrush (fix_color), + bar.ClientRectangle.Right - 4, bar.ClientRectangle.Y, 3, bar.ClientRectangle.Height); + } + + thumb_pos = bar.ThumbPos; + + if ( bar.vert ) { + first_arrow_area = new Rectangle( 0, 0, bar.Width, scrollbutton_height + 1 ); + bar.FirstArrowArea = first_arrow_area; + + second_arrow_area = new Rectangle( 0, bar.ClientRectangle.Height - scrollbutton_height - 1, bar.Width, scrollbutton_height + 1 ); + bar.SecondArrowArea = second_arrow_area; + + thumb_pos.Width = bar.Width; + bar.ThumbPos = thumb_pos; + + ScrollBar_Vertical_Draw_ThumbMoving_None (scrollbutton_height, bar, clip, dc); + + /* Buttons */ + if ( clip.IntersectsWith( first_arrow_area ) ) + CPDrawScrollButton( dc, first_arrow_area, ScrollButton.Up, bar.firstbutton_state ); + if ( clip.IntersectsWith( second_arrow_area ) ) + CPDrawScrollButton( dc, second_arrow_area, ScrollButton.Down, bar.secondbutton_state ); + } else { + first_arrow_area = new Rectangle( 0, 0, scrollbutton_width + 1, bar.Height ); + bar.FirstArrowArea = first_arrow_area; + + second_arrow_area = new Rectangle( bar.ClientRectangle.Width - scrollbutton_width - 1, 0, scrollbutton_width + 1, bar.Height ); + bar.SecondArrowArea = second_arrow_area; + + thumb_pos.Height = bar.Height; + bar.ThumbPos = thumb_pos; + + /* Background */ + ScrollBar_Horizontal_Draw_ThumbMoving_None (scrollbutton_width, bar, clip, dc); + + /* Buttons */ + if ( clip.IntersectsWith( first_arrow_area ) ) + CPDrawScrollButton( dc, first_arrow_area, ScrollButton.Left, bar.firstbutton_state ); + if ( clip.IntersectsWith( second_arrow_area ) ) + CPDrawScrollButton( dc, second_arrow_area, ScrollButton.Right, bar.secondbutton_state ); + } + + /* Thumb */ + ScrollBar_DrawThumb( bar, thumb_pos, clip, dc ); + + #if _EXPERIMENTAL_ + DrawDrawableToDC (dc, bar); + #endif + } + + protected override void ScrollBar_DrawThumb( ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc ) { + if ( bar.Enabled) + DrawScrollBarThumb( dc, thumb_pos, bar ); + } + + protected override void ScrollBar_Vertical_Draw_ThumbMoving_None (int scrollbutton_height, ScrollBar bar, Rectangle clip, Graphics dc) + { + Rectangle r = new Rectangle (0, + scrollbutton_height, bar.ClientRectangle.Width, bar.ClientRectangle.Height - (scrollbutton_height * 2)); + gtk_paint_box (current_style, + current_gdk_drawable, + (int) StateType.Active, + (int) ShadowType.In, + IntPtr.Zero, + global_gtk_vscrollbar, + "vscrollbar", + r.X, r.Y, + r.Width, r.Height); + } + + protected override void ScrollBar_Horizontal_Draw_ThumbMoving_None (int scrollbutton_width, ScrollBar bar, Rectangle clip, Graphics dc) + { + Rectangle r = new Rectangle (scrollbutton_width, + 0, bar.ClientRectangle.Width - (scrollbutton_width * 2), bar.ClientRectangle.Height); + + gtk_paint_box (current_style, + current_gdk_drawable, + (int) StateType.Active, + (int) ShadowType.In, + IntPtr.Zero, + global_gtk_hscrollbar, + "hscrollbar", + r.X, r.Y, + r.Width, r.Height); + } + + private void DrawScrollBarThumb( Graphics dc, Rectangle area, ScrollBar bar ) { + IntPtr gtk_scrollbar = bar.vert ? global_gtk_vscrollbar : global_gtk_hscrollbar; + + gtk_paint_box (current_style, + current_gdk_drawable, + (int) StateType.Active, + (int) ShadowType.Out, + IntPtr.Zero, + gtk_scrollbar, + "slider", + area.X, area.Y, + area.Width, area.Height); + } + #endregion // ScrollBar + + #region ProgressBar + public override void DrawProgressBar (Graphics dc, Rectangle clip_rect, ProgressBar ctrl) + { + Rectangle client_area = ctrl.client_area; + int barpos_pixels; + + SetDrawableAndStyle (ctrl); + + // draw background + gtk_paint_box (current_style, + current_gdk_drawable, + (int) StateType.Normal, + (int) ShadowType.In, + IntPtr.Zero, + global_gtk_progress_bar, + "trough", + ctrl.ClientRectangle.X, + ctrl.ClientRectangle.Y, + ctrl.ClientRectangle.Width, + ctrl.ClientRectangle.Height); + + // don't draw the bar if Value is = 0 + if (ctrl.Value <= 0) + return; + + int value = ctrl.Value; + + if (value > ctrl.Maximum) + value = ctrl.Maximum; + + if (value == ctrl.Maximum) + barpos_pixels = client_area.Width + 2; + else + barpos_pixels = (((value - ctrl.Minimum) * client_area.Width) / (ctrl.Maximum - ctrl.Minimum)) + 1; + + gtk_paint_box (current_style, + current_gdk_drawable, + (int) StateType.Prelight, + (int) ShadowType.Out, + IntPtr.Zero, + global_gtk_progress_bar, + "bar", + client_area.X - 1, client_area.Y - 1, + barpos_pixels, client_area.Height + 2); + + #if _EXPERIMENTAL_ + DrawDrawableToDC (dc, ctrl); + #endif + } + #endregion // ProgressBar + + #region RadioButton + protected override void RadioButton_DrawButton (RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle) + { + // we currently don't care for flat or popup radio buttons + if (radio_button.appearance == Appearance.Button) { + DrawButtonBase (dc, radio_button.ClientRectangle, radio_button); + } else { + DrawRadioButton (dc, radio_button, state, radiobutton_rectangle); + } + } + + private void DrawRadioButton (Graphics dc, RadioButton radio_button, ButtonState state, Rectangle radiobutton_rectangle) + { + SetDrawableAndStyle (radio_button); + + ShadowType shadow_type; + + if (!radio_button.Enabled) + shadow_type = ShadowType.Out; + else + shadow_type = radio_button.Checked ? ShadowType.In : ShadowType.EtchedIn; + + StateType state_type = StateType.Normal; + + if (!radio_button.Enabled) + state_type = StateType.Insensitive; + else + if (radio_button.is_pressed) + state_type = StateType.Active; + else + if (radio_button.is_entered) + state_type = StateType.Prelight; + + gtk_paint_option (current_style, + current_gdk_drawable, + (int) state_type, + (int) shadow_type, + IntPtr.Zero, + global_gtk_radio_button, + "radiobutton", + radiobutton_rectangle.X, + radiobutton_rectangle.Y, + radiobutton_rectangle.Width, + radiobutton_rectangle.Height); + + #if _EXPERIMENTAL_ + DrawDrawableToDC (dc, radio_button); + #endif + } + + protected override void RadioButton_DrawText (RadioButton radio_button, Rectangle text_rectangle, Graphics dc, StringFormat text_format) + { + if (radio_button.Appearance != Appearance.Button) + base.RadioButton_DrawText (radio_button, text_rectangle, dc, text_format); + } + + protected override void RadioButton_DrawFocus (RadioButton radio_button, Graphics dc, Rectangle text_rectangle) + { + if (radio_button.Focused && radio_button.appearance != Appearance.Button) { + gtk_paint_focus (current_style, + current_gdk_drawable, + (int) StateType.Active, + IntPtr.Zero, + global_gtk_radio_button, + "radiobutton", + text_rectangle.X, + text_rectangle.Y, + text_rectangle.Width, + text_rectangle.Height); + } + + #if _EXPERIMENTAL_ + DrawDrawableToDC (dc, radio_button); + #endif + } + #endregion // RadioButton + + #region CheckBox + protected override void CheckBox_DrawCheckBox (Graphics dc, CheckBox checkbox, ButtonState state, Rectangle checkbox_rectangle) + { + // render as per normal button + if (checkbox.appearance == Appearance.Button) { + DrawButtonBase (dc, checkbox.ClientRectangle, checkbox); + } else { + InternalDrawCheckBox (dc, checkbox, state, checkbox_rectangle); + } + } + + private void InternalDrawCheckBox (Graphics dc, CheckBox checkbox, ButtonState state, Rectangle checkbox_rectangle) + { + SetDrawableAndStyle (checkbox); + + ShadowType shadow_type; + + if (!checkbox.Enabled) + shadow_type = ShadowType.Out; + else + shadow_type = checkbox.Checked ? ShadowType.In : ShadowType.EtchedIn; + + StateType state_type = StateType.Normal; + + if (!checkbox.Enabled) + state_type = StateType.Insensitive; + else + if (checkbox.is_pressed) + state_type = StateType.Active; + else + if (checkbox.is_entered) + state_type = StateType.Prelight; + + gtk_paint_check (current_style, + current_gdk_drawable, + (int) state_type, + (int) shadow_type, + IntPtr.Zero, + global_gtk_check_button, + "checkbutton", + checkbox_rectangle.X, + checkbox_rectangle.Y, + checkbox_rectangle.Width, + checkbox_rectangle.Height); + + #if _EXPERIMENTAL_ + DrawDrawableToDC (dc, checkbox); + #endif + } + + protected override void CheckBox_DrawText (CheckBox checkbox, Rectangle text_rectangle, Graphics dc, StringFormat text_format) + { + if (checkbox.Appearance != Appearance.Button) + base.CheckBox_DrawText (checkbox, text_rectangle, dc, text_format); + } + + protected override void CheckBox_DrawFocus( CheckBox checkbox, Graphics dc, Rectangle text_rectangle ) + { + if (checkbox.Focused && checkbox.appearance != Appearance.Button) { + gtk_paint_focus (current_style, + current_gdk_drawable, + (int) StateType.Active, + IntPtr.Zero, + global_gtk_check_button, + "checkbutton", + text_rectangle.X, + text_rectangle.Y, + text_rectangle.Width, + text_rectangle.Height); + } + + #if _EXPERIMENTAL_ + DrawDrawableToDC (dc, checkbox); + #endif + } + #endregion // CheckBox + + #region TrackBar + private void DrawTrackBar_Vertical (Graphics dc, Rectangle clip_rectangle, TrackBar tb, + ref Rectangle thumb_pos, ref Rectangle thumb_area, + float ticks, int value_pos, bool mouse_value) + { + Point toptick_startpoint = new Point (); + Point bottomtick_startpoint = new Point (); + Point channel_startpoint = new Point (); + float pixel_len; + float pixels_betweenticks; + const int space_from_right = 8; + const int space_from_left = 8; + Rectangle area = tb.ClientRectangle; + + Rectangle allocation = new Rectangle (area.X, area.Y, area.Width, area.Height); + + gtk_widget_size_allocate (current_widget, ref allocation); + + gtk_range_set_range (current_widget, tb.Minimum, tb.Maximum); + gtk_range_set_value (current_widget, tb.Value); + + ShadowType shadow_type = ShadowType.In; + + if (!tb.Enabled) + shadow_type = ShadowType.Out; + + StateType state_type = StateType.Normal; + + if (!tb.Enabled) + state_type = StateType.Insensitive; + else + if (tb.is_entered) + state_type = StateType.Prelight; + + switch (tb.TickStyle) { + case TickStyle.BottomRight: + case TickStyle.None: + channel_startpoint.Y = 8; + channel_startpoint.X = 9; + bottomtick_startpoint.Y = 13; + bottomtick_startpoint.X = 24; + break; + case TickStyle.TopLeft: + channel_startpoint.Y = 8; + channel_startpoint.X = 19; + toptick_startpoint.Y = 13; + toptick_startpoint.X = 8; + break; + case TickStyle.Both: + channel_startpoint.Y = 8; + channel_startpoint.X = 18; + bottomtick_startpoint.Y = 13; + bottomtick_startpoint.X = 32; + toptick_startpoint.Y = 13; + toptick_startpoint.X = 8; + break; + default: + break; + } + + thumb_area.X = area.X + channel_startpoint.X; + thumb_area.Y = area.Y + channel_startpoint.Y; + thumb_area.Height = area.Height - space_from_right - space_from_left; + thumb_area.Width = 4; + + pixel_len = thumb_area.Height - 11; + pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum); + + /* Convert thumb position from mouse position to value*/ + if (mouse_value) { + + if (value_pos >= channel_startpoint.Y) + value_pos = (int)(((float) (value_pos - channel_startpoint.Y)) / pixels_betweenticks); + else + value_pos = 0; + + if (value_pos + tb.Minimum > tb.Maximum) + value_pos = tb.Maximum - tb.Minimum; + + tb.Value = value_pos + tb.Minimum; + } + + thumb_pos.Width = 13; + thumb_pos.Height = 29; + + thumb_pos.Y = channel_startpoint.Y + (int) (pixels_betweenticks * (float) value_pos) - (thumb_pos.Height / 3); + + if (thumb_pos.Y < channel_startpoint.Y) + thumb_pos.Y = channel_startpoint.Y; + + if (thumb_pos.Y > thumb_area.Bottom - 29) + thumb_pos.Y = thumb_area.Bottom - 29; + + /* Draw channel */ + gtk_paint_box (current_style, + current_gdk_drawable, + (int)state_type, + (int)shadow_type, + IntPtr.Zero, + current_widget, + "trough", + thumb_area.X, + thumb_area.Y, + 4, + thumb_area.Height); + + /* Draw thumb */ + thumb_pos.X = channel_startpoint.X + 2 - thumb_pos.Width / 2; + + shadow_type = ShadowType.Out; + + gtk_paint_slider (current_style, + current_gdk_drawable, + (int)state_type, + (int)shadow_type, + IntPtr.Zero, + current_widget, + "vscale", + thumb_pos.X, + thumb_pos.Y, + thumb_pos.Width, + thumb_pos.Height, + 0); + + pixel_len = thumb_area.Height - 11; + pixels_betweenticks = pixel_len / ticks; + + /* Draw ticks*/ + thumb_area.X = thumb_pos.X; + thumb_area.Y = channel_startpoint.Y; + thumb_area.Width = thumb_pos.Width; + + Region outside = new Region (area); + outside.Exclude (thumb_area); + + if (outside.IsVisible (clip_rectangle)) { + if (pixels_betweenticks > 0 && ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight || + ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) { + + for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) { + if (inc == 0 || (inc + pixels_betweenticks) >= pixel_len + 1) + dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X , area.Y + bottomtick_startpoint.Y + inc, + area.X + bottomtick_startpoint.X + 3, area.Y + bottomtick_startpoint.Y + inc); + else + dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X, area.Y + bottomtick_startpoint.Y + inc, + area.X + bottomtick_startpoint.X + 2, area.Y + bottomtick_startpoint.Y + inc); + } + } + + if (pixels_betweenticks > 0 && ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft || + ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) { + + pixel_len = thumb_area.Height - 11; + pixels_betweenticks = pixel_len / ticks; + + for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) { + if (inc == 0 || (inc + pixels_betweenticks) >= pixel_len + 1) + dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X - 3 , area.Y + toptick_startpoint.Y + inc, + area.X + toptick_startpoint.X, area.Y + toptick_startpoint.Y + inc); + else + dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X - 2, area.Y + toptick_startpoint.Y + inc, + area.X + toptick_startpoint.X, area.Y + toptick_startpoint.Y + inc); + } + } + } + + outside.Dispose (); + } + + private void DrawTrackBar_Horizontal (Graphics dc, Rectangle clip_rectangle, TrackBar tb, + ref Rectangle thumb_pos, ref Rectangle thumb_area, + float ticks, int value_pos, bool mouse_value) + { + Point toptick_startpoint = new Point (); + Point bottomtick_startpoint = new Point (); + Point channel_startpoint = new Point (); + float pixel_len; + float pixels_betweenticks; + const int space_from_right = 8; + const int space_from_left = 8; + Rectangle area = tb.ClientRectangle; + + Rectangle allocation = new Rectangle (area.X, area.Y, area.Width, area.Height); + + gtk_widget_size_allocate (current_widget, ref allocation); + + gtk_range_set_range (current_widget, tb.Minimum, tb.Maximum); + gtk_range_set_value (current_widget, tb.Value); + + ShadowType shadow_type = ShadowType.In; + + if (!tb.Enabled) + shadow_type = ShadowType.Out; + + StateType state_type = StateType.Normal; + + if (!tb.Enabled) + state_type = StateType.Insensitive; + else + if (tb.is_entered) + state_type = StateType.Prelight; + + switch (tb.TickStyle) { + case TickStyle.BottomRight: + case TickStyle.None: + channel_startpoint.X = 8; + channel_startpoint.Y = 9; + bottomtick_startpoint.X = 13; + bottomtick_startpoint.Y = 24; + break; + case TickStyle.TopLeft: + channel_startpoint.X = 8; + channel_startpoint.Y = 19; + toptick_startpoint.X = 13; + toptick_startpoint.Y = 8; + break; + case TickStyle.Both: + channel_startpoint.X = 8; + channel_startpoint.Y = 18; + bottomtick_startpoint.X = 13; + bottomtick_startpoint.Y = 32; + toptick_startpoint.X = 13; + toptick_startpoint.Y = 8; + break; + default: + break; + } + + thumb_area.X = area.X + channel_startpoint.X; + thumb_area.Y = area.Y + channel_startpoint.Y; + thumb_area.Width = area.Width - space_from_right - space_from_left; + thumb_area.Height = 4; + + pixel_len = thumb_area.Width - 11; + pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum); + + /* Convert thumb position from mouse position to value*/ + if (mouse_value) { + if (value_pos >= channel_startpoint.X) + value_pos = (int)(((float) (value_pos - channel_startpoint.X)) / pixels_betweenticks); + else + value_pos = 0; + + if (value_pos + tb.Minimum > tb.Maximum) + value_pos = tb.Maximum - tb.Minimum; + + tb.Value = value_pos + tb.Minimum; + } + + thumb_pos.Width = 29; + thumb_pos.Height = 13; + + thumb_pos.X = channel_startpoint.X + (int) (pixels_betweenticks * (float) value_pos) - (thumb_pos.Width / 3); + + + if (thumb_pos.X < channel_startpoint.X) + thumb_pos.X = channel_startpoint.X; + + if (thumb_pos.X > thumb_area.Right - 29) + thumb_pos.X = thumb_area.Right - 29; + + /* Draw channel */ + gtk_paint_box (current_style, + current_gdk_drawable, + (int)state_type, + (int)shadow_type, + IntPtr.Zero, + current_widget, + "trough", + thumb_area.X, + thumb_area.Y, + thumb_area.Width, + 4); + + /* Draw thumb */ + + thumb_pos.Y = channel_startpoint.Y + 2 - thumb_pos.Height / 2; + + shadow_type = ShadowType.Out; + + gtk_paint_slider (current_style, + current_gdk_drawable, + (int)state_type, + (int)shadow_type, + IntPtr.Zero, + current_widget, + "hscale", + thumb_pos.X, + thumb_pos.Y, + thumb_pos.Width, + thumb_pos.Height, + 0); + + pixel_len = thumb_area.Width - 11; + pixels_betweenticks = pixel_len / ticks; + + /* Draw ticks*/ + thumb_area.Y = thumb_pos.Y; + thumb_area.X = channel_startpoint.X; + thumb_area.Height = thumb_pos.Height; + Region outside = new Region (area); + outside.Exclude (thumb_area); + + if (outside.IsVisible (clip_rectangle)) { + if (pixels_betweenticks > 0 && ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight || + ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) { + + for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) { + if (inc == 0 || (inc + pixels_betweenticks) >= pixel_len + 1) + dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X + inc , area.Y + bottomtick_startpoint.Y, + area.X + bottomtick_startpoint.X + inc , area.Y + bottomtick_startpoint.Y + 3); + else + dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X + inc, area.Y + bottomtick_startpoint.Y, + area.X + bottomtick_startpoint.X + inc, area.Y + bottomtick_startpoint.Y + 2); + } + } + + if (pixels_betweenticks > 0 && ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft || + ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) { + + for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) { + if (inc == 0 || (inc + pixels_betweenticks) >= pixel_len + 1) + dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X + inc , area.Y + toptick_startpoint.Y - 3, + area.X + toptick_startpoint.X + inc , area.Y + toptick_startpoint.Y); + else + dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X + inc, area.Y + toptick_startpoint.Y - 2, + area.X + toptick_startpoint.X + inc, area.Y + toptick_startpoint.Y); + } + } + } + + outside.Dispose (); + } + + public override void DrawTrackBar (Graphics dc, Rectangle clip_rectangle, TrackBar tb) + { + int value_pos; + bool mouse_value; + float ticks = (tb.Maximum - tb.Minimum) / tb.tickFrequency; /* N of ticks draw*/ + Rectangle area; + Rectangle thumb_pos = tb.ThumbPos; + Rectangle thumb_area = tb.ThumbArea; + + if (tb.thumb_pressed) { + value_pos = tb.thumb_mouseclick; + mouse_value = true; + } else { + value_pos = tb.Value - tb.Minimum; + mouse_value = false; + } + + area = tb.ClientRectangle; + + SetDrawableAndStyle (tb); + + /* Control Background */ + if (tb.BackColor == DefaultControlBackColor) { + dc.FillRectangle (ResPool.GetSolidBrush (ColorControl), clip_rectangle); + } else { + dc.FillRectangle (ResPool.GetSolidBrush (tb.BackColor), clip_rectangle); + } + + if (tb.Orientation == Orientation.Vertical) { + DrawTrackBar_Vertical (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area, + ticks, value_pos, mouse_value); + + } else { + DrawTrackBar_Horizontal (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area, + ticks, value_pos, mouse_value); + } + + if (tb.Enabled && tb.Focused) + gtk_paint_focus (current_style, + current_gdk_drawable, + (int)StateType.Normal, + IntPtr.Zero, + current_widget, + "trough", + area.X, + area.Y, + area.Width, + area.Height); + + tb.ThumbPos = thumb_pos; + tb.ThumbArea = thumb_area; + + #if _EXPERIMENTAL_ + DrawDrawableToDC (dc, tb); + #endif + } + #endregion // TrackBar + + public override void CPDrawButton (Graphics dc, Rectangle rectangle, ButtonState state) + { + #if _EXPERIMENTAL_ + SetDrawableAndStyle (rectangle, typeof(ButtonBase), Orientation.Horizontal); + #endif + + bool is_pushed = false; +// bool is_checked = false; +// bool is_flat = false; + bool is_inactive = false; + + if ((state & ButtonState.Pushed) != 0) { + is_pushed = true; + } + +// if ((state & ButtonState.Checked) != 0) { +// is_checked = true; +// } +// +// if ((state & ButtonState.Flat) != 0) { +// is_flat = true; +// } + + if ((state & ButtonState.Inactive) != 0) { + is_inactive = true; + } + + IntPtr drawbutton_style = gtk_style_attach (global_gtk_button_style, current_gdk_drawable); // need it + + StateType state_type = StateType.Normal; + ShadowType shadow_type = ShadowType.Out; + string detail = "buttondefault"; + + if (is_inactive) { + state_type = StateType.Insensitive; + } else + if (is_pushed) { + state_type = StateType.Active; + shadow_type = ShadowType.In; + detail = "button"; + } + + gtk_paint_box (drawbutton_style, current_gdk_drawable, + (int) state_type, + (int) shadow_type, + IntPtr.Zero, + IntPtr.Zero, + detail, + rectangle.X, rectangle.Y, + rectangle.Width, rectangle.Height); + + #if _EXPERIMENTAL_ + DrawDrawableToDC (dc, rectangle); + #endif + } + + /* Scroll button: regular button + direction arrow */ + public override void CPDrawScrollButton (Graphics dc, Rectangle area, ScrollButton scroll_button_type, ButtonState state) + { + #if _EXPERIMENTAL_ + Orientation orientation = Orientation.Vertical; + if (scroll_button_type == ScrollButton.Left || scroll_button_type == ScrollButton.Right) + orientation = Orientation.Horizontal; + SetDrawableAndStyle (area, typeof(ScrollBar), orientation); + #endif + + bool enabled = (state == ButtonState.Inactive) ? false: true; + + StateType state_type = enabled ? StateType.Normal : StateType.Insensitive; + + DrawScrollButtonPrimitive (dc, area, state, scroll_button_type); + + if (area.Width < 12 || area.Height < 12) /* Cannot see a thing at smaller sizes */ + return; + + ArrowType arrow_type = 0; + + switch (scroll_button_type) { + case ScrollButton.Up: + arrow_type = ArrowType.Up; + break; + case ScrollButton.Down: + arrow_type = ArrowType.Down; + break; + case ScrollButton.Right: + arrow_type = ArrowType.Right; + break; + case ScrollButton.Left: + arrow_type = ArrowType.Left; + break; + default: + break; + } + + int centerX = area.Left + area.Width / 2; + int centerY = area.Top + area.Height / 2; + int arrow_x = 0, arrow_y = 0, arrow_height = 0, arrow_width = 0; + + switch (scroll_button_type) { + case ScrollButton.Down: + case ScrollButton.Up: + arrow_x = centerX - 4; + arrow_y = centerY - 2; + arrow_width = 8; + arrow_height = 4; + break; + case ScrollButton.Left: + case ScrollButton.Right: + arrow_x = centerX - 2; + arrow_y = centerY - 4; + arrow_width = 4; + arrow_height = 8; + break; + default: + break; + } + + gtk_paint_arrow (current_style, + current_gdk_drawable, + (int) state_type, + (int) ShadowType.Out, + IntPtr.Zero, + current_widget, + "", + (int) arrow_type, true, + arrow_x, + arrow_y, + arrow_width, arrow_height); + + current_widget = IntPtr.Zero; + + #if _EXPERIMENTAL_ + DrawDrawableToDC (dc, area); + #endif + } + + public void DrawScrollButtonPrimitive (Graphics dc, Rectangle area, ButtonState state, ScrollButton scroll_button_type) + { + StateType state_type = StateType.Normal; + ShadowType shadow_type = ShadowType.Out; + + if ((state & ButtonState.Pushed) == ButtonState.Pushed) { + state_type = StateType.Active; + shadow_type = ShadowType.In; + } + + switch (scroll_button_type) { + case ScrollButton.Left: + case ScrollButton.Right: + gtk_paint_box (current_style, + current_gdk_drawable, + (int) state_type, + (int) shadow_type, + IntPtr.Zero, + global_gtk_hscrollbar, + "stepper", + area.X, area.Y, + area.Width, area.Height); + break; + case ScrollButton.Up: + case ScrollButton.Down: + gtk_paint_box (current_style, + current_gdk_drawable, + (int) state_type, + (int) shadow_type, + IntPtr.Zero, + global_gtk_vscrollbar, + "stepper", + area.X, area.Y, + area.Width, area.Height); + break; + } + } + + private static Color ColorFromGdkColor (GdkColorStruct gtkcolor) + { + return Color.FromArgb (255, + (gtkcolor.red >> 8) & 0xff, + (gtkcolor.green >> 8) & 0xff, + (gtkcolor.blue >> 8) & 0xff ); + } + + } //class +} |