From d577d991b97ae2b5ee1af23641bcffc3f83af5b2 Mon Sep 17 00:00:00 2001 From: Pixel Date: Wed, 4 Nov 2009 11:56:41 -0800 Subject: Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux. --- iup/src/gtk/iupgtk_button.c | 477 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 477 insertions(+) create mode 100755 iup/src/gtk/iupgtk_button.c (limited to 'iup/src/gtk/iupgtk_button.c') diff --git a/iup/src/gtk/iupgtk_button.c b/iup/src/gtk/iupgtk_button.c new file mode 100755 index 0000000..18be87c --- /dev/null +++ b/iup/src/gtk/iupgtk_button.c @@ -0,0 +1,477 @@ +/** \file + * \brief Button Control + * + * See Copyright Notice in "iup.h" + */ + +#include + +#include +#include +#include +#include +#include + +#include "iup.h" +#include "iupcbs.h" + +#include "iup_object.h" +#include "iup_layout.h" +#include "iup_attrib.h" +#include "iup_str.h" +#include "iup_image.h" +#include "iup_button.h" +#include "iup_drv.h" +#include "iup_drvfont.h" +#include "iup_image.h" +#include "iup_key.h" + +#include "iupgtk_drv.h" + + +#if !GTK_CHECK_VERSION(2, 6, 0) +static void gtk_button_set_image(GtkButton *button, GtkWidget *image) +{ +} +static GtkWidget* gtk_button_get_image(GtkButton *button) +{ + return NULL; +} +#endif + +void iupdrvButtonAddBorders(int *x, int *y) +{ +#ifdef WIN32 + int border_size = 2*5; +#else +#ifdef HILDON + int border_size = 2*7+1; /* borders are not symetric */ +#else + int border_size = 2*5+1; /* borders are not symetric */ +#endif +#endif + (*x) += border_size; + (*y) += border_size; +} + +static void gtk_button_children_callback(GtkWidget *widget, gpointer client_data) +{ + if (GTK_IS_LABEL(widget)) + { + GtkLabel **label = (GtkLabel**) client_data; + *label = (GtkLabel*)widget; + } +} + +static GtkLabel* gtkButtonGetLabel(Ihandle* ih) +{ + if (ih->data->type == IUP_BUTTON_TEXT) /* text only */ + return (GtkLabel*)gtk_bin_get_child((GtkBin*)ih->handle); + else if (ih->data->type == IUP_BUTTON_BOTH) /* both */ + { + /* when both is set, button contains an GtkAlignment, + that contains a GtkBox, that contains a label and an image */ + GtkContainer *container = (GtkContainer*)gtk_bin_get_child((GtkBin*)gtk_bin_get_child((GtkBin*)ih->handle)); + GtkLabel* label = NULL; + gtk_container_foreach(container, gtk_button_children_callback, &label); + return label; + } + return NULL; +} + +static int gtkButtonSetTitleAttrib(Ihandle* ih, const char* value) +{ + if (ih->data->type != IUP_BUTTON_IMAGE) /* text or both */ + { + GtkLabel* label = gtkButtonGetLabel(ih); + iupgtkSetMnemonicTitle(ih, label, value); + return 1; + } + + return 0; +} + +static int gtkButtonSetAlignmentAttrib(Ihandle* ih, const char* value) +{ + GtkButton* button = (GtkButton*)ih->handle; + PangoAlignment alignment; + float xalign, yalign; + char value1[30]="", value2[30]=""; + + iupStrToStrStr(value, value1, value2, ':'); + + if (iupStrEqualNoCase(value1, "ARIGHT")) + { + xalign = 1.0f; + alignment = PANGO_ALIGN_RIGHT; + } + else if (iupStrEqualNoCase(value1, "ACENTER")) + { + xalign = 0.5f; + alignment = PANGO_ALIGN_CENTER; + } + else /* "ALEFT" */ + { + xalign = 0; + alignment = PANGO_ALIGN_LEFT; + } + + if (iupStrEqualNoCase(value2, "ABOTTOM")) + yalign = 1.0f; + else if (iupStrEqualNoCase(value2, "ATOP")) + yalign = 0; + else /* ACENTER (default) */ + yalign = 0.5f; + + gtk_button_set_alignment(button, xalign, yalign); + + if (ih->data->type == IUP_BUTTON_TEXT && !GTK_IS_COLOR_BUTTON(ih->handle)) /* text only */ + { + PangoLayout* layout = gtk_label_get_layout(gtkButtonGetLabel(ih)); + if (layout) pango_layout_set_alignment(layout, alignment); + } + + return 1; +} + +static int gtkButtonSetPaddingAttrib(Ihandle* ih, const char* value) +{ + iupStrToIntInt(value, &ih->data->horiz_padding, &ih->data->vert_padding, 'x'); + if (ih->handle) + { + if (ih->data->type == IUP_BUTTON_TEXT) /* text only */ + { + GtkMisc* misc = (GtkMisc*)gtk_bin_get_child((GtkBin*)ih->handle); + gtk_misc_set_padding(misc, ih->data->horiz_padding, ih->data->vert_padding); + } + else + { + GtkAlignment* alignment = (GtkAlignment*)gtk_bin_get_child((GtkBin*)ih->handle); + gtk_alignment_set_padding(alignment, ih->data->vert_padding, ih->data->vert_padding, + ih->data->horiz_padding, ih->data->horiz_padding); + } + } + return 0; +} + +#ifdef WIN32 +static int gtkButtonSetBgColorAttrib(Ihandle* ih, const char* value) +{ + if (ih->data->type == IUP_BUTTON_TEXT && GTK_IS_COLOR_BUTTON(ih->handle)) + { + GdkColor color; + unsigned char r, g, b; + if (!iupStrToRGB(value, &r, &g, &b)) + return 0; + + iupgdkColorSet(&color, r, g, b); + gtk_color_button_set_color((GtkColorButton*)ih->handle, &color); + return 1; + } + + return iupdrvBaseSetBgColorAttrib(ih, value); +} +#endif + +static int gtkButtonSetFgColorAttrib(Ihandle* ih, const char* value) +{ + unsigned char r, g, b; + GtkLabel* label = gtkButtonGetLabel(ih); + if (!label) return 0; + + if (!iupStrToRGB(value, &r, &g, &b)) + return 0; + + iupgtkBaseSetFgColor((GtkWidget*)label, r, g, b); + + return 1; +} + +static int gtkButtonSetStandardFontAttrib(Ihandle* ih, const char* value) +{ + iupdrvSetStandardFontAttrib(ih, value); + + if (ih->handle) + { + GtkLabel* label = gtkButtonGetLabel(ih); + if (!label) return 1; + + gtk_widget_modify_font((GtkWidget*)label, (PangoFontDescription*)iupgtkGetPangoFontDescAttrib(ih)); + if (ih->data->type == IUP_BUTTON_TEXT && !GTK_IS_COLOR_BUTTON(ih->handle)) /* text only */ + iupgtkFontUpdatePangoLayout(ih, gtk_label_get_layout(label)); + } + return 1; +} + +static void gtkButtonSetPixbuf(Ihandle* ih, const char* name, int make_inactive) +{ + GtkButton* button = (GtkButton*)ih->handle; + GtkImage* image = (GtkImage*)gtk_button_get_image(button); + + if (name && image) + { + GdkPixbuf* pixbuf = iupImageGetImage(name, ih, make_inactive); + GdkPixbuf* old_pixbuf = gtk_image_get_pixbuf(image); + if (pixbuf != old_pixbuf) + gtk_image_set_from_pixbuf(image, pixbuf); + return; + } + + /* if not defined */ +#if GTK_CHECK_VERSION(2, 8, 0) + if (image) + gtk_image_clear(image); +#endif +} + +static int gtkButtonSetImageAttrib(Ihandle* ih, const char* value) +{ + if (ih->data->type != IUP_BUTTON_TEXT) /* image or both */ + { + if (iupdrvIsActive(ih)) + gtkButtonSetPixbuf(ih, value, 0); + else + { + if (!iupAttribGet(ih, "IMINACTIVE")) + { + /* if not active and IMINACTIVE is not defined + then automaticaly create one based on IMAGE */ + gtkButtonSetPixbuf(ih, value, 1); /* make_inactive */ + } + } + return 1; + } + else + return 0; +} + +static int gtkButtonSetImInactiveAttrib(Ihandle* ih, const char* value) +{ + if (ih->data->type != IUP_BUTTON_TEXT) /* image or both */ + { + if (!iupdrvIsActive(ih)) + { + if (value) + gtkButtonSetPixbuf(ih, value, 0); + else + { + /* if not defined then automaticaly create one based on IMAGE */ + char* name = iupAttribGet(ih, "IMAGE"); + gtkButtonSetPixbuf(ih, name, 1); /* make_inactive */ + } + } + return 1; + } + else + return 0; +} + +static int gtkButtonSetActiveAttrib(Ihandle* ih, const char* value) +{ + /* update the inactive image if necessary */ + if (ih->data->type != IUP_BUTTON_TEXT) /* image or both */ + { + if (!iupStrBoolean(value)) + { + char* name = iupAttribGet(ih, "IMINACTIVE"); + if (name) + gtkButtonSetPixbuf(ih, name, 0); + else + { + /* if not defined then automaticaly create one based on IMAGE */ + name = iupAttribGet(ih, "IMAGE"); + gtkButtonSetPixbuf(ih, name, 1); /* make_inactive */ + } + } + else + { + /* must restore the normal image */ + char* name = iupAttribGet(ih, "IMAGE"); + gtkButtonSetPixbuf(ih, name, 0); + } + } + + return iupBaseSetActiveAttrib(ih, value); +} + +static int gtkButtonSetFocusOnClickAttrib(Ihandle* ih, const char* value) +{ + if (iupStrBoolean(value)) + gtk_button_set_focus_on_click((GtkButton*)ih->handle, TRUE); + else + gtk_button_set_focus_on_click((GtkButton*)ih->handle, FALSE); + return 1; +} + +static gboolean gtkButtonEnterLeaveEvent(GtkWidget *widget, GdkEventCrossing *evt, Ihandle *ih) +{ + iupgtkEnterLeaveEvent(widget, evt, ih); + (void)widget; + + if (evt->type == GDK_ENTER_NOTIFY) + gtk_button_set_relief((GtkButton*)ih->handle, GTK_RELIEF_NORMAL); + else if (evt->type == GDK_LEAVE_NOTIFY) + gtk_button_set_relief((GtkButton*)ih->handle, GTK_RELIEF_NONE); + + return FALSE; +} + +static gboolean gtkButtonEvent(GtkWidget *widget, GdkEventButton *evt, Ihandle *ih) +{ + if (iupgtkButtonEvent(widget, evt, ih)==TRUE) + return TRUE; + + if (ih->data->type != IUP_BUTTON_TEXT) /* image or both */ + { + char* name = iupAttribGet(ih, "IMPRESS"); + if (name) + { + if (evt->type == GDK_BUTTON_PRESS) + gtkButtonSetPixbuf(ih, name, 0); + else + { + name = iupAttribGet(ih, "IMAGE"); + gtkButtonSetPixbuf(ih, name, 0); + } + } + } + + return FALSE; +} + +static void gtkButtonClicked(GtkButton *widget, Ihandle* ih) +{ + Icallback cb = IupGetCallback(ih, "ACTION"); + if (cb) + { + if (cb(ih) == IUP_CLOSE) + IupExitLoop(); + } + (void)widget; +} + +static int gtkButtonMapMethod(Ihandle* ih) +{ + int impress; + char* value; + + ih->handle = gtk_button_new(); + if (!ih->handle) + return IUP_ERROR; + + value = iupAttribGet(ih, "IMAGE"); + if (value) + { + gtk_button_set_image((GtkButton*)ih->handle, gtk_image_new()); + ih->data->type = IUP_BUTTON_IMAGE; + + value = iupAttribGet(ih, "TITLE"); + if (value) + { + GtkSettings* settings = gtk_widget_get_settings(ih->handle); + g_object_set(settings, "gtk-button-images", (int)TRUE, NULL); + + gtk_button_set_label((GtkButton*)ih->handle, value); + ih->data->type |= IUP_BUTTON_TEXT; + +#if GTK_CHECK_VERSION(2, 10, 0) + gtk_button_set_image_position((GtkButton*)ih->handle, ih->data->img_position); /* IUP and GTK have the same Ids */ +#endif + } + } + else + { + char* title = iupAttribGet(ih, "TITLE"); + if (!title) + { +#ifdef WIN32 + if (iupAttribGet(ih, "BGCOLOR")) + { + gtk_widget_destroy(ih->handle); + ih->handle = gtk_color_button_new(); + } + else + gtk_button_set_label((GtkButton*)ih->handle, ""); +#else + gtk_button_set_label((GtkButton*)ih->handle, ""); +#endif + } + else + gtk_button_set_label((GtkButton*)ih->handle, title); + ih->data->type = IUP_BUTTON_TEXT; + } + + /* add to the parent, all GTK controls must call this. */ + iupgtkBaseAddToParent(ih); + + if (!iupAttribGetBoolean(ih, "CANFOCUS")) + GTK_WIDGET_FLAGS(ih->handle) &= ~GTK_CAN_FOCUS; + + value = iupAttribGet(ih, "IMPRESS"); + impress = (ih->data->type & IUP_BUTTON_IMAGE && value)? 1: 0; + if (!impress && iupAttribGetBoolean(ih, "FLAT")) + { + gtk_button_set_relief((GtkButton*)ih->handle, GTK_RELIEF_NONE); + + g_signal_connect(G_OBJECT(ih->handle), "enter-notify-event", G_CALLBACK(gtkButtonEnterLeaveEvent), ih); + g_signal_connect(G_OBJECT(ih->handle), "leave-notify-event", G_CALLBACK(gtkButtonEnterLeaveEvent), ih); + } + else + { + if (impress && !iupAttribGetStr(ih, "IMPRESSBORDER")) + gtk_button_set_relief((GtkButton*)ih->handle, GTK_RELIEF_NONE); + else + gtk_button_set_relief((GtkButton*)ih->handle, GTK_RELIEF_NORMAL); + + 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), "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), "show-help", G_CALLBACK(iupgtkShowHelp), ih); + + g_signal_connect(G_OBJECT(ih->handle), "clicked", G_CALLBACK(gtkButtonClicked), ih); + g_signal_connect(G_OBJECT(ih->handle), "button-press-event", G_CALLBACK(gtkButtonEvent), ih); + g_signal_connect(G_OBJECT(ih->handle), "button-release-event",G_CALLBACK(gtkButtonEvent), ih); + + gtk_widget_realize(ih->handle); + + return IUP_NOERROR; +} + +void iupdrvButtonInitClass(Iclass* ic) +{ + /* Driver Dependent Class functions */ + ic->Map = gtkButtonMapMethod; + + /* Driver Dependent Attribute functions */ + + /* Overwrite Common */ + iupClassRegisterAttribute(ic, "STANDARDFONT", NULL, gtkButtonSetStandardFontAttrib, IUPAF_SAMEASSYSTEM, "DEFAULTFONT", IUPAF_NOT_MAPPED); + + /* Overwrite Visual */ + iupClassRegisterAttribute(ic, "ACTIVE", iupBaseGetActiveAttrib, gtkButtonSetActiveAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_DEFAULT); + + /* Visual */ +#ifdef WIN32 + iupClassRegisterAttribute(ic, "BGCOLOR", NULL, gtkButtonSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT); +#else + iupClassRegisterAttribute(ic, "BGCOLOR", NULL, iupdrvBaseSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT); +#endif + + /* Special */ + iupClassRegisterAttribute(ic, "FGCOLOR", NULL, gtkButtonSetFgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGFGCOLOR", IUPAF_DEFAULT); + iupClassRegisterAttribute(ic, "TITLE", NULL, gtkButtonSetTitleAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); + + /* IupButton only */ + iupClassRegisterAttribute(ic, "ALIGNMENT", NULL, gtkButtonSetAlignmentAttrib, "ACENTER:ACENTER", NULL, IUPAF_NO_INHERIT); /* force new default value */ + iupClassRegisterAttribute(ic, "IMAGE", NULL, gtkButtonSetImageAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "IMINACTIVE", NULL, gtkButtonSetImInactiveAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "IMPRESS", NULL, NULL, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "FOCUSONCLICK", NULL, gtkButtonSetFocusOnClickAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NO_INHERIT); + + iupClassRegisterAttribute(ic, "PADDING", iupButtonGetPaddingAttrib, gtkButtonSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED); + iupClassRegisterAttribute(ic, "MARKUP", NULL, NULL, NULL, NULL, IUPAF_DEFAULT); +} -- cgit v1.2.3