GTK+ Forums Forum Index GTK+ Forums
Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

GtkComboBox sample code

 
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Example Code
Author Message
tadeboro
Never Seen the Sunlight


Joined: 23 Jul 2008
Posts: 2114
Location: Slovenia

PostPosted: Thu Apr 16, 2009 1:24 pm    Post subject: GtkComboBox sample code Reply with quote

Hello.

Below you'll find fairly complex example of combo box at work.

It's main purpose is to demonstrate many of the advanced features of this widget. Hope you'll find it useful.

(BTW, if you're having trouble with this code, you may want to read my tutorial on GtkComboBox, found here: http://tadeboro.blogspot.com/2009/04/gtkcombobox-widget-part-1.html)

Code: (C)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
/*
 * Test me with:
 *  gcc -o combo2 combo2.c $(pkg-config --cflags --libs gtk+-2.0) && ./combo2
 */

#include <gtk/gtk.h>

/* This enumeration simplifies using data store, since column numbers can be
 * accessed via more meaningful names. */
enum
{
    /* Text related columns */
   
TEXT_C = 0,    /* Column with text strings */
   
TEXT_VIS_C,    /* Visibility column for text strings */
   
TEXT_COL_C,    /* Text color column */

    /* Image related columns */
   
PIXBUF_C,     /* Column with GdkPixbufs */
   
PIXBUF_VIS_C, /* Visibility column for pixbufs */

    /* Progress renderer related columns */
   
PROGRESS_C,     /* Column with progress information [0, 100] */
   
PROGRESS_VIS_C, /* Column with progress visibility */

    /* Last element of enumeration holds the number of columns */
   
N_COLS
};

/* Structure that holds widgets we need in our callback functions. */
typedef struct _Data Data;
struct _Data
{
    GtkWidget    *combo;  /* Our combo box */
   
GtkTreeModel *store;  /* Just a conveniance to avoid calling
                             gtk_combo_box_get_model every time we need to
                             access to data. */

    /* Check buttons that control visibility of renderers. */
   
GtkWidget *vis_pixbuf;
    GtkWidget *vis_text;
    GtkWidget *vis_progress;

    /* Entries for modifying values */
   
GtkWidget *e_pixbuf;
    GtkWidget *e_text;
    GtkWidget *e_progress;
};

/* Callback function for updating current item. */
static void
cb_clicked( GtkButton *button,
            Data      *data )
{
    const gchar *stock_id, *string;
    gint         value;
    gboolean     pix, text, prog;
    GtkTreeIter  iter;

    /* If nothing is selected, do nothing. */
   
if( ! gtk_combo_box_get_active_iter( GTK_COMBO_BOX( data->combo ), &iter ) )
        return;

    /* Fill variables with proper data */
   
stock_id = gtk_entry_get_text( GTK_ENTRY( data->e_pixbuf ) );
    string   = gtk_entry_get_text( GTK_ENTRY( data->e_text ) );
    value    = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( data->e_progress ) );
    pix  = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( data->vis_pixbuf ) );
    text = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( data->vis_text ) );
    prog = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( data->vis_progress ) );

    /* Update data store for current iter */
   
gtk_tree_store_set( GTK_TREE_STORE( data->store ), &iter,
                        TEXT_C, string,
                        TEXT_VIS_C, text,
                        PIXBUF_C, stock_id,
                        PIXBUF_VIS_C, pix,
                        PROGRESS_C, value,
                        PROGRESS_VIS_C, prog,
                        -1 );
}

/* Callback function for changed signal.
 * In this function, we'll set the widgets that control current line. */
static void
cb_changed( GtkComboBox *combo,
            Data        *data )
{
    /* sensitive flag */
   
static gboolean sensitive = TRUE;

    /* Vars */
   
GtkTreeIter  iter;
    gchar       *stock_id = NULL, *string = NULL;
    gint         value;
    gboolean     pix, text, prog;
    gboolean     active;

    /* Get active iter from combo box. If nothing is selected,
     * disable controls. */
   
active = gtk_combo_box_get_active_iter( combo, &iter );
    if( active )
    {
        gtk_tree_model_get( data->store, &iter, TEXT_C, &string,
                                                TEXT_VIS_C, &text,
                                                PIXBUF_C, &stock_id,
                                                PIXBUF_VIS_C, &pix,
                                                PROGRESS_C, &value,
                                                PROGRESS_VIS_C, &prog,
                                                -1 );

        gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( data->vis_pixbuf ), pix );
        gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( data->vis_text ), text );
        gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( data->vis_progress ), prog );
        gtk_entry_set_text( GTK_ENTRY( data->e_pixbuf ), stock_id );
        gtk_entry_set_text( GTK_ENTRY( data->e_text ), string );
        gtk_spin_button_set_value( GTK_SPIN_BUTTON( data->e_progress ), value );

        /* Free strings */
       
g_free( stock_id );
        g_free( string );
    }

    if( sensitive != active )
    {
        gtk_widget_set_sensitive( data->vis_pixbuf, active );
        gtk_widget_set_sensitive( data->vis_text, active );
        gtk_widget_set_sensitive( data->vis_progress, active );
        gtk_widget_set_sensitive( data->e_pixbuf, active );
        gtk_widget_set_sensitive( data->e_text, active );
        gtk_widget_set_sensitive( data->e_progress, active );

        sensitive = active;
    }
}

/* This function creates tree data structure and fills it with data. */
static GtkTreeModel *
create_model( Data *data )
{
    GtkTreeStore *store;
    GtkTreeIter   parent, child;

    /* Create data store. We'll be using GtkTreeStore today, to show you how
     * combo box handles tree structures. */
   
store = gtk_tree_store_new( N_COLS, G_TYPE_STRING,  /* text */
                                       
G_TYPE_BOOLEAN, /* text visibility */
                                       
G_TYPE_STRING,  /* text color */
                                       
G_TYPE_STRING,  /* pixbufs */
                                       
G_TYPE_BOOLEAN, /* pixbuf visibility */
                                       
G_TYPE_INT,     /* progress bar % */
                                       
G_TYPE_BOOLEAN  /* progress vis */
                                       
);

    /* Fill our store with some data. */
   
gtk_tree_store_append( store, &parent, NULL );
    gtk_tree_store_set( store, &parent, TEXT_C, "Root 1",
                                        TEXT_VIS_C, TRUE,
                                        TEXT_COL_C, "black",
                                        PIXBUF_C, GTK_STOCK_OK,
                                        PIXBUF_VIS_C, TRUE,
                                        PROGRESS_C, 100,
                                        PROGRESS_VIS_C, TRUE,
                                        -1 );

    gtk_tree_store_append( store, &child, &parent );
    gtk_tree_store_set( store, &child, TEXT_C, "Leaf 1.1",
                                       TEXT_VIS_C, TRUE,
                                       TEXT_COL_C, "red",
                                       PIXBUF_C, GTK_STOCK_ADD,
                                       PIXBUF_VIS_C, TRUE,
                                       PROGRESS_C, 100,
                                       PROGRESS_VIS_C, TRUE,
                                       -1 );

    gtk_tree_store_append( store, &child, &parent );
    gtk_tree_store_set( store, &child, TEXT_C, "Leaf 1.2",
                                       TEXT_VIS_C, TRUE,
                                       TEXT_COL_C, "green",
                                       PIXBUF_C, GTK_STOCK_APPLY,
                                       PIXBUF_VIS_C, TRUE,
                                       PROGRESS_C, 100,
                                       PROGRESS_VIS_C, TRUE,
                                       -1 );

    gtk_tree_store_append( store, &child, &parent );
    gtk_tree_store_set( store, &child, TEXT_C, "Leaf 1.3",
                                       TEXT_VIS_C, TRUE,
                                       TEXT_COL_C, "blue",
                                       PIXBUF_C, GTK_STOCK_CDROM,
                                       PIXBUF_VIS_C, TRUE,
                                       PROGRESS_C, 100,
                                       PROGRESS_VIS_C, TRUE,
                                       -1 );

    gtk_tree_store_append( store, &child, &parent );
    gtk_tree_store_set( store, &child, TEXT_C, "Leaf 1.4",
                                       TEXT_VIS_C, TRUE,
                                       TEXT_COL_C, "orange",
                                       PIXBUF_C, GTK_STOCK_QUIT,
                                       PIXBUF_VIS_C, TRUE,
                                       PROGRESS_C, 100,
                                       PROGRESS_VIS_C, TRUE,
                                       -1 );

    gtk_tree_store_append( store, &parent, NULL );
    gtk_tree_store_set( store, &parent, TEXT_C, "Root 2",
                                        TEXT_VIS_C, TRUE,
                                        TEXT_COL_C, "black",
                                        PIXBUF_C, GTK_STOCK_FILE,
                                        PIXBUF_VIS_C, TRUE,
                                        PROGRESS_C, 100,
                                        PROGRESS_VIS_C, TRUE,
                                        -1 );

    gtk_tree_store_append( store, &child, &parent );
    gtk_tree_store_set( store, &child, TEXT_C, "Leaf 2.1",
                                       TEXT_VIS_C, TRUE,
                                       TEXT_COL_C, "blue",
                                       PIXBUF_C, GTK_STOCK_EXECUTE,
                                       PIXBUF_VIS_C, TRUE,
                                       PROGRESS_C, 100,
                                       PROGRESS_VIS_C, TRUE,
                                       -1 );

    gtk_tree_store_append( store, &child, &parent );
    gtk_tree_store_set( store, &child, TEXT_C, "Leaf 2.2",
                                       TEXT_VIS_C, TRUE,
                                       TEXT_COL_C, "red",
                                       PIXBUF_C, GTK_STOCK_HOME,
                                       PIXBUF_VIS_C, TRUE,
                                       PROGRESS_C, 100,
                                       PROGRESS_VIS_C, TRUE,
                                       -1 );

    gtk_tree_store_append( store, &child, &parent );
    gtk_tree_store_set( store, &child, TEXT_C, "Leaf 2.3",
                                       TEXT_VIS_C, TRUE,
                                       TEXT_COL_C, "gray",
                                       PIXBUF_C, GTK_STOCK_INFO,
                                       PIXBUF_VIS_C, TRUE,
                                       PROGRESS_C, 100,
                                       PROGRESS_VIS_C, TRUE,
                                       -1 );

    gtk_tree_store_append( store, &child, &parent );
    gtk_tree_store_set( store, &child, TEXT_C, "Leaf 2.4",
                                       TEXT_VIS_C, TRUE,
                                       TEXT_COL_C, "green",
                                       PIXBUF_C, GTK_STOCK_PRINT,
                                       PIXBUF_VIS_C, TRUE,
                                       PROGRESS_C, 100,
                                       PROGRESS_VIS_C, TRUE,
                                       -1 );

    return( GTK_TREE_MODEL( store ) );
}

/* Main */
int
main( int    argc,
      char **argv )
{
    GtkWidget       *window;
    GtkWidget       *table;
    GtkWidget       *button;
    GtkCellRenderer *cell;
    Data             data;

    /* Initialization */
   
gtk_init( &argc, &argv );

    /* Main window */
   
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    g_signal_connect( G_OBJECT( window ), "destroy",
                      G_CALLBACK( gtk_main_quit ), NULL );
    gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );

    /* Table */
   
table = gtk_table_new( 4, 3, FALSE );
    gtk_container_add( GTK_CONTAINER( window ), table );

    /* Create combo box */
   
data.combo = gtk_combo_box_new();
    g_signal_connect( G_OBJECT( data.combo ), "changed",
                      G_CALLBACK( cb_changed ), &data );
    gtk_table_attach( GTK_TABLE( table ), data.combo, 0, 3, 0, 1,
                      GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0 );

    /* Create data store */
   
data.store = create_model( &data );

    /* Add data store to combo box */
   
gtk_combo_box_set_model( GTK_COMBO_BOX( data.combo ), data.store );
    g_object_unref( G_OBJECT( data.store ) );

    /* Create pixbuf cell renderer */
   
cell = gtk_cell_renderer_pixbuf_new();

    /* Add cell renderer to combo box */
   
gtk_cell_layout_pack_start( GTK_CELL_LAYOUT( data.combo ), cell, FALSE );

    /* Connect cell renderer with data from store */
   
gtk_cell_layout_set_attributes( GTK_CELL_LAYOUT( data.combo ), cell,
                                    "stock-id", PIXBUF_C,
                                    "visible", PIXBUF_VIS_C,
                                    NULL );

    /* Create text cell renderer */
   
cell = gtk_cell_renderer_text_new();
    gtk_cell_layout_pack_start( GTK_CELL_LAYOUT( data.combo ), cell, FALSE );
    gtk_cell_layout_set_attributes( GTK_CELL_LAYOUT( data.combo ), cell,
                                    "text", TEXT_C,
                                    "visible", TEXT_VIS_C,
                                    "foreground", TEXT_COL_C,
                                    NULL );

    /* Create progress renderer */
   
cell = gtk_cell_renderer_progress_new();
    gtk_cell_layout_pack_start( GTK_CELL_LAYOUT( data.combo ), cell, TRUE );
    gtk_cell_layout_set_attributes( GTK_CELL_LAYOUT( data.combo ), cell,
                                    "value", PROGRESS_C,
                                    "visible", PROGRESS_VIS_C,
                                    NULL );

    /* Create check buttons for controling visibility */
   
data.vis_pixbuf = gtk_check_button_new_with_label( "Image visible" );
    gtk_table_attach( GTK_TABLE( table ), data.vis_pixbuf, 0, 1, 1, 2,
                      GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0 );

    data.vis_text = gtk_check_button_new_with_label( "Text visible" );
    gtk_table_attach( GTK_TABLE( table ), data.vis_text, 1, 2, 1, 2,
                      GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0 );

    data.vis_progress = gtk_check_button_new_with_label( "Progress visible" );
    gtk_table_attach( GTK_TABLE( table ), data.vis_progress, 2, 3, 1, 2,
                      GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0 );

    /* Create entries for modifying values */
   
data.e_pixbuf = gtk_entry_new();
    gtk_table_attach( GTK_TABLE( table ), data.e_pixbuf, 0, 1, 2, 3,
                      GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0 );

    data.e_text = gtk_entry_new();
    gtk_table_attach( GTK_TABLE( table ), data.e_text, 1, 2, 2, 3,
                      GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0 );

    data.e_progress = gtk_spin_button_new_with_range( 0, 100, 1 );
    gtk_spin_button_set_numeric( GTK_SPIN_BUTTON( data.e_progress ), TRUE );
    gtk_table_attach( GTK_TABLE( table ), data.e_progress, 2, 3, 2, 3,
                      GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0 );

    /* Create button for applying changes */
   
button = gtk_button_new_from_stock( GTK_STOCK_APPLY );
    g_signal_connect( G_OBJECT( button ), "clicked",
                      G_CALLBACK( cb_clicked ), &data );
    gtk_table_attach( GTK_TABLE( table ), button, 0, 3, 3, 4,
                      GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0 );

    /* Manually call cb_changed function to set controllers to right state. */
   
cb_changed( GTK_COMBO_BOX( data.combo ), &data );

    /* Show everything and start main loop */
   
gtk_widget_show_all( window );
    gtk_main();

    return( 0 );
}
Back to top
Display posts from previous:   
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Example Code All times are GMT
Page 1 of 1

 


Powered by phpBB © 2001, 2005 phpBB Group
CodeBB 1.0 Beta 2
Protected by Anti-Spam ACP