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

Reply via email to