1 /* run the display for a option in a workspace
2 */
3
4 /*
5
6 Copyright (C) 1991-2003 The National Gallery
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
22 */
23
24 /*
25
26 These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
27
28 */
29
30 /*
31 #define DEBUG
32 */
33
34 #include "ip.h"
35
36 static GraphicviewClass *parent_class = NULL;
37
38 /* Copy a gslist of strings.
39 */
40 static GSList *
lstring_copy(GSList * lstring)41 lstring_copy( GSList *lstring )
42 {
43 GSList *new;
44 GSList *p;
45
46 new = NULL;
47 for( p = lstring; p; p = p->next )
48 new = g_slist_prepend( new,
49 g_strdup( (const char *) p->data ) );
50
51 new = g_slist_reverse( new );
52
53 return( new );
54 }
55
56 /* Are two lstrings equal?
57 */
58 static gboolean
lstring_equal(GSList * a,GSList * b)59 lstring_equal( GSList *a, GSList *b )
60 {
61 for( ; a && b; a = a->next, b = b->next )
62 if( strcmp( (const char *) a->data,
63 (const char *) b->data ) != 0 )
64 return( FALSE );
65
66 if( a || b )
67 return( FALSE );
68
69 return( TRUE );
70 }
71
72 static void
optionview_destroy(GtkObject * object)73 optionview_destroy( GtkObject *object )
74 {
75 Optionview *optionview;
76
77 g_return_if_fail( object != NULL );
78 g_return_if_fail( IS_OPTIONVIEW( object ) );
79
80 optionview = OPTIONVIEW( object );
81
82 /* My instance destroy stuff.
83 */
84 IM_FREEF( slist_free_all, optionview->labels );
85
86 GTK_OBJECT_CLASS( parent_class )->destroy( object );
87 }
88
89 static void
optionview_link(View * view,Model * model,View * parent)90 optionview_link( View *view, Model *model, View *parent )
91 {
92 Optionview *optionview = OPTIONVIEW( view );
93
94 VIEW_CLASS( parent_class )->link( view, model, parent );
95
96 if( GRAPHICVIEW( view )->sview )
97 gtk_size_group_add_widget( GRAPHICVIEW( view )->sview->group,
98 optionview->label );
99 }
100
101 /* Change to a optionview widget ... update the model.
102 */
103 static void
optionview_change_cb(GtkWidget * wid,Optionview * optionview)104 optionview_change_cb( GtkWidget *wid, Optionview *optionview )
105 {
106 Option *option = OPTION( VOBJECT( optionview )->iobject );
107 Classmodel *classmodel = CLASSMODEL( option );
108
109 const int nvalue = gtk_combo_box_get_active(
110 GTK_COMBO_BOX( optionview->options ) );
111
112 if( option->value != nvalue ) {
113 option->value = nvalue;
114
115 classmodel_update( classmodel );
116 symbol_recalculate_all();
117 }
118 }
119
120 static gboolean
optionview_scroll_cb(GtkWidget * wid,GdkEvent * event,Optionview * optionview)121 optionview_scroll_cb( GtkWidget *wid, GdkEvent *event, Optionview *optionview )
122 {
123 /* Stop any other scroll handlers running. We don't want the scroll
124 * wheel to change widgets while we're moving.
125 */
126 return( TRUE );
127 }
128
129 static void
optionview_refresh(vObject * vobject)130 optionview_refresh( vObject *vobject )
131 {
132 Optionview *optionview = OPTIONVIEW( vobject );
133 Option *option = OPTION( VOBJECT( optionview )->iobject );
134
135 GSList *p;
136 int i;
137
138 #ifdef DEBUG
139 printf( "optionview_refresh: " );
140 row_name_print( HEAPMODEL( option )->row );
141 printf( "\n" );
142 #endif /*DEBUG*/
143
144 /* Only rebuild the menu if there's been a change.
145 */
146 if( !lstring_equal( optionview->labels, option->labels ) ) {
147 /* If the menu is currently up, we can get strange things
148 * happening if we destroy it.
149 */
150 if( optionview->options )
151 gtk_combo_box_popdown(
152 GTK_COMBO_BOX( optionview->options ) );
153 IM_FREEF( gtk_widget_destroy, optionview->options );
154
155 optionview->options = gtk_combo_box_new_text();
156 for( p = option->labels, i = 0; p; p = p->next, i++ )
157 gtk_combo_box_append_text(
158 GTK_COMBO_BOX( optionview->options ),
159 (const char *) p->data );
160 gtk_box_pack_start( GTK_BOX( optionview->hbox ),
161 optionview->options, TRUE, TRUE, 0 );
162
163 gtk_signal_connect( GTK_OBJECT( optionview->options ),
164 "changed",
165 GTK_SIGNAL_FUNC( optionview_change_cb ), optionview );
166 gtk_widget_show( optionview->options );
167
168 IM_FREEF( slist_free_all, optionview->labels );
169 optionview->labels = lstring_copy( option->labels );
170
171 g_signal_connect( GTK_OBJECT( optionview->options ),
172 "scroll-event",
173 GTK_SIGNAL_FUNC( optionview_scroll_cb ), optionview );
174 }
175
176 if( optionview->options ) {
177 gtk_signal_handler_block_by_data(
178 GTK_OBJECT( optionview->options ), optionview );
179 gtk_combo_box_set_active( GTK_COMBO_BOX( optionview->options ),
180 option->value );
181 gtk_signal_handler_unblock_by_data(
182 GTK_OBJECT( optionview->options ), optionview );
183 }
184
185 set_glabel( optionview->label, _( "%s:" ), IOBJECT( option )->caption );
186
187 VOBJECT_CLASS( parent_class )->refresh( vobject );
188 }
189
190 static void
optionview_class_init(OptionviewClass * class)191 optionview_class_init( OptionviewClass *class )
192 {
193 GtkObjectClass *object_class = (GtkObjectClass *) class;
194 vObjectClass *vobject_class = (vObjectClass *) class;
195 ViewClass *view_class = (ViewClass *) class;
196
197 parent_class = g_type_class_peek_parent( class );
198
199 object_class->destroy = optionview_destroy;
200
201 /* Create signals.
202 */
203
204 /* Init methods.
205 */
206 vobject_class->refresh = optionview_refresh;
207
208 view_class->link = optionview_link;
209 }
210
211 static void
optionview_init(Optionview * optionview)212 optionview_init( Optionview *optionview )
213 {
214 optionview->hbox = gtk_hbox_new( FALSE, 12 );
215 gtk_box_pack_start( GTK_BOX( optionview ),
216 optionview->hbox, TRUE, FALSE, 0 );
217
218 optionview->label = gtk_label_new( "" );
219 gtk_misc_set_alignment( GTK_MISC( optionview->label ), 0, 0.5 );
220 gtk_box_pack_start( GTK_BOX( optionview->hbox ),
221 optionview->label, FALSE, FALSE, 2 );
222
223 optionview->options = NULL;
224
225 optionview->labels = NULL;
226
227 gtk_widget_show_all( optionview->hbox );
228 }
229
230 GtkType
optionview_get_type(void)231 optionview_get_type( void )
232 {
233 static GtkType optionview_type = 0;
234
235 if( !optionview_type ) {
236 static const GtkTypeInfo sinfo = {
237 "Optionview",
238 sizeof( Optionview ),
239 sizeof( OptionviewClass ),
240 (GtkClassInitFunc) optionview_class_init,
241 (GtkObjectInitFunc) optionview_init,
242 /* reserved_1 */ NULL,
243 /* reserved_2 */ NULL,
244 (GtkClassInitFunc) NULL,
245 };
246
247 optionview_type = gtk_type_unique( TYPE_GRAPHICVIEW, &sinfo );
248 }
249
250 return( optionview_type );
251 }
252
253 View *
optionview_new(void)254 optionview_new( void )
255 {
256 Optionview *optionview = gtk_type_new( TYPE_OPTIONVIEW );
257
258 return( VIEW( optionview ) );
259 }
260