From 0f59322c3d8175fafb061e530a6b36c2e043b4ee Mon Sep 17 00:00:00 2001 From: Jim Evins Date: Sat, 7 Feb 2004 05:29:48 +0000 Subject: [PATCH] 2004-02-07 Jim Evins * src/stock-pixmaps/Makefile.am: * src/stock-pixmaps/stock_hchain_24.png: * src/stock-pixmaps/stock_hchain_broken_24.png: * src/stock-pixmaps/stock_vchain_24.png: * src/stock-pixmaps/stock_vchain_broken_24.png: Added chain pixmaps borrowed from the gimp's default theme. * src/stock.h: * src/stock.c: (gl_stock_init), (add_button_icon): Added above pixmaps to stock icon sets. Created add_button_icon() to add these pixmaps sized as GTK_ICON_SIZE_BUTTON. * src/wdgt-chain-button.h * src/wdgt-chain-button.c * src/Makefile.am: * po/POTFILES.in: Added this Modified version of gimpchainbutton widget, borrowed from the gimp. * AUTHORS: Added acknowledgements of the above borrowing from the gimp. * src/object-editor-size-page.c: (aspect_toggle_cb), (w_spin_cb), (h_spin_cb): * src/object-editor.c: (gl_object_editor_construct_chain_button): * src/object-editor.glade: Replaced the keep aspect ratio check box with the above chain-button widget. * src/text-node.c: (gl_text_node_equal): * src/text-node.h: Added function gl_text_node_equal() to compare text_nodes. * src/label-image.c: (gl_label_image_set_filename): Replaced incomplete text_node comparison code with invocation of gl_text_node_equal. This fixed the problem of not being able to resize an image using the object_editor if the aspect ratio is not locked. git-svn-id: https://glabels.svn.sourceforge.net/svnroot/glabels/trunk@413 f5e0f49d-192f-0410-a22d-a8d8700d0965 --- glabels2/AUTHORS | 9 +- glabels2/ChangeLog | 41 +++ glabels2/po/POTFILES.in | 2 + glabels2/src/Makefile.am | 2 + glabels2/src/label-image.c | 5 +- glabels2/src/object-editor-size-page.c | 21 +- glabels2/src/object-editor.c | 19 + glabels2/src/object-editor.glade | 112 +++--- glabels2/src/stock-pixmaps/Makefile.am | 12 +- .../src/stock-pixmaps/stock_hchain_24.png | Bin 0 -> 302 bytes .../stock-pixmaps/stock_hchain_broken_24.png | Bin 0 -> 325 bytes .../src/stock-pixmaps/stock_vchain_24.png | Bin 0 -> 326 bytes .../stock-pixmaps/stock_vchain_broken_24.png | Bin 0 -> 333 bytes glabels2/src/stock.c | 40 ++ glabels2/src/stock.h | 4 + glabels2/src/text-node.c | 34 ++ glabels2/src/text-node.h | 3 + glabels2/src/wdgt-chain-button.c | 347 ++++++++++++++++++ glabels2/src/wdgt-chain-button.h | 96 +++++ 19 files changed, 673 insertions(+), 74 deletions(-) create mode 100644 glabels2/src/stock-pixmaps/stock_hchain_24.png create mode 100644 glabels2/src/stock-pixmaps/stock_hchain_broken_24.png create mode 100644 glabels2/src/stock-pixmaps/stock_vchain_24.png create mode 100644 glabels2/src/stock-pixmaps/stock_vchain_broken_24.png create mode 100644 glabels2/src/wdgt-chain-button.c create mode 100644 glabels2/src/wdgt-chain-button.h diff --git a/glabels2/AUTHORS b/glabels2/AUTHORS index f18f0913..d7bc9fbe 100644 --- a/glabels2/AUTHORS +++ b/glabels2/AUTHORS @@ -32,14 +32,21 @@ Glabels includes gnome-recent objects. The author: James Willcox +Glabels includes a modified version of the gimpchainbutton widget from the +gimp, as well as several stock icons from the gimp's default theme. +These are copyright: + + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * Copyright (C) 1999-2000 Sven Neumann + Glabels includes contributions from: Emmanuel Pacaud Wayne Schuller - Akkana nestor di -- excellent splash screen that first appeared in 0.4.3: Alessandro Zummo + Akkana Dag Wieers Translations: diff --git a/glabels2/ChangeLog b/glabels2/ChangeLog index 5d84a9a1..41a4a8e8 100644 --- a/glabels2/ChangeLog +++ b/glabels2/ChangeLog @@ -1,3 +1,44 @@ +2004-02-07 Jim Evins + + * src/stock-pixmaps/Makefile.am: + * src/stock-pixmaps/stock_hchain_24.png: + * src/stock-pixmaps/stock_hchain_broken_24.png: + * src/stock-pixmaps/stock_vchain_24.png: + * src/stock-pixmaps/stock_vchain_broken_24.png: + Added chain pixmaps borrowed from the gimp's default theme. + + * src/stock.h: + * src/stock.c: (gl_stock_init), (add_button_icon): + Added above pixmaps to stock icon sets. Created add_button_icon() to + add these pixmaps sized as GTK_ICON_SIZE_BUTTON. + + * src/wdgt-chain-button.h + * src/wdgt-chain-button.c + * src/Makefile.am: + * po/POTFILES.in: + Added this Modified version of gimpchainbutton widget, borrowed from + the gimp. + + * AUTHORS: + Added acknowledgements of the above borrowing from the gimp. + + * src/object-editor-size-page.c: (aspect_toggle_cb), (w_spin_cb), + (h_spin_cb): + * src/object-editor.c: (gl_object_editor_construct_chain_button): + * src/object-editor.glade: + Replaced the keep aspect ratio check box with the above chain-button + widget. + + * src/text-node.c: (gl_text_node_equal): + * src/text-node.h: + Added function gl_text_node_equal() to compare text_nodes. + + * src/label-image.c: (gl_label_image_set_filename): + Replaced incomplete text_node comparison code with invocation of + gl_text_node_equal. This fixed the problem of not being able to + resize an image using the object_editor if the aspect ratio is not + locked. + 2004-02-04 Jim Evins * src/object-editor-image-page.c: diff --git a/glabels2/po/POTFILES.in b/glabels2/po/POTFILES.in index a07b81d1..6bbfa30b 100644 --- a/glabels2/po/POTFILES.in +++ b/glabels2/po/POTFILES.in @@ -137,6 +137,8 @@ src/wdgt-mini-preview.c src/wdgt-mini-preview.h src/wdgt-rotate-label.c src/wdgt-rotate-label.h +src/wdgt-chain-button.c +src/wdgt-chain-button.h src/util.c src/util.h src/color.c diff --git a/glabels2/src/Makefile.am b/glabels2/src/Makefile.am index d97c7d30..54bc048c 100644 --- a/glabels2/src/Makefile.am +++ b/glabels2/src/Makefile.am @@ -164,6 +164,8 @@ glabels_SOURCES = \ wdgt-mini-preview.h \ wdgt-rotate-label.c \ wdgt-rotate-label.h \ + wdgt-chain-button.c \ + wdgt-chain-button.h \ util.c \ util.h \ color.c \ diff --git a/glabels2/src/label-image.c b/glabels2/src/label-image.c index 0f51bc89..4572b3d7 100644 --- a/glabels2/src/label-image.c +++ b/glabels2/src/label-image.c @@ -209,10 +209,7 @@ gl_label_image_set_filename (glLabelImage *limage, old_filename = limage->private->filename; /* If Unchanged don't do anything */ - if ( (filename->field_flag == old_filename->field_flag) && - old_filename->data != NULL && filename->data != NULL && - !strcmp(filename->data, old_filename->data) ) - { + if ( gl_text_node_equal (filename, old_filename ) ) { return; } diff --git a/glabels2/src/object-editor-size-page.c b/glabels2/src/object-editor-size-page.c index 9b289387..e31815d5 100644 --- a/glabels2/src/object-editor-size-page.c +++ b/glabels2/src/object-editor-size-page.c @@ -26,6 +26,7 @@ #include "object-editor.h" #include "prefs.h" +#include "wdgt-chain-button.h" #include "object-editor-private.h" @@ -143,12 +144,12 @@ gl_object_editor_prepare_size_page (glObjectEditor *editor, static void aspect_toggle_cb (glObjectEditor *editor) { - GtkToggleButton *toggle; - gdouble w, h; + glWdgtChainButton *toggle; + gdouble w, h; - toggle = GTK_TOGGLE_BUTTON (editor->priv->size_aspect_checkbutton); + toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton); - if (gtk_toggle_button_get_active (toggle)) { + if (gl_wdgt_chain_button_get_active (toggle)) { w = gtk_spin_button_get_value (GTK_SPIN_BUTTON(editor->priv->size_w_spin)); h = gtk_spin_button_get_value (GTK_SPIN_BUTTON(editor->priv->size_h_spin)); @@ -164,12 +165,12 @@ aspect_toggle_cb (glObjectEditor *editor) static void w_spin_cb (glObjectEditor *editor) { - gdouble w, h; - GtkToggleButton *toggle; + gdouble w, h; + glWdgtChainButton *toggle; - toggle = GTK_TOGGLE_BUTTON (editor->priv->size_aspect_checkbutton); + toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton); - if (gtk_toggle_button_get_active (toggle)) { + if (gl_wdgt_chain_button_get_active (toggle)) { w = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin)); @@ -199,9 +200,9 @@ h_spin_cb (glObjectEditor *editor) { gdouble w, h; - GtkToggleButton *toggle = GTK_TOGGLE_BUTTON (editor->priv->size_aspect_checkbutton); + glWdgtChainButton *toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton); - if (gtk_toggle_button_get_active (toggle)) { + if (gl_wdgt_chain_button_get_active (toggle)) { h = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin)); diff --git a/glabels2/src/object-editor.c b/glabels2/src/object-editor.c index bd8a373a..259108f7 100644 --- a/glabels2/src/object-editor.c +++ b/glabels2/src/object-editor.c @@ -29,6 +29,7 @@ #include "prefs.h" #include "mygal/widget-color-combo.h" #include "color.h" +#include "wdgt-chain-button.h" #include "marshal.h" #include "object-editor-private.h" @@ -502,6 +503,24 @@ gl_object_editor_construct_color_combo (gchar *name, return color_combo; } +/*****************************************************************************/ +/* Construct chain button "Custom widget". */ +/*****************************************************************************/ +GtkWidget * +gl_object_editor_construct_chain_button (gchar *name, + gchar *string1, + gchar *string2, + gint int1, + gint int2) +{ + GtkWidget *chain_button; + + chain_button = gl_wdgt_chain_button_new (GL_WDGT_CHAIN_RIGHT); + gl_wdgt_chain_button_set_active (GL_WDGT_CHAIN_BUTTON(chain_button), TRUE); + + return chain_button; +} + /*--------------------------------------------------------------------------*/ /* PRIVATE. Prefs changed callback. Update units related items. */ /*--------------------------------------------------------------------------*/ diff --git a/glabels2/src/object-editor.glade b/glabels2/src/object-editor.glade index e167c6ea..44c3f1b5 100644 --- a/glabels2/src/object-editor.glade +++ b/glabels2/src/object-editor.glade @@ -1661,8 +1661,8 @@ True - 4 - 2 + 3 + 3 False 12 12 @@ -1716,13 +1716,13 @@ - + True False 12 - + True True 0.01 @@ -1741,7 +1741,7 @@ - + True inches False @@ -1764,20 +1764,52 @@ 1 2 - 0 - 1 + 1 + 2 + fill fill - + True False 12 - + + True + True + Reset image size + True + GTK_RELIEF_NORMAL + + + 0 + False + False + + + + + 0 + 2 + 2 + 3 + fill + + + + + + + True + False + 12 + + + True True 0.01 @@ -1796,7 +1828,7 @@ - + True inches False @@ -1819,62 +1851,28 @@ 1 2 - 1 - 2 + 0 + 1 fill fill - + True - True - Maintain current aspect ratio - True - GTK_RELIEF_NORMAL - True - False - True + gl_object_editor_construct_chain_button + 0 + 0 + Sat, 07 Feb 2004 02:56:47 GMT - 0 - 2 - 2 - 3 - fill - - - - - - - True - False - 12 - - - - True - True - Reset image size - True - GTK_RELIEF_NORMAL - - - 0 - False - False - - - - - 0 - 2 - 3 - 4 - fill - + 2 + 3 + 0 + 2 + + fill diff --git a/glabels2/src/stock-pixmaps/Makefile.am b/glabels2/src/stock-pixmaps/Makefile.am index dd8327d3..5e34a955 100644 --- a/glabels2/src/stock-pixmaps/Makefile.am +++ b/glabels2/src/stock-pixmaps/Makefile.am @@ -35,7 +35,11 @@ IMAGES = \ stock_bucket_fill_16.png \ stock_bucket_fill_24.png \ stock_pencil_16.png \ - stock_pencil_24.png + stock_pencil_24.png \ + stock_hchain_24.png \ + stock_hchain_broken_24.png \ + stock_vchain_24.png \ + stock_vchain_broken_24.png VARIABLES1 = \ stock_arrow_24 $(srcdir)/stock_arrow_24.png \ @@ -73,7 +77,11 @@ VARIABLES1 = \ stock_bucket_fill_16 $(srcdir)/stock_bucket_fill_16.png \ stock_bucket_fill_24 $(srcdir)/stock_bucket_fill_24.png \ stock_pencil_16 $(srcdir)/stock_pencil_16.png \ - stock_pencil_24 $(srcdir)/stock_pencil_24.png + stock_pencil_24 $(srcdir)/stock_pencil_24.png \ + stock_hchain_24 $(srcdir)/stock_hchain_24.png \ + stock_hchain_broken_24 $(srcdir)/stock_hchain_broken_24.png \ + stock_vchain_24 $(srcdir)/stock_vchain_24.png \ + stock_vchain_broken_24 $(srcdir)/stock_vchain_broken_24.png noinst_DATA = stockpixbufs.h diff --git a/glabels2/src/stock-pixmaps/stock_hchain_24.png b/glabels2/src/stock-pixmaps/stock_hchain_24.png new file mode 100644 index 0000000000000000000000000000000000000000..5bc2eedcacf36ced3749e623c07dd9c813823b29 GIT binary patch literal 302 zcmeAS@N?(olHy`uVBq!ia0vp^5|gW!U_%O``R3p^r= z85p>QK$!8;-MT+OLG}_)Usv{vJVLBG`ul2|m4QOLJzX3_D&{07EHF%Pd1hd^@z3$4 zAMWqBPg&V&JYz=0KX(@wgD+pd8ttk0$mDwX-(Pl#uI}!KQZs>4-@kn`TCsAak%YAL z;uW^l-*lSSua|FYmH=tXzq{+Ly|6I1>yM+|)BjJbJ>Hblxn+wa}0^Cu~WJ9bwe zcq%C&Au-Rcw(DU~2kVM`?jH}fa*JoaZm#_N%;?Mv!`6dm&Ir9bwcKCcu;%YCVP(FA oeNOz1+qQ*?7|vR*G>e(xp+&>v+dL~)1HHlE>FVdQ&MBb@0N=rVZ2$lO literal 0 HcmV?d00001 diff --git a/glabels2/src/stock-pixmaps/stock_hchain_broken_24.png b/glabels2/src/stock-pixmaps/stock_hchain_broken_24.png new file mode 100644 index 0000000000000000000000000000000000000000..2e961a3e7956e25846ebf90a491f10d6d10d8b33 GIT binary patch literal 325 zcmeAS@N?(olHy`uVBq!ia0vp^5|gW!U_%O``R3p^r= z85p>QK$!8;-MT+OLG}_)Usv{vJVFd+ymx>9`VJJj-rONmD{*#E^{fpT%>WRZ1zEk%Zeda1wAKyF;kqRciPBjxp2k2>nAmr3bd_O zU#Y|2=fQVu`6K7VGiL=o)fpRR-oNIk5-YP_kj2};_}S;kmgC`f!Dv^la9FEvF)_k49U!0j33(dr7rzr;aBr%zWq+) RzdO)(44$rjF6*2UngB2jgBSn+ literal 0 HcmV?d00001 diff --git a/glabels2/src/stock-pixmaps/stock_vchain_24.png b/glabels2/src/stock-pixmaps/stock_vchain_24.png new file mode 100644 index 0000000000000000000000000000000000000000..7dc2031f4f031b7cd4d3c66b2cebe41f2edb662d GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^oIotW!3HEXq_67%DYhhUcNd2LAh=-f^2s121s;*b z3=G^tAk28_ZrvZCAbW|YuPggS9wAmORgO<*cLRkkd%8G=RLogBDUhq#fT!($tDMsZ ziKY#!Pxu)enf=4ArLz0iD?NoP+B{R~ zJLmcI-e!-2K#?^e=e@q_q#lkeOM0$2@xiKH1`{{9ziw|m(U4hH;+3&>zo%16bcRHm zz>9yIy}5la3o}f3p3dNK`<_`)-L6TSHp*7b^a(GNvEIl0*O+@PYxUC(7U_d&BB_yw zqE82XxOD$Y3X8huqiilAIhL6}bJn`f@Q#f)>|@??tz!{K?Da^EKfm84wrSHJY5_^D&}0B?8wz@AmF;+nNP8T z$MHqz5_OG7zIVhI-gDaijmc?`lj0<~1Fj1#?#{U4qWyN0Jd!)5sI0Xt|nBLS-V|8(!i7NoM_bRa-sjS(VHd&y^?nAPHYlpSdhD3S~ESo^ln7^YM*1FBCdXa#Fd0}QqR||&EWjOF4N($L32^2 zf1pT2@2O24r*G^$cS6Ll@A22!WxRh`X3op)?J}6XYFC1U$d+pyhXrDfield_flag != text_node2->field_flag ) { + return FALSE; + } + + /* Now take care of the case of either or both data fields being NULL. */ + if ( text_node1->data == NULL ) { + return ( text_node2->data == NULL ); + } else { + if ( text_node2->data == NULL ) { + return FALSE; + } + } + + /* Field flags are identical, so now compare the data. */ + return (strcmp (text_node1->data, text_node2->data) == 0); +} + /****************************************************************************/ /* Expand text lines into single string. */ /****************************************************************************/ diff --git a/glabels2/src/text-node.h b/glabels2/src/text-node.h index 937f188f..b7d06f2d 100644 --- a/glabels2/src/text-node.h +++ b/glabels2/src/text-node.h @@ -38,6 +38,9 @@ glTextNode *gl_text_node_new_from_text (gchar *text); glTextNode *gl_text_node_dup (glTextNode *text_node); void gl_text_node_free (glTextNode **text_node); +gboolean gl_text_node_equal (glTextNode *text_node1, + glTextNode *text_node2); + gchar *gl_text_node_lines_expand (GList *lines, glMergeRecord *record); GList *gl_text_node_lines_new_from_text (gchar *text); diff --git a/glabels2/src/wdgt-chain-button.c b/glabels2/src/wdgt-chain-button.c new file mode 100644 index 00000000..6eef0dcc --- /dev/null +++ b/glabels2/src/wdgt-chain-button.c @@ -0,0 +1,347 @@ +/* wdgt-chain-button.c + * Modified version of gimpchainbutton.c for gLabels: + * + * LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpchainbutton.c + * Copyright (C) 1999-2000 Sven Neumann + * + * Modified or gLabels by Jim Evins + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +#include "wdgt-chain-button.h" +#include "stock.h" + + +enum +{ + TOGGLED, + LAST_SIGNAL +}; + + +static void gl_wdgt_chain_button_class_init (glWdgtChainButtonClass *klass); +static void gl_wdgt_chain_button_init (glWdgtChainButton *button); + +static void gl_wdgt_chain_button_clicked_callback (GtkWidget *widget, + glWdgtChainButton *button); +static gboolean gl_wdgt_chain_button_draw_lines (GtkWidget *widget, + GdkEventExpose *eevent, + glWdgtChainButton *button); + + +static const gchar *gl_wdgt_chain_stock_items[] = +{ + GL_STOCK_HCHAIN, + GL_STOCK_HCHAIN_BROKEN, + GL_STOCK_VCHAIN, + GL_STOCK_VCHAIN_BROKEN +}; + + +static guint gl_wdgt_chain_button_signals[LAST_SIGNAL] = { 0 }; + +static GtkTableClass *parent_class = NULL; + + +GType +gl_wdgt_chain_button_get_type (void) +{ + static GType button_type = 0; + + if (! button_type) + { + static const GTypeInfo button_info = + { + sizeof (glWdgtChainButtonClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) gl_wdgt_chain_button_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (glWdgtChainButton), + 0, /* n_preallocs */ + (GInstanceInitFunc) gl_wdgt_chain_button_init, + }; + + button_type = g_type_register_static (GTK_TYPE_TABLE, "glWdgtChainButton", + &button_info, 0); + } + + return button_type; +} + +static void +gl_wdgt_chain_button_class_init (glWdgtChainButtonClass *klass) +{ + parent_class = g_type_class_peek_parent (klass); + + gl_wdgt_chain_button_signals[TOGGLED] = + g_signal_new ("toggled", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (glWdgtChainButtonClass, toggled), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + klass->toggled = NULL; +} + +static void +gl_wdgt_chain_button_init (glWdgtChainButton *button) +{ + button->position = GL_WDGT_CHAIN_TOP; + button->active = FALSE; + + button->line1 = gtk_drawing_area_new (); + button->line2 = gtk_drawing_area_new (); + button->image = gtk_image_new (); + + button->button = gtk_button_new (); + + gtk_button_set_relief (GTK_BUTTON (button->button), GTK_RELIEF_NONE); + gtk_container_add (GTK_CONTAINER (button->button), button->image); + gtk_widget_show (button->image); + + g_signal_connect (button->button, "clicked", + G_CALLBACK (gl_wdgt_chain_button_clicked_callback), + button); + g_signal_connect (button->line1, "expose_event", + G_CALLBACK (gl_wdgt_chain_button_draw_lines), + button); + g_signal_connect (button->line2, "expose_event", + G_CALLBACK (gl_wdgt_chain_button_draw_lines), + button); +} + + +/** + * gl_wdgt_chain_button_new: + * @position: The position you are going to use for the button + * with respect to the widgets you want to chain. + * + * Creates a new #glWdgtChainButton widget. + * + * This returns a button showing either a broken or a linked chain and + * small clamps attached to both sides that visually group the two widgets + * you want to connect. This widget looks best when attached + * to a table taking up two columns (or rows respectively) next + * to the widgets that it is supposed to connect. It may work + * for more than two widgets, but the look is optimized for two. + * + * Returns: Pointer to the new #glWdgtChainButton, which is inactive + * by default. Use gl_wdgt_chain_button_set_active() to + * change its state. + */ +GtkWidget * +gl_wdgt_chain_button_new (glWdgtChainPosition position) +{ + glWdgtChainButton *button; + + button = g_object_new (GL_WDGT_TYPE_CHAIN_BUTTON, NULL); + + button->position = position; + + gtk_image_set_from_stock + (GTK_IMAGE (button->image), + gl_wdgt_chain_stock_items[((position & GL_WDGT_CHAIN_LEFT) << 1) + ! button->active], + GTK_ICON_SIZE_BUTTON); + + if (position & GL_WDGT_CHAIN_LEFT) /* are we a vertical chainbutton? */ + { + gtk_table_resize (GTK_TABLE (button), 3, 1); + gtk_table_attach (GTK_TABLE (button), button->button, 0, 1, 1, 2, + GTK_SHRINK, GTK_SHRINK, 0, 0); + gtk_table_attach_defaults (GTK_TABLE (button), + button->line1, 0, 1, 0, 1); + gtk_table_attach_defaults (GTK_TABLE (button), + button->line2, 0, 1, 2, 3); + } + else + { + gtk_table_resize (GTK_TABLE (button), 1, 3); + gtk_table_attach (GTK_TABLE (button), button->button, 1, 2, 0, 1, + GTK_SHRINK, GTK_SHRINK, 0, 0); + gtk_table_attach_defaults (GTK_TABLE (button), + button->line1, 0, 1, 0, 1); + gtk_table_attach_defaults (GTK_TABLE (button), + button->line2, 2, 3, 0, 1); + } + + gtk_widget_show (button->button); + gtk_widget_show (button->line1); + gtk_widget_show (button->line2); + + return GTK_WIDGET (button); +} + +/** + * gl_wdgt_chain_button_set_active: + * @button: Pointer to a #glWdgtChainButton. + * @active: The new state. + * + * Sets the state of the #glWdgtChainButton to be either locked (%TRUE) or + * unlocked (%FALSE) and changes the showed pixmap to reflect the new state. + */ +void +gl_wdgt_chain_button_set_active (glWdgtChainButton *button, + gboolean active) +{ + g_return_if_fail (GL_WDGT_IS_CHAIN_BUTTON (button)); + + if (button->active != active) + { + guint num; + + button->active = active ? TRUE : FALSE; + + num = ((button->position & GL_WDGT_CHAIN_LEFT) << 1) + (active ? 0 : 1); + + gtk_image_set_from_stock (GTK_IMAGE (button->image), + gl_wdgt_chain_stock_items[num], + GTK_ICON_SIZE_BUTTON); + } +} + +/** + * gl_wdgt_chain_button_get_active + * @button: Pointer to a #glWdgtChainButton. + * + * Checks the state of the #glWdgtChainButton. + * + * Returns: %TRUE if the #glWdgtChainButton is active (locked). + */ +gboolean +gl_wdgt_chain_button_get_active (glWdgtChainButton *button) +{ + g_return_val_if_fail (GL_WDGT_IS_CHAIN_BUTTON (button), FALSE); + + return button->active; +} + +static void +gl_wdgt_chain_button_clicked_callback (GtkWidget *widget, + glWdgtChainButton *button) +{ + g_return_if_fail (GL_WDGT_IS_CHAIN_BUTTON (button)); + + gl_wdgt_chain_button_set_active (button, ! button->active); + + g_signal_emit (button, gl_wdgt_chain_button_signals[TOGGLED], 0); +} + +static gboolean +gl_wdgt_chain_button_draw_lines (GtkWidget *widget, + GdkEventExpose *eevent, + glWdgtChainButton *button) +{ + GdkPoint points[3]; + GdkPoint buf; + GtkShadowType shadow; + glWdgtChainPosition position; + gint which_line; + +#define SHORT_LINE 4 + /* don't set this too high, there's no check against drawing outside + the widgets bounds yet (and probably never will be) */ + + g_return_val_if_fail (GL_WDGT_IS_CHAIN_BUTTON (button), FALSE); + + points[0].x = widget->allocation.width / 2; + points[0].y = widget->allocation.height / 2; + + which_line = (widget == button->line1) ? 1 : -1; + + position = button->position; + + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) + switch (position) + { + case GL_WDGT_CHAIN_LEFT: + position = GL_WDGT_CHAIN_RIGHT; + break; + case GL_WDGT_CHAIN_RIGHT: + position = GL_WDGT_CHAIN_LEFT; + break; + default: + break; + } + + switch (position) + { + case GL_WDGT_CHAIN_LEFT: + points[0].x += SHORT_LINE; + points[1].x = points[0].x - SHORT_LINE; + points[1].y = points[0].y; + points[2].x = points[1].x; + points[2].y = (which_line == 1) ? widget->allocation.height - 1 : 0; + shadow = GTK_SHADOW_ETCHED_IN; + break; + case GL_WDGT_CHAIN_RIGHT: + points[0].x -= SHORT_LINE; + points[1].x = points[0].x + SHORT_LINE; + points[1].y = points[0].y; + points[2].x = points[1].x; + points[2].y = (which_line == 1) ? widget->allocation.height - 1 : 0; + shadow = GTK_SHADOW_ETCHED_OUT; + break; + case GL_WDGT_CHAIN_TOP: + points[0].y += SHORT_LINE; + points[1].x = points[0].x; + points[1].y = points[0].y - SHORT_LINE; + points[2].x = (which_line == 1) ? widget->allocation.width - 1 : 0; + points[2].y = points[1].y; + shadow = GTK_SHADOW_ETCHED_OUT; + break; + case GL_WDGT_CHAIN_BOTTOM: + points[0].y -= SHORT_LINE; + points[1].x = points[0].x; + points[1].y = points[0].y + SHORT_LINE; + points[2].x = (which_line == 1) ? widget->allocation.width - 1 : 0; + points[2].y = points[1].y; + shadow = GTK_SHADOW_ETCHED_IN; + break; + default: + return FALSE; + } + + if ( ((shadow == GTK_SHADOW_ETCHED_OUT) && (which_line == -1)) || + ((shadow == GTK_SHADOW_ETCHED_IN) && (which_line == 1)) ) + { + buf = points[0]; + points[0] = points[2]; + points[2] = buf; + } + + gtk_paint_polygon (widget->style, + widget->window, + GTK_STATE_NORMAL, + shadow, + &eevent->area, + widget, + "chainbutton", + points, + 3, + FALSE); + + return TRUE; +} diff --git a/glabels2/src/wdgt-chain-button.h b/glabels2/src/wdgt-chain-button.h new file mode 100644 index 00000000..e6a9f0db --- /dev/null +++ b/glabels2/src/wdgt-chain-button.h @@ -0,0 +1,96 @@ +/* wdgt-chain-button.h + * Modified version of gimpchainbutton.h for gLabels: + * + * LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpchainbutton.h + * Copyright (C) 1999-2000 Sven Neumann + * + * Modified or gLabels by Jim Evins + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * This implements a widget derived from GtkTable that visualizes + * it's state with two different pixmaps showing a closed and a + * broken chain. It's intented to be used with the GimpSizeEntry + * widget. The usage is quite similar to the one the GtkToggleButton + * provides. + */ + +#ifndef __WDGT_CHAIN_BUTTON_H__ +#define __WDGT_CHAIN_BUTTON_H__ + +#include + +G_BEGIN_DECLS + + +typedef enum +{ + GL_WDGT_CHAIN_TOP, + GL_WDGT_CHAIN_LEFT, + GL_WDGT_CHAIN_BOTTOM, + GL_WDGT_CHAIN_RIGHT +} glWdgtChainPosition; + + +#define GL_WDGT_TYPE_CHAIN_BUTTON (gl_wdgt_chain_button_get_type ()) +#define GL_WDGT_CHAIN_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GL_WDGT_TYPE_CHAIN_BUTTON, glWdgtChainButton)) +#define GL_WDGT_CHAIN_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GL_WDGT_TYPE_CHAIN_BUTTON, glWdgtChainButtonClass)) +#define GL_WDGT_IS_CHAIN_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GL_WDGT_TYPE_CHAIN_BUTTON)) +#define GL_WDGT_IS_CHAIN_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GL_WDGT_TYPE_CHAIN_BUTTON)) +#define GL_WDGT_CHAIN_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GL_WDGT_TYPE_CHAIN_BUTTON, glWdgtChainButtonClass)) + + +typedef struct _glWdgtChainButton glWdgtChainButton; +typedef struct _glWdgtChainButtonClass glWdgtChainButtonClass; + +struct _glWdgtChainButton +{ + GtkTable parent_instance; + + glWdgtChainPosition position; + gboolean active; + + GtkWidget *button; + GtkWidget *line1; + GtkWidget *line2; + GtkWidget *image; +}; + +struct _glWdgtChainButtonClass +{ + GtkTableClass parent_class; + + void (* toggled) (glWdgtChainButton *button); +}; + + +GType gl_wdgt_chain_button_get_type (void) G_GNUC_CONST; + +GtkWidget * gl_wdgt_chain_button_new (glWdgtChainPosition position); + +void gl_wdgt_chain_button_set_active (glWdgtChainButton *button, + gboolean active); +gboolean gl_wdgt_chain_button_get_active (glWdgtChainButton *button); + + +G_END_DECLS + +#endif /* __WDGT_CHAIN_BUTTON_H__ */ -- 2.39.5