2006-08-31

GtkCellRendererToggle

#include <gtk/gtk.h>
#include <glib/gprintf.h>

static gboolean window_delete_event( GtkWidget *widget, GdkEvent *event, gpointer data);
static void toggled_event( GtkWidget *widget, gchar *path, gpointer data);
static gboolean set_toggle( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data);
static void print_values( void);

GtkWidget *label;

char *numbers[] ={"Ichi", "Ni", "San", "Shi", "Go", "Roku", "Shichi", "Hachi", NULL};

enum
  {
    COL_TOGGLE,
    COL_DESC,
    N_COLUMNS
  };

GtkListStore *store;
GtkWidget *view;

gint selected =7;

int main( int argc, char **argv)
{
  GtkWidget *window, *vbox;
  GtkTreeViewColumn *column;
  GtkCellRenderer *renderer;
  GtkTreeIter iter;

  int i =0;

  gtk_set_locale( );

  gtk_init( &argc, &argv);

  window =gtk_window_new( GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title( GTK_WINDOW( window), "Toggle test");
  g_signal_connect( G_OBJECT( window),
      "delete_event",
      G_CALLBACK( window_delete_event), NULL);

  vbox =gtk_vbox_new( FALSE, 8);
  gtk_container_add( GTK_CONTAINER( window), vbox);

  label =gtk_label_new( "Choose one");
  gtk_box_pack_start( GTK_BOX( vbox), label, FALSE, TRUE, 8);

  store =gtk_list_store_new (N_COLUMNS,
         G_TYPE_BOOLEAN,
         G_TYPE_STRING);
  
  view =gtk_tree_view_new_with_model( GTK_TREE_MODEL( store));

  renderer =gtk_cell_renderer_toggle_new( );
  gtk_cell_renderer_toggle_set_radio( GTK_CELL_RENDERER_TOGGLE( renderer), TRUE);
  g_signal_connect( G_OBJECT( renderer),
      "toggled",
      G_CALLBACK( toggled_event), NULL);
  column =gtk_tree_view_column_new_with_attributes ("Default",
          renderer,
          "active", COL_TOGGLE,
          NULL);
  gtk_tree_view_append_column( GTK_TREE_VIEW( view), column); 

  renderer =gtk_cell_renderer_text_new( );
  column =gtk_tree_view_column_new_with_attributes( "Description", renderer,
          "text", COL_DESC,
          NULL);
  gtk_tree_view_append_column( GTK_TREE_VIEW( view), column); 

  while( NULL !=numbers[ i])
    {
      gtk_list_store_append( store, &iter);
      gtk_list_store_set( store, &iter,
     COL_TOGGLE, ( ( selected ==i) ? TRUE : FALSE),
     COL_DESC, numbers[ i++],
     -1);
    }

  gtk_box_pack_start( GTK_BOX( vbox), view, FALSE, TRUE, 8);

  gtk_widget_show_all( window);

  gtk_main( );

  return 0;
}

static gboolean window_delete_event( GtkWidget *widget, GdkEvent *event, gpointer data)
{
  print_values( );

  exit( 0);
}

// I'm quite sure there is a better way...

static void toggled_event( GtkWidget *widget, gchar *path, gpointer data)
{
  GtkTreeIter iter;

  gtk_tree_model_foreach( GTK_TREE_MODEL( store), set_toggle, path);
 
  if( gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( store), &iter, path))
    {
      gtk_list_store_set( GTK_LIST_STORE( store), &iter, COL_TOGGLE, TRUE, -1);
    }
}

static gboolean set_toggle( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
{
  gtk_list_store_set( GTK_LIST_STORE( store), iter, COL_TOGGLE, FALSE, -1);

  return FALSE;
}

static void print_values( void)
{
  gboolean toggled;
  gchar *description;
  GtkTreeIter iter;

  if( gtk_tree_model_get_iter_first( GTK_TREE_MODEL( store), &iter))
    {
      while( TRUE)
 {
   gtk_tree_model_get( GTK_TREE_MODEL( store), &iter,
         COL_TOGGLE, &toggled,
         COL_DESC, &description,
         -1);

   g_printf( "%s %s (%p)\n", description, ( toggled ? "yes" : "no"), description);

   g_free( description);

   if( !gtk_tree_model_iter_next( GTK_TREE_MODEL( store), &iter))
     break;
 }
    }
}