Please excuse me asking 3 further questions on this excellent example which does just what I want:
1. Given that this is a dialog which may be popped up and dismissed several times whilst the application runs, do I need to do any g_object_unrefs on any of the list stores or other parts to avoid memory leaks? 2. Given that the type field in my structure is an integer, do I take it that the appropriate starting type cannot be selected nor the final value extracted when the dialog completes out of the combo as an integer, I have to make the list column a string and insert the appropriate string and decipher the appropriate string at the end as the Combo renderer is based on a text entry so there is no equivalent of xxxx_get_active() like I have with a "standalone" combo box? 3. Is there a sensible way without speaking pixels that I can say "allow for at least n rows initially" as if my initial list is empty or has only one row the thing is stupidly small (I am using a scroll on the treeview as it could get arbitrarily large). On Wed, 2008-12-10 at 20:13 +0100, Tadej Borovšak wrote: > Hi. > > I'm afraid that the ideal solution cannot be achieved since you would > need 2 different renderers on the same place. The second proposed > solution can be achieved and it's quite simple to code. > > And since the example can say more than a thousand words, I wrote a > simple application to demonstrate some techniques I use (they may not > be the best, but they work). > > --------------- > #include <gtk/gtk.h> > > enum > { > TYPE_COL, > TEXT_COL, > TEXT_SENS_COL, > INT_COL, > INT_SENS_COL, > NO_COLS > }; > > > static void > cb_type_changed( GtkCellRendererText *renderer, > gchar *path, > gchar *new_text, > GtkListStore *master ) > { > GtkTreeIter iter; > gchar *old_text; > gboolean text_sens = FALSE; > gboolean int_sens = FALSE; > > /* Get previous value from master model */ > gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( master ), > &iter, path ); > gtk_tree_model_get( GTK_TREE_MODEL( master ), &iter, > TYPE_COL, &old_text, -1 ); > > /* Do we need to change anything? */ > if( ! g_strcmp0( old_text, new_text ) ) > return; > > /* What changes are needed? */ > if( ! g_strcmp0( new_text, "String" ) ) > text_sens = TRUE; > else if( ! g_strcmp0( new_text, "Integer" ) ) > int_sens = TRUE; > > /* Update master model */ > gtk_list_store_set( master, &iter, TYPE_COL, new_text, > TEXT_SENS_COL, text_sens, > INT_SENS_COL, int_sens, > -1 ); > } > > > static void > cb_string_param_changed( GtkCellRendererText *renderer, > gchar *path, > gchar *new_text, > GtkListStore *master ) > { > GtkTreeIter iter; > > /* Update master model */ > gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( master ), > &iter, path ); > gtk_list_store_set( master, &iter, TEXT_COL, new_text, -1 ); > } > > static void > cb_integer_param_changed( GtkCellRendererText *renderer, > gchar *path, > gchar *new_text, > GtkListStore *master ) > { > GtkTreeIter iter; > gint value; > > /* Update master model */ > gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( master ), > &iter, path ); > value = (gint)strtol( new_text, NULL, 10 ); > gtk_list_store_set( master, &iter, INT_COL, value, -1 ); > } > > int > main( int argc, > char **argv ) > { > GtkWidget *window; > GtkWidget *treeview; > GtkListStore *model; > GtkListStore *master; > GtkTreeIter iter; > GtkCellRenderer *renderer; > GtkAdjustment *adj; > GtkTreeViewColumn *col; > > gtk_init( &argc, &argv ); > > window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); > g_signal_connect( G_OBJECT( window ), "destroy", > G_CALLBACK( gtk_main_quit ), NULL ); > > > /* create treeview */ > treeview = gtk_tree_view_new(); > gtk_tree_view_set_reorderable( GTK_TREE_VIEW( treeview ), TRUE ); > gtk_container_add( GTK_CONTAINER( window ), treeview ); > > /* Create "master" model for treeview and add 2 entries */ > master = gtk_list_store_new( NO_COLS, G_TYPE_STRING, > G_TYPE_STRING, > G_TYPE_BOOLEAN, > G_TYPE_INT, > G_TYPE_BOOLEAN ); > gtk_list_store_append( master, &iter ); > gtk_list_store_set( master, &iter, TYPE_COL, "None", > TEXT_COL, "Parameter 1", > TEXT_SENS_COL, FALSE, > INT_COL, 0, > INT_SENS_COL, FALSE, > -1 ); > gtk_list_store_append( master, &iter ); > gtk_list_store_set( master, &iter, TYPE_COL, "Integer", > TEXT_COL, "Parameter 1", > TEXT_SENS_COL, FALSE, > INT_COL, 5, > INT_SENS_COL, TRUE, > -1 ); > gtk_tree_view_set_model( GTK_TREE_VIEW( treeview ), > GTK_TREE_MODEL( master ) ); > > /* column 1 */ > /* Create model for combo renderer and populate it */ > model = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_INT ); > gtk_list_store_append( model, &iter ); > gtk_list_store_set( model, &iter, 0, "None", 1, 0, -1 ); > gtk_list_store_append( model, &iter ); > gtk_list_store_set( model, &iter, 0, "String", 1, 1, -1 ); > gtk_list_store_append( model, &iter ); > gtk_list_store_set( model, &iter, 0, "Integer", 1, 2, -1 ); > > /* Create column and add renderer to it */ > col = gtk_tree_view_column_new(); > gtk_tree_view_column_set_resizable( col, TRUE ); > > renderer = gtk_cell_renderer_combo_new(); > g_signal_connect( G_OBJECT( renderer ), "edited", > G_CALLBACK( cb_type_changed ), master ); > g_object_set( G_OBJECT( renderer ), "model", GTK_TREE_MODEL( model ), > "text-column", 0, > "editable", TRUE, > "has_entry", FALSE, > NULL ); > gtk_tree_view_column_pack_start( col, renderer, TRUE ); > gtk_tree_view_column_set_attributes( col, renderer, "text", TYPE_COL, > NULL ); > gtk_tree_view_append_column( GTK_TREE_VIEW( treeview ), col ); > > /* column 2 */ > /* Again create model for combo renderer and populate it */ > model = gtk_list_store_new( 1, G_TYPE_STRING ); > gtk_list_store_append( model, &iter ); > gtk_list_store_set( model, &iter, 0, "Parameter 1", -1 ); > gtk_list_store_append( model, &iter ); > gtk_list_store_set( model, &iter, 0, "Parameter 2", -1 ); > gtk_list_store_append( model, &iter ); > gtk_list_store_set( model, &iter, 0, "Parameter 3", -1 ); > > /* Create column and add renderer to it */ > col = gtk_tree_view_column_new(); > gtk_tree_view_column_set_resizable( col, TRUE ); > > renderer = gtk_cell_renderer_combo_new(); > g_signal_connect( G_OBJECT( renderer ), "edited", > G_CALLBACK( cb_string_param_changed ), master ); > g_object_set( G_OBJECT( renderer ), "model", GTK_TREE_MODEL( model ), > "text-column", 0, > "has_entry", FALSE, > NULL ); > gtk_tree_view_column_pack_start( col, renderer, TRUE ); > gtk_tree_view_column_set_attributes( col, renderer, > "text", TEXT_COL, > "sensitive", TEXT_SENS_COL, > "editable", TEXT_SENS_COL, > NULL ); > gtk_tree_view_append_column( GTK_TREE_VIEW( treeview ), col ); > > /* column 3 */ > /* Create adjustment for spin renderer */ > adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0, 0, 100, 1, 10, 0 ) ); > > /* Create column and add renderer to it */ > col = gtk_tree_view_column_new(); > gtk_tree_view_column_set_resizable( col, TRUE ); > > renderer = gtk_cell_renderer_spin_new(); > g_signal_connect( G_OBJECT( renderer ), "edited", > G_CALLBACK( cb_integer_param_changed ), master ); > g_object_set( G_OBJECT( renderer ), "adjustment", adj, > "editable", TRUE, > NULL ); > gtk_tree_view_column_pack_start( col, renderer, TRUE ); > gtk_tree_view_column_set_attributes( col, renderer, > "text", INT_COL, > "sensitive", INT_SENS_COL, > "editable", INT_SENS_COL, > NULL ); > gtk_tree_view_append_column( GTK_TREE_VIEW( treeview ), col ); > > > gtk_widget_show_all( window ); > > gtk_main(); > > return( 0); > } > ------------------ > > Hope you'll find it useful. > > > > 2008/12/10 John M Collins <j...@xisl.com>: > > In my application I am trying to build a dialog box to display and allow > > the user to create/delete/edit a list of some structures. > > > > According to the "type" field in the structures, some variants of the > > structures use a string as a parameter, others use an integer. (There is > > a "null" option which doesn't take anything). > > > > Ideally I'd like to have a TreeView with 2 columns (there are some other > > ones too relating to other fields in the structure but we'll ignore them > > for the purposes of the question), with a GtkCellRenderCombo for the > > "type" and the second column either an editable text field or a spin box > > depending on what was selected in the ComboBox. Obviously it would be > > different for each row depending on what "type" was selected for the > > structure represented by that row. > > > > If that can't be done simply - and it probably isn't worth having huge > > lumps of code to do just one bit of one dialog the way I want it in one > > part of one application - is it possible to selectively make a given > > cell non-sensitive or invisible according to the selected value of the > > combo box without affecting different rows in the same column? And how > > do I reach the "changed" signal for the ComboBox? > > > > Another more trivial question relates to the initial size of the > > TreeView (I am using a scroll as well) which is fine if I have existing > > structures to display when I start, but if the list is empty to start > > with I get a pathetic weedy little window I can only see half a line in. > > Is there a nice clean way I can set a minimum size - preferably not > > mentioning pixels for the benefit of people using big default fonts? > > > > > > John Collins Xi Software Ltd www.xisl.com > > > > _______________________________________________ > > gtk-app-devel-list mailing list > > gtk-app-devel-list@gnome.org > > http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list > > > > John Collins Xi Software Ltd www.xisl.com _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list