// 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
}
|