ThemeGtk.cs :  » 2.6.4-mono-.net-core » System.Windows.Forms » System » Windows » Forms » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » 2.6.4 mono .net core » System.Windows.Forms 
System.Windows.Forms » System » Windows » Forms » ThemeGtk.cs
// 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 {
      public IntPtr Instance;
      public IntPtr ref_count;
      public 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(IntPtr argc, IntPtr 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 (IntPtr argc, IntPtr 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");    
      
      gdk_init_check (IntPtr.Zero, IntPtr.Zero);  

      dispmgr =  gdk_display_manager_get ();
      gdkdisplay =  gdk_display_manager_get_default_display (dispmgr);
      gtk_init_check (IntPtr.Zero, IntPtr.Zero);

      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 ();
      
      LoadSysDefaultColors ();  
    }  

    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.FlatStyle == 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.FlatStyle == 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.FlatStyle != FlatStyle.Popup || (button.FlatStyle == 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 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 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
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.