summaryrefslogtreecommitdiff
path: root/iup/src/gtk/iupgtk_canvas.c
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2009-11-04 11:56:41 -0800
committerPixel <pixel@nobis-crew.org>2009-11-04 11:59:33 -0800
commitd577d991b97ae2b5ee1af23641bcffc3f83af5b2 (patch)
tree590639d50205d1bcfaff2a7d2dc6ebf3f373c7ed /iup/src/gtk/iupgtk_canvas.c
Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux.
Diffstat (limited to 'iup/src/gtk/iupgtk_canvas.c')
-rwxr-xr-xiup/src/gtk/iupgtk_canvas.c624
1 files changed, 624 insertions, 0 deletions
diff --git a/iup/src/gtk/iupgtk_canvas.c b/iup/src/gtk/iupgtk_canvas.c
new file mode 100755
index 0000000..daae4ad
--- /dev/null
+++ b/iup/src/gtk/iupgtk_canvas.c
@@ -0,0 +1,624 @@
+/** \file
+ * \brief Canvas Control
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <gtk/gtk.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <stdarg.h>
+#include <limits.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_object.h"
+#include "iup_layout.h"
+#include "iup_attrib.h"
+#include "iup_dialog.h"
+#include "iup_str.h"
+#include "iup_drv.h"
+#include "iup_drvinfo.h"
+#include "iup_drvfont.h"
+#include "iup_canvas.h"
+#include "iup_key.h"
+
+#include "iupgtk_drv.h"
+
+
+static int gtkCanvasScroll2Iup(GtkScrollType scroll, int vert)
+{
+ switch(scroll)
+ {
+ case GTK_SCROLL_STEP_UP:
+ return IUP_SBUP;
+ case GTK_SCROLL_STEP_DOWN:
+ return IUP_SBDN;
+ case GTK_SCROLL_PAGE_UP:
+ return IUP_SBPGUP;
+ case GTK_SCROLL_PAGE_DOWN:
+ return IUP_SBPGDN;
+ case GTK_SCROLL_STEP_LEFT:
+ return IUP_SBLEFT;
+ case GTK_SCROLL_STEP_RIGHT:
+ return IUP_SBRIGHT;
+ case GTK_SCROLL_PAGE_LEFT:
+ return IUP_SBPGLEFT;
+ case GTK_SCROLL_PAGE_RIGHT:
+ return IUP_SBPGRIGHT;
+ case GTK_SCROLL_STEP_BACKWARD:
+ return vert? IUP_SBUP: IUP_SBLEFT;
+ case GTK_SCROLL_STEP_FORWARD:
+ return vert? IUP_SBDN: IUP_SBRIGHT;
+ case GTK_SCROLL_PAGE_BACKWARD:
+ return vert? IUP_SBPGUP: IUP_SBPGLEFT;
+ case GTK_SCROLL_PAGE_FORWARD:
+ return vert? IUP_SBPGDN: IUP_SBPGRIGHT;
+ case GTK_SCROLL_JUMP:
+ case GTK_SCROLL_START:
+ case GTK_SCROLL_END:
+ return vert? IUP_SBPOSV: IUP_SBPOSH;
+ case GTK_SCROLL_NONE:
+ return -1;
+ }
+
+ /* No IUP_SBDRAGV or IUP_SBDRAGH support in GTK */
+
+ return -1;
+}
+
+static gboolean gtkCanvasHChangeValue(GtkRange *range, GtkScrollType scroll, double value, Ihandle *ih)
+{
+ double posx, posy;
+ IFniff cb;
+
+ double xmin = iupAttribGetFloat(ih, "XMIN");
+ double xmax = iupAttribGetFloat(ih, "XMAX");
+ double dx = iupAttribGetFloat(ih, "DX");
+ if (value < xmin) value = xmin;
+ if (value > xmax-dx) value = xmax-dx;
+
+ posx = value;
+ ih->data->posx = (float)posx;
+ posy = ih->data->posy;
+
+ cb = (IFniff)IupGetCallback(ih,"SCROLL_CB");
+ if (cb)
+ {
+ int op = gtkCanvasScroll2Iup(scroll, 0);
+ if (op == -1)
+ return FALSE;
+
+ cb(ih, op, (float)posx, (float)posy);
+ }
+ else
+ {
+ IFnff cb = (IFnff)IupGetCallback(ih,"ACTION");
+ if (cb)
+ cb (ih, (float)posx, (float)posy);
+ }
+
+ (void)range;
+ return FALSE;
+}
+
+static gboolean gtkCanvasVChangeValue(GtkRange *range, GtkScrollType scroll, double value, Ihandle *ih)
+{
+ double posx, posy;
+ IFniff cb;
+
+ double ymin = iupAttribGetFloat(ih, "YMIN");
+ double ymax = iupAttribGetFloat(ih, "YMAX");
+ double dy = iupAttribGetFloat(ih, "DY");
+ if (value < ymin) value = ymin;
+ if (value > ymax-dy) value = ymax-dy;
+
+ posy = value;
+ ih->data->posy = (float)posy;
+ posx = ih->data->posx;
+
+ cb = (IFniff)IupGetCallback(ih,"SCROLL_CB");
+ if (cb)
+ {
+ int op = gtkCanvasScroll2Iup(scroll, 1);
+ if (op == -1)
+ return FALSE;
+
+ cb(ih, op, (float)posx, (float)posy);
+ }
+ else
+ {
+ IFnff cb = (IFnff)IupGetCallback(ih,"ACTION");
+ if (cb)
+ cb (ih, (float)posx, (float)posy);
+ }
+
+ (void)range;
+ return FALSE;
+}
+
+static gboolean gtkCanvasScrollEvent(GtkWidget *widget, GdkEventScroll *evt, Ihandle *ih)
+{
+ IFnfiis wcb = (IFnfiis)IupGetCallback(ih, "WHEEL_CB");
+ if (wcb)
+ {
+ int delta = evt->direction==GDK_SCROLL_UP||evt->direction==GDK_SCROLL_LEFT? 1: -1;
+ char status[IUPKEY_STATUS_SIZE] = IUPKEY_STATUS_INIT;
+ int button = evt->direction==GDK_SCROLL_UP||evt->direction==GDK_SCROLL_LEFT? 4: 5;
+ iupgtkButtonKeySetStatus(evt->state, button, status, 0);
+
+ wcb(ih, (float)delta, (int)evt->x, (int)evt->y, status);
+ }
+ else
+ {
+ IFniff scb = (IFniff)IupGetCallback(ih,"SCROLL_CB");
+ int delta = evt->direction==GDK_SCROLL_UP||evt->direction==GDK_SCROLL_LEFT? 1: -1;
+
+ if (evt->direction==GDK_SCROLL_UP || evt->direction==GDK_SCROLL_DOWN)
+ {
+ float posy = ih->data->posy;
+ posy -= delta*iupAttribGetFloat(ih, "DY")/10.0f;
+ IupSetfAttribute(ih, "POSY", "%g", posy);
+ }
+ else
+ {
+ float posx = ih->data->posx;
+ posx -= delta*iupAttribGetFloat(ih, "DX")/10.0f;
+ IupSetfAttribute(ih, "POSX", "%g", posx);
+ }
+
+ if (scb)
+ {
+ int scroll_gtk2iup[4] = {IUP_SBUP, IUP_SBDN, IUP_SBLEFT, IUP_SBRIGHT};
+ int op = scroll_gtk2iup[evt->direction];
+ scb(ih,op,ih->data->posx,ih->data->posy);
+ }
+ }
+ (void)widget;
+ return TRUE;
+}
+
+static gboolean gtkCanvasButtonEvent(GtkWidget *widget, GdkEventButton *evt, Ihandle *ih)
+{
+ if (evt->type == GDK_BUTTON_PRESS)
+ {
+ /* Force focus on canvas click */
+ if (iupAttribGetBoolean(ih, "CANFOCUS"))
+ gtk_widget_grab_focus(ih->handle);
+ }
+
+ return iupgtkButtonEvent(widget, evt, ih);
+}
+
+static int gtkCanvasSetBgColorAttrib(Ihandle* ih, const char* value);
+
+static gboolean gtkCanvasExposeEvent(GtkWidget *widget, GdkEventExpose *evt, Ihandle *ih)
+{
+ IFnff cb = (IFnff)IupGetCallback(ih,"ACTION");
+ if (cb)
+ {
+ if (!iupAttribGet(ih, "_IUPGTK_NO_BGCOLOR"))
+ gtkCanvasSetBgColorAttrib(ih, iupAttribGetStr(ih, "BGCOLOR")); /* reset to update window attributes */
+
+ iupAttribSetStrf(ih, "CLIPRECT", "%d %d %d %d", evt->area.x, evt->area.y, evt->area.x+evt->area.width-1, evt->area.y+evt->area.height-1);
+ cb(ih,ih->data->posx,ih->data->posy);
+ iupAttribSetStr(ih, "CLIPRECT", NULL);
+ }
+
+ (void)widget;
+ return TRUE; /* stop other handlers */
+}
+
+static gboolean gtkCanvasConfigureEvent(GtkWidget *widget, GdkEventConfigure *evt, Ihandle *ih)
+{
+ IFnii cb = (IFnii)IupGetCallback(ih,"RESIZE_CB");
+ if (cb)
+ cb(ih,evt->width,evt->height);
+
+ (void)widget;
+ return FALSE;
+}
+
+static GtkScrolledWindow* gtkCanvasGetScrolledWindow(Ihandle* ih)
+{
+ return (GtkScrolledWindow*)iupAttribGet(ih, "_IUP_EXTRAPARENT");
+}
+
+static int gtkCanvasSetXAutoHideAttrib(Ihandle* ih, const char *value)
+{
+ GtkPolicyType vscrollbar_policy;
+ gtk_scrolled_window_get_policy(gtkCanvasGetScrolledWindow(ih), NULL, &vscrollbar_policy);
+
+ if (ih->data->sb & IUP_SB_HORIZ)
+ {
+ GtkPolicyType hscrollbar_policy;
+
+ if (iupStrBoolean(value))
+ hscrollbar_policy = GTK_POLICY_AUTOMATIC;
+ else
+ hscrollbar_policy = GTK_POLICY_ALWAYS;
+
+ gtk_scrolled_window_set_policy(gtkCanvasGetScrolledWindow(ih), hscrollbar_policy, vscrollbar_policy);
+ }
+ else
+ gtk_scrolled_window_set_policy(gtkCanvasGetScrolledWindow(ih), GTK_POLICY_NEVER, vscrollbar_policy);
+
+ return 1;
+}
+
+static int gtkCanvasSetYAutoHideAttrib(Ihandle* ih, const char *value)
+{
+ GtkPolicyType hscrollbar_policy;
+ gtk_scrolled_window_get_policy(gtkCanvasGetScrolledWindow(ih), &hscrollbar_policy, NULL);
+
+ if (ih->data->sb & IUP_SB_VERT)
+ {
+ GtkPolicyType vscrollbar_policy;
+
+ if (iupStrBoolean(value))
+ vscrollbar_policy = GTK_POLICY_AUTOMATIC;
+ else
+ vscrollbar_policy = GTK_POLICY_ALWAYS;
+
+ gtk_scrolled_window_set_policy(gtkCanvasGetScrolledWindow(ih), hscrollbar_policy, vscrollbar_policy);
+ }
+ else
+ gtk_scrolled_window_set_policy(gtkCanvasGetScrolledWindow(ih), hscrollbar_policy, GTK_POLICY_NEVER);
+
+ return 1;
+}
+
+static int gtkCanvasCheckScroll(double min, double max, double *page, double *pos)
+{
+ double old_pos = *pos;
+ double range = max-min;
+ if (*page > range) *page = range;
+ if (*page <= 0) *page = range/10.;
+
+ if (*pos < min) *pos = min;
+ if (*pos > (max - *page)) *pos = max - *page;
+
+ if (old_pos == *pos)
+ return 0;
+ else
+ return 1;
+}
+
+static int gtkCanvasSetDXAttrib(Ihandle* ih, const char *value)
+{
+ if (ih->data->sb & IUP_SB_HORIZ)
+ {
+ double xmin, xmax, linex;
+ float dx;
+ int value_changed;
+ GtkAdjustment* sb_horiz = gtk_scrolled_window_get_hadjustment(gtkCanvasGetScrolledWindow(ih));
+ if (!sb_horiz) return 1;
+
+ if (!iupStrToFloat(value, &dx))
+ return 1;
+
+ xmin = iupAttribGetFloat(ih, "XMIN");
+ xmax = iupAttribGetFloat(ih, "XMAX");
+
+ if (!iupAttribGet(ih,"LINEX"))
+ {
+ linex = dx/10;
+ if (linex==0)
+ linex = 1;
+ }
+ else
+ linex = iupAttribGetFloat(ih,"LINEX");
+
+ sb_horiz->lower = xmin;
+ sb_horiz->upper = xmax;
+ sb_horiz->step_increment = linex;
+ sb_horiz->page_size = dx;
+
+ value_changed = gtkCanvasCheckScroll(xmin, xmax, &sb_horiz->page_size, &sb_horiz->value);
+ sb_horiz->page_increment = sb_horiz->page_size;
+
+ gtk_adjustment_changed(sb_horiz);
+
+ if (value_changed)
+ gtk_adjustment_value_changed(sb_horiz);
+ }
+ return 1;
+}
+
+static int gtkCanvasSetDYAttrib(Ihandle* ih, const char *value)
+{
+ if (ih->data->sb & IUP_SB_VERT)
+ {
+ double ymin, ymax, liney;
+ float dy;
+ int value_changed;
+ GtkAdjustment* sb_vert = gtk_scrolled_window_get_vadjustment(gtkCanvasGetScrolledWindow(ih));
+ if (!sb_vert) return 1;
+
+ if (!iupStrToFloat(value, &dy))
+ return 1;
+
+ ymin = iupAttribGetFloat(ih, "YMIN");
+ ymax = iupAttribGetFloat(ih, "YMAX");
+
+ if (!iupAttribGet(ih,"LINEY"))
+ {
+ liney = dy/10;
+ if (liney==0)
+ liney = 1;
+ }
+ else
+ liney = iupAttribGetFloat(ih,"LINEY");
+
+ sb_vert->lower = ymin;
+ sb_vert->upper = ymax;
+ sb_vert->step_increment = liney;
+ sb_vert->page_size = dy;
+
+ value_changed = gtkCanvasCheckScroll(ymin, ymax, &sb_vert->page_size, &sb_vert->value);
+ sb_vert->page_increment = sb_vert->page_size;
+
+ gtk_adjustment_changed(sb_vert);
+
+ if (value_changed)
+ gtk_adjustment_value_changed(sb_vert);
+ }
+ return 1;
+}
+
+static int gtkCanvasSetPosXAttrib(Ihandle* ih, const char *value)
+{
+ if (ih->data->sb & IUP_SB_HORIZ)
+ {
+ float posx, xmin, xmax, dx;
+ GtkAdjustment* sb_horiz = gtk_scrolled_window_get_hadjustment(gtkCanvasGetScrolledWindow(ih));
+ if (!sb_horiz) return 1;
+
+ if (!iupStrToFloat(value, &posx))
+ return 1;
+
+ xmin = iupAttribGetFloat(ih, "XMIN");
+ xmax = iupAttribGetFloat(ih, "XMAX");
+ dx = iupAttribGetFloat(ih, "DX");
+
+ if (posx < xmin) posx = xmin;
+ if (posx > (xmax - dx)) posx = xmax - dx;
+ ih->data->posx = posx;
+
+ gtk_adjustment_set_value(sb_horiz, posx);
+ }
+ return 1;
+}
+
+static int gtkCanvasSetPosYAttrib(Ihandle* ih, const char *value)
+{
+ if (ih->data->sb & IUP_SB_VERT)
+ {
+ float posy, ymin, ymax, dy;
+ GtkAdjustment* sb_vert = gtk_scrolled_window_get_vadjustment(gtkCanvasGetScrolledWindow(ih));
+ if (!sb_vert) return 1;
+
+ if (!iupStrToFloat(value, &posy))
+ return 1;
+
+ ymin = iupAttribGetFloat(ih, "YMIN");
+ ymax = iupAttribGetFloat(ih, "YMAX");
+ dy = iupAttribGetFloat(ih, "DY");
+
+ if (posy < ymin) posy = ymin;
+ if (posy > (ymax - dy)) posy = ymax - dy;
+ ih->data->posy = posy;
+
+ gtk_adjustment_set_value(sb_vert, posy);
+ }
+ return 1;
+}
+
+static int gtkCanvasSetBgColorAttrib(Ihandle* ih, const char* value)
+{
+ GtkScrolledWindow* scrolled_window = gtkCanvasGetScrolledWindow(ih);
+ unsigned char r, g, b;
+
+ /* ignore given value, must use only from parent for the scrollbars */
+ char* parent_value = iupBaseNativeParentGetBgColor(ih);
+
+ if (iupStrToRGB(parent_value, &r, &g, &b))
+ {
+ GtkWidget* sb;
+
+ iupgtkBaseSetBgColor((GtkWidget*)scrolled_window, r, g, b);
+
+#if GTK_CHECK_VERSION(2, 8, 0)
+ sb = gtk_scrolled_window_get_hscrollbar(scrolled_window);
+ if (sb) iupgtkBaseSetBgColor(sb, r, g, b);
+ sb = gtk_scrolled_window_get_vscrollbar(scrolled_window);
+ if (sb) iupgtkBaseSetBgColor(sb, r, g, b);
+#endif
+ }
+
+ if (!IupGetCallback(ih, "ACTION"))
+ {
+ /* enable automatic double buffering */
+ gtk_widget_set_double_buffered(ih->handle, TRUE);
+ gtk_widget_set_double_buffered((GtkWidget*)scrolled_window, TRUE);
+ return iupdrvBaseSetBgColorAttrib(ih, value);
+ }
+ else
+ {
+ /* disable automatic double buffering */
+ gtk_widget_set_double_buffered(ih->handle, FALSE);
+ gtk_widget_set_double_buffered((GtkWidget*)scrolled_window, FALSE);
+ gdk_window_set_back_pixmap(ih->handle->window, NULL, FALSE);
+ iupAttribSetStr(ih, "_IUPGTK_NO_BGCOLOR", "1");
+ return 1;
+ }
+}
+
+static char* gtkCanvasGetDrawableAttrib(Ihandle* ih)
+{
+ return (char*)ih->handle->window;
+}
+
+static void gtkCanvasDummyLogFunc(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
+{
+ /* does nothing */
+ (void)log_domain;
+ (void)log_level;
+ (void)message;
+ (void)user_data;
+}
+
+static int gtkCanvasMapMethod(Ihandle* ih)
+{
+ GtkScrolledWindow* scrolled_window;
+ void* visual;
+
+ if (!ih->parent)
+ return IUP_ERROR;
+
+ ih->data->sb = iupBaseGetScrollbar(ih);
+
+ visual = (void*)IupGetAttribute(ih, "VISUAL"); /* defined by the OpenGL Canvas in X11 or NULL */
+ if (visual)
+ iupgtkPushVisualAndColormap(visual, (void*)iupAttribGet(ih, "COLORMAP"));
+
+ ih->handle = gtk_drawing_area_new();
+
+ if (visual)
+ gtk_widget_pop_colormap();
+
+ if (!ih->handle)
+ return IUP_ERROR;
+
+ scrolled_window = (GtkScrolledWindow*)gtk_scrolled_window_new(NULL, NULL);
+ if (!scrolled_window)
+ return IUP_ERROR;
+
+ {
+ /* to avoid the "cannot add non scrollable widget" warning */
+#if GTK_CHECK_VERSION(2, 6, 0)
+ GLogFunc def_func = g_log_set_default_handler(gtkCanvasDummyLogFunc, NULL);
+#endif
+ gtk_container_add((GtkContainer*)scrolled_window, ih->handle);
+#if GTK_CHECK_VERSION(2, 6, 0)
+ g_log_set_default_handler(def_func, NULL);
+#endif
+ }
+
+ gtk_widget_show((GtkWidget*)scrolled_window);
+
+ iupAttribSetStr(ih, "_IUP_EXTRAPARENT", (char*)scrolled_window);
+
+ /* add to the parent, all GTK controls must call this. */
+ iupgtkBaseAddToParent(ih);
+
+ g_signal_connect(G_OBJECT(ih->handle), "focus-in-event", G_CALLBACK(iupgtkFocusInOutEvent), ih);
+ g_signal_connect(G_OBJECT(ih->handle), "focus-out-event", G_CALLBACK(iupgtkFocusInOutEvent), ih);
+ g_signal_connect(G_OBJECT(ih->handle), "key-press-event", G_CALLBACK(iupgtkKeyPressEvent), ih);
+ g_signal_connect(G_OBJECT(ih->handle), "key-release-event", G_CALLBACK(iupgtkKeyReleaseEvent), ih);
+ g_signal_connect(G_OBJECT(ih->handle), "enter-notify-event", G_CALLBACK(iupgtkEnterLeaveEvent), ih);
+ g_signal_connect(G_OBJECT(ih->handle), "leave-notify-event", G_CALLBACK(iupgtkEnterLeaveEvent), ih);
+ g_signal_connect(G_OBJECT(ih->handle), "show-help", G_CALLBACK(iupgtkShowHelp), ih);
+
+ g_signal_connect(G_OBJECT(ih->handle), "expose-event", G_CALLBACK(gtkCanvasExposeEvent), ih);
+ g_signal_connect(G_OBJECT(ih->handle), "button-press-event", G_CALLBACK(gtkCanvasButtonEvent), ih);
+ g_signal_connect(G_OBJECT(ih->handle), "button-release-event",G_CALLBACK(gtkCanvasButtonEvent), ih);
+ g_signal_connect(G_OBJECT(ih->handle), "motion-notify-event",G_CALLBACK(iupgtkMotionNotifyEvent), ih);
+ g_signal_connect(G_OBJECT(ih->handle), "scroll-event",G_CALLBACK(gtkCanvasScrollEvent), ih);
+
+#if GTK_CHECK_VERSION(2, 8, 0)
+ g_signal_connect(G_OBJECT(gtk_scrolled_window_get_hscrollbar(scrolled_window)), "change-value",G_CALLBACK(gtkCanvasHChangeValue), ih);
+ g_signal_connect(G_OBJECT(gtk_scrolled_window_get_vscrollbar(scrolled_window)), "change-value",G_CALLBACK(gtkCanvasVChangeValue), ih);
+#endif
+
+ /* To receive mouse events on a drawing area, you will need to enable them. */
+ gtk_widget_add_events(ih->handle, GDK_EXPOSURE_MASK|
+ GDK_POINTER_MOTION_MASK|GDK_BUTTON_MOTION_MASK|
+ GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK|
+ GDK_KEY_PRESS_MASK|GDK_KEY_RELEASE_MASK|
+ GDK_ENTER_NOTIFY_MASK|GDK_LEAVE_NOTIFY_MASK|
+ GDK_FOCUS_CHANGE_MASK|GDK_STRUCTURE_MASK);
+
+ /* To receive keyboard events, you will need to set the GTK_CAN_FOCUS flag on the drawing area. */
+ if (ih->iclass->is_interactive)
+ {
+ if (iupAttribGetBoolean(ih, "CANFOCUS"))
+ GTK_WIDGET_FLAGS(ih->handle) |= GTK_CAN_FOCUS;
+ }
+
+ if (iupAttribGetBoolean(ih, "BORDER"))
+ gtk_scrolled_window_set_shadow_type(scrolled_window, GTK_SHADOW_IN);
+ else
+ gtk_scrolled_window_set_shadow_type(scrolled_window, GTK_SHADOW_NONE);
+
+ gtk_widget_realize((GtkWidget*)scrolled_window);
+ gtk_widget_realize(ih->handle);
+
+ /* must be connected after realize or a RESIZE_CB will happen before MAP_CB
+ works only for the GtkDrawingArea. */
+ g_signal_connect(G_OBJECT(ih->handle), "configure-event", G_CALLBACK(gtkCanvasConfigureEvent), ih);
+
+ /* configure for DRAG&DROP */
+ if (IupGetCallback(ih, "DROPFILES_CB"))
+ iupAttribSetStr(ih, "DRAGDROP", "YES");
+
+ /* update a mnemonic in a label if necessary */
+ iupgtkUpdateMnemonic(ih);
+
+ /* configure scrollbar */
+ if (ih->data->sb)
+ {
+ GtkPolicyType hscrollbar_policy = GTK_POLICY_NEVER, vscrollbar_policy = GTK_POLICY_NEVER;
+ if (ih->data->sb & IUP_SB_HORIZ)
+ hscrollbar_policy = GTK_POLICY_AUTOMATIC;
+ if (ih->data->sb & IUP_SB_VERT)
+ vscrollbar_policy = GTK_POLICY_AUTOMATIC;
+ gtk_scrolled_window_set_policy(scrolled_window, hscrollbar_policy, vscrollbar_policy);
+ }
+ else
+ gtk_scrolled_window_set_policy(scrolled_window, GTK_POLICY_NEVER, GTK_POLICY_NEVER);
+
+ /* force the update of BGCOLOR here, to let derived classes ignore it if ACTION is defined */
+ gtkCanvasSetBgColorAttrib(ih, iupAttribGetStr(ih, "BGCOLOR"));
+
+ return IUP_NOERROR;
+}
+
+void iupdrvCanvasInitClass(Iclass* ic)
+{
+ /* Driver Dependent Class functions */
+ ic->Map = gtkCanvasMapMethod;
+
+ /* Driver Dependent Attribute functions */
+
+ /* Visual */
+ iupClassRegisterAttribute(ic, "BGCOLOR", NULL, gtkCanvasSetBgColorAttrib, "255 255 255", NULL, IUPAF_DEFAULT); /* force new default value */
+
+ /* IupCanvas only */
+ iupClassRegisterAttribute(ic, "DRAGDROP", NULL, iupgtkSetDragDropAttrib, NULL, NULL, IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "CURSOR", NULL, iupdrvBaseSetCursorAttrib, IUPAF_SAMEASSYSTEM, "ARROW", IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "DRAWSIZE", iupdrvBaseGetClientSizeAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);
+
+ iupClassRegisterAttribute(ic, "DX", NULL, gtkCanvasSetDXAttrib, "0.1", NULL, IUPAF_NO_INHERIT); /* force new default value */
+ iupClassRegisterAttribute(ic, "DY", NULL, gtkCanvasSetDYAttrib, "0.1", NULL, IUPAF_NO_INHERIT); /* force new default value */
+ iupClassRegisterAttribute(ic, "POSX", iupCanvasGetPosXAttrib, gtkCanvasSetPosXAttrib, "0.0", NULL, IUPAF_NO_INHERIT); /* force new default value */
+ iupClassRegisterAttribute(ic, "POSY", iupCanvasGetPosYAttrib, gtkCanvasSetPosYAttrib, "0.0", NULL, IUPAF_NO_INHERIT); /* force new default value */
+ iupClassRegisterAttribute(ic, "XAUTOHIDE", NULL, gtkCanvasSetXAutoHideAttrib, "YES", NULL, IUPAF_DEFAULT); /* force new default value */
+ iupClassRegisterAttribute(ic, "YAUTOHIDE", NULL, gtkCanvasSetYAutoHideAttrib, "YES", NULL, IUPAF_DEFAULT); /* force new default value */
+
+ iupClassRegisterAttribute(ic, "DRAWABLE", gtkCanvasGetDrawableAttrib, NULL, NULL, NULL, IUPAF_NO_STRING);
+ //iupClassRegisterAttribute(ic, "CD_GDK", NULL, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NO_INHERIT);
+
+ /* IupCanvas Windows or X only */
+#ifdef WIN32
+ iupClassRegisterAttribute(ic, "HWND", iupgtkGetNativeWindowHandle, NULL, NULL, NULL, IUPAF_NO_STRING|IUPAF_NO_INHERIT);
+#else
+ iupClassRegisterAttribute(ic, "XWINDOW", iupgtkGetNativeWindowHandle, NULL, NULL, NULL, IUPAF_NO_INHERIT|IUPAF_NO_STRING);
+ iupClassRegisterAttribute(ic, "XDISPLAY", (IattribGetFunc)iupdrvGetDisplay, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT|IUPAF_NO_STRING);
+#endif
+}
+