Check Boxes Don't Work Independently



Let's try it again.

The attached and inline program works but the all the check boxes get
checked or unchecked when only one is clicked.  Sometimes the mouse has
to move accross the rows to refresh the display.  

Can someone explain why this happens and where the mouseover event is
coming from?  If you run the program you'll see what I mean.

Thanks in advance,

--dhk

====================== P R O G R A M ======================
/* Compile Command:
 * gcc -Wall -g3 `pkg-config --cflags --libs gtk+-2.0` -o checkBox
checkBox.c
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
                                                                                
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
                                                                                
enum {COL_DESC, COL_DISABLE, COL_NUM};
                                                                                
void treeStore0(GtkWidget *tv);
void treeView0(GtkWidget *tv);
void itemToggled(GtkCellRendererToggle *cell, gchar *path, gpointer
data);
void destroyCb(GtkWidget *widget, gpointer data);
                                                                                
int main(int argc, char **argv) {
  GtkWidget *window=NULL;
  GtkWidget *scrolledwindow=NULL;
  GtkWidget *tv=NULL;
  GtkTreeModel *tm=NULL;
  GtkTreeIter iter;
                                                                                
  gtk_init (&argc, &argv);
                                                                                
  window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "Tree View Test");
  gtk_window_set_default_size(GTK_WINDOW(window), 300, 165);
  g_signal_connect(G_OBJECT(window), "delete_event",
G_CALLBACK(destroyCb), NULL);
                                                                                
  scrolledwindow=gtk_scrolled_window_new(NULL, NULL);
  gtk_widget_show(scrolledwindow);
  gtk_container_add(GTK_CONTAINER(window), scrolledwindow);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow),
GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);

gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow),
GTK_SHADOW_IN);
                                                                                
  gtk_widget_show(window);
                                                                                
  tv=gtk_tree_view_new();
  gtk_widget_show(tv);
  gtk_container_add(GTK_CONTAINER(scrolledwindow), tv);
                                                                                
  treeStore0(tv); /* Make the tree store */
  treeView0(tv); /* Make the tree view */
                                                                                
  tm=gtk_tree_view_get_model(GTK_TREE_VIEW(tv));
  gtk_tree_store_append(GTK_TREE_STORE(tm), &iter, NULL);
  gtk_tree_store_set(GTK_TREE_STORE(tm), &iter, 0, "Click the check
box", -1);
  gtk_tree_store_append(GTK_TREE_STORE(tm), &iter, NULL);
  gtk_tree_store_set(GTK_TREE_STORE(tm), &iter, 0, "Why are all check
boxes affected?", -1);
  gtk_tree_store_append(GTK_TREE_STORE(tm), &iter, NULL);
  gtk_tree_store_set(GTK_TREE_STORE(tm), &iter, 0, "Click the check box
again",
-1);
  gtk_tree_store_append(GTK_TREE_STORE(tm), &iter, NULL);
  gtk_tree_store_set(GTK_TREE_STORE(tm), &iter, 0, "Move the mouse over
the other rows.", -1);
  gtk_tree_store_append(GTK_TREE_STORE(tm), &iter, NULL);
  gtk_tree_store_set(GTK_TREE_STORE(tm), &iter, 0, "Where does the mouse
over event come from and why are the check boxes getting toggled?", -1);
                                                                                
  gtk_main();
                                                                                
  return 0;
}
                                                                                
void treeStore0(GtkWidget *tv) {
  GtkTreeStore *ts=NULL;
                                                                                
  ts=gtk_tree_store_new(COL_NUM,     /* Total number of columns */
    G_TYPE_STRING,      /* <Description>        */
    G_TYPE_BOOLEAN      /* Check Box - Disable item */
  );
                                                                                
  gtk_tree_view_set_model(GTK_TREE_VIEW(tv), GTK_TREE_MODEL(ts));
}
                                                                                
                                                                                
void treeView0(GtkWidget *tv) {
  GtkCellRenderer *renderer=NULL;
  GtkTreeViewColumn *column=NULL;
  gint col_num=0;
                                                                                
  /* --- Description --- */
  renderer = gtk_cell_renderer_text_new();
  g_object_set(renderer, "editable", TRUE, NULL);
  g_object_set(G_OBJECT(renderer), "width-chars", 100, NULL);
                                                                                
  /* Create a Column */
  column=gtk_tree_view_column_new();
  gtk_tree_view_column_set_title(column, "Description");
  gtk_tree_view_column_pack_start(column, renderer, FALSE);
  gtk_tree_view_column_set_attributes(column, renderer, "text",
COL_DESC, NULL);  col_num=gtk_tree_view_insert_column(GTK_TREE_VIEW(tv),
column, -1);
                                                                                
  /* FIELD is the column number not the index:  always one more than
index. */
  g_object_set_data(G_OBJECT(renderer), "FIELD",
GUINT_TO_POINTER(col_num));
                                                                                
                                                                                
  /* --- Disable Check Box --- */
  renderer=gtk_cell_renderer_toggle_new();
                                                                                
  g_signal_connect(renderer, "toggled", G_CALLBACK(itemToggled), tv);
                                                                                
  /* Create a Column */
  column=gtk_tree_view_column_new();
  gtk_tree_view_column_set_title(column, "Disable");
  gtk_tree_view_column_pack_start(column, renderer, FALSE);
  // Why does setting attributes cause errors and seems unnecessary
anyway?
  //gtk_tree_view_column_set_attributes(column, renderer, "activatable",
TRUE, "active", FALSE, NULL);
  col_num=gtk_tree_view_insert_column(GTK_TREE_VIEW(tv), column, -1);
                                                                                

col_num=gtk_tree_model_get_n_columns(gtk_tree_view_get_model(GTK_TREE_VIEW(tv)));
  /* FIELD is the column number not the index:  always one more than
index. */
  g_object_set_data(G_OBJECT(renderer), "FIELD",
GUINT_TO_POINTER(col_num));
}
                                                                                
                                                                                
/* itemToggled() is basically from the gtk-demo application.  The major
 * difference is the call to gtk_cell_renderer_toggle_set_active()
 * which I don't understand why gtk-demo doesn't do it.*/
void itemToggled(GtkCellRendererToggle *cell, gchar *path, gpointer
data) {
  GtkTreeModel *tm=NULL;
  GtkTreePath *tp=gtk_tree_path_new_from_string(path);
  GtkTreeIter iter;
  gboolean toggle_item=FALSE;
  gint col_num=0;
                                                                                
  tm=gtk_tree_view_get_model(GTK_TREE_VIEW(data));
  if(tm==NULL) {
    g_error("%s:%d Tree Model is NULL", __FILE__, __LINE__);
  }
                                                                                
  col_num=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cell), "FIELD"));
  col_num--; /* FIELD is set to the column number not the index:
decrement. */
                                                                                
  /* get toggled iter */
  gtk_tree_model_get_iter(tm, &iter, tp);
                                                                                
  /* get the toggle value */
  gtk_tree_model_get(tm, &iter, col_num, &toggle_item, -1);
                                                                                
  toggle_item^=1; /* flip the value */
  /* set the new toggle value */
  gtk_tree_store_set(GTK_TREE_STORE(tm), &iter, col_num, toggle_item,
-1);
  g_print("TOGGLE set to {%s}\n", (toggle_item)?"TRUE":"FALSE");
                                                                                
  /* Redisplay the toggle with the appropriate state.
   * gtk-demo doesn't have this but it seems necessary. */
  gtk_cell_renderer_toggle_set_active(cell, toggle_item);
                                                                                
  /* clean up */
  gtk_tree_path_free(tp);
}
                                                                                
void destroyCb(GtkWidget *widget, gpointer data) {
  gtk_main_quit();
  return;
}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]