marks in iconview made clickable
authorVladimir Nadvornik <nadvornik@suse.cz>
Sat, 16 Aug 2008 23:37:26 +0000 (23:37 +0000)
committerVladimir Nadvornik <nadvornik@suse.cz>
Sat, 16 Aug 2008 23:37:26 +0000 (23:37 +0000)
src/cellrenderericon.c
src/cellrenderericon.h
src/filedata.c
src/filedata.h
src/view_file_icon.c

index a704e70..f712fa2 100644 (file)
@@ -56,6 +56,18 @@ static void gqv_cell_renderer_icon_render(GtkCellRenderer    *cell,
                                           GdkRectangle         *expose_area,
                                           GtkCellRendererState flags);
 
+static gint gqv_cell_renderer_icon_activate (GtkCellRenderer      *cell,
+                                            GdkEvent             *event,
+                                            GtkWidget            *widget,
+                                            const gchar          *path,
+                                            GdkRectangle         *background_area,
+                                            GdkRectangle         *cell_area,
+                                            GtkCellRendererState  flags);
+
+enum {
+  TOGGLED,
+  LAST_SIGNAL
+};
 
 enum {
        PROP_ZERO,
@@ -72,9 +84,12 @@ enum {
        PROP_SHOW_TEXT,
        PROP_SHOW_MARKS,
        PROP_NUM_MARKS,
-       PROP_MARKS
+       PROP_MARKS,
+       PROP_TOGGLED
 };
 
+static guint toggle_cell_signals[LAST_SIGNAL] = { 0 };
+
 static gpointer parent_class;
 
 GType
@@ -109,6 +124,7 @@ gqv_cell_renderer_icon_get_type(void)
 static void
 gqv_cell_renderer_icon_init(GQvCellRendererIcon *cellicon)
 {
+       GTK_CELL_RENDERER(cellicon)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
        GTK_CELL_RENDERER(cellicon)->xpad = 2;
        GTK_CELL_RENDERER(cellicon)->ypad = 2;
 }
@@ -128,6 +144,7 @@ gqv_cell_renderer_icon_class_init(GQvCellRendererIconClass *class)
 
        cell_class->get_size = gqv_cell_renderer_icon_get_size;
        cell_class->render = gqv_cell_renderer_icon_render;
+       cell_class->activate = gqv_cell_renderer_icon_activate;
 
        g_object_class_install_property(object_class,
                                        PROP_PIXBUF,
@@ -236,6 +253,25 @@ gqv_cell_renderer_icon_class_init(GQvCellRendererIconClass *class)
                                                        0, 0xffffffff,
                                                        0,
                                                        G_PARAM_READWRITE));
+
+       g_object_class_install_property(object_class,
+                                       PROP_TOGGLED,
+                                       g_param_spec_uint("toggled_mark",
+                                                       _("Toggled mark"),
+                                                       _("Toggled mark"),
+                                                       0, 32,
+                                                       0,
+                                                       G_PARAM_READWRITE));
+       toggle_cell_signals[TOGGLED] = 
+               g_signal_new ("toggled",
+               G_OBJECT_CLASS_TYPE (object_class),
+               G_SIGNAL_RUN_LAST,
+               G_STRUCT_OFFSET (GQvCellRendererIconClass, toggled),
+               NULL, NULL,
+               g_cclosure_marshal_VOID__STRING,
+               G_TYPE_NONE, 1,
+               G_TYPE_STRING);
+
 }
 
 static void
@@ -315,6 +351,9 @@ gqv_cell_renderer_icon_get_property(GObject *object,
        case PROP_MARKS:
                g_value_set_uint(value, cellicon->marks);
                break;
+       case PROP_TOGGLED:
+               g_value_set_uint(value, cellicon->toggled_mark);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
                break;
@@ -727,3 +766,52 @@ gqv_cell_renderer_icon_render(GtkCellRenderer              *cell,
                                cell_area->width, cell_area->height);
                }
 }
+
+static gint
+gqv_cell_renderer_icon_activate (GtkCellRenderer      *cell,
+                                GdkEvent             *event,
+                                GtkWidget            *widget,
+                                const gchar          *path,
+                                GdkRectangle         *background_area,
+                                GdkRectangle         *cell_area,
+                                GtkCellRendererState  flags)
+{
+       GQvCellRendererIcon *cellicon = (GQvCellRendererIcon *) cell;
+       GdkEventButton      *bevent = &event->button;
+
+       if (cellicon->show_marks &&
+           event->type == GDK_BUTTON_PRESS &&
+            !(bevent->state & GDK_SHIFT_MASK ) &&
+            !(bevent->state & GDK_CONTROL_MASK ))
+               {
+               GdkRectangle rect;
+               GdkRectangle cell_rect;
+               gint i;
+               
+               gqv_cell_renderer_icon_get_size(cell, widget, cell_area,
+                                               &cell_rect.x, &cell_rect.y,
+                                               &cell_rect.width, &cell_rect.height);
+
+               cell_rect.x += cell->xpad;
+               cell_rect.y += cell->ypad;
+               cell_rect.width -= cell->xpad * 2;
+               cell_rect.height -= cell->ypad * 2;
+
+               rect.width = TOGGLE_WIDTH;
+               rect.height = TOGGLE_WIDTH;
+               rect.y = cell_area->y + cell->ypad + (cell_rect.height - TOGGLE_SPACING) + (TOGGLE_SPACING - TOGGLE_WIDTH) / 2;
+               for (i = 0; i < cellicon->num_marks; i++)
+                       {
+                       rect.x = cell_area->x + cell->xpad + (cell_rect.width - TOGGLE_SPACING * cellicon->num_marks + 1) / 2 + i * TOGGLE_SPACING;
+                       
+                       if (bevent->x >= rect.x && bevent->x < rect.x + rect.width &&
+                           bevent->y >= rect.y && bevent->y < rect.y + rect.height)
+                               {
+                               cellicon->toggled_mark = i;
+                               g_signal_emit (cell, toggle_cell_signals[TOGGLED], 0, path);
+                               break;
+                               }
+                       }
+               }
+       return FALSE;
+}
index 5c278dc..2bd99e7 100644 (file)
@@ -62,6 +62,7 @@ struct _GQvCellRendererIcon
        gboolean show_marks;
        
        guint marks;
+       guint toggled_mark;
        
 };
 
@@ -69,6 +70,9 @@ struct _GQvCellRendererIconClass
 {
        GtkCellRendererClass parent_class;
 
+       void (* toggled) (GQvCellRendererIcon *cell_renderer,
+                   const gchar                 *path);
+
        /* Padding for future expansion */
        void (*_gtk_reserved1)(void);
        void (*_gtk_reserved2)(void);
index 718857f..2b11f8d 100644 (file)
@@ -1059,6 +1059,11 @@ gboolean file_data_get_mark(FileData *fd, gint n)
        return !!(fd->marks & (1 << n));
 }
 
+guint file_data_get_marks(FileData *fd)
+{
+       return fd->marks;
+}
+
 void file_data_set_mark(FileData *fd, gint n, gboolean value)
 {
        guint old = fd->marks;
index 1ce28fa..8192058 100644 (file)
@@ -64,6 +64,7 @@ GList *filelist_sort_path(GList *list);
 GList *filelist_recursive(FileData *dir_fd);
 
 gboolean file_data_get_mark(FileData *fd, gint n);
+guint file_data_get_marks(FileData *fd);
 void file_data_set_mark(FileData *fd, gint n, gboolean value);
 gboolean file_data_filter_marks(FileData *fd, guint filter);
 GList *file_data_filter_marks_list(GList *list, guint filter);
index a30530c..c61833c 100644 (file)
@@ -369,6 +369,35 @@ static IconData *vficon_find_data_by_coord(ViewFile *vf, gint x, gint y, GtkTree
        return NULL;
 }
 
+static void vficon_mark_toggled_cb(GtkCellRendererToggle *cell, gchar *path_str, gpointer data)
+{
+       ViewFile *vf = data;
+       GtkTreeModel *store;
+       GtkTreePath *path = gtk_tree_path_new_from_string(path_str);
+       GtkTreeIter row;
+       gint column;
+       GList *list;
+       guint toggled_mark;
+
+       store = gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview));
+       if (!path || !gtk_tree_model_get_iter(store, &row, path))
+               return;
+
+       gtk_tree_model_get(store, &row, FILE_COLUMN_POINTER, &list, -1);
+
+       column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cell), "column_number"));
+       g_object_get(G_OBJECT(cell), "toggled_mark", &toggled_mark, NULL);
+
+       IconData *id = g_list_nth_data(list, column);
+       
+       if (id)
+               {
+               FileData *fd = id->fd;
+               file_data_set_mark(fd, toggled_mark, !file_data_get_mark(fd, toggled_mark));
+               }
+}
+
+
 /*
  *-------------------------------------------------------------------
  * tooltip type window
@@ -1380,7 +1409,7 @@ gint vficon_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data)
                        break;
                }
 
-       return TRUE;
+       return FALSE;
 }
 
 gint vficon_release_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data)
@@ -2283,7 +2312,7 @@ static void vficon_cell_data_cb(GtkTreeViewColumn *tree_column, GtkCellRenderer
 
                        g_object_set(cell,      "pixbuf", id->fd->thumb_pixbuf,
                                                "text", name_sidecars,
-                                               "marks", id->fd->marks,
+                                               "marks", file_data_get_marks(id->fd),
                                                "show_marks", vf->marks_enabled,
                                                "cell-background-gdk", &color_bg,
                                                "cell-background-set", TRUE,
@@ -2327,6 +2356,7 @@ static void vficon_append_column(ViewFile *vf, gint n)
                                         "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
 
        g_object_set_data(G_OBJECT(column), "column_number", GINT_TO_POINTER(n));
+       g_object_set_data(G_OBJECT(renderer), "column_number", GINT_TO_POINTER(n));
 
        cd = g_new0(ColumnData, 1);
        cd->vf = vf;
@@ -2334,6 +2364,8 @@ static void vficon_append_column(ViewFile *vf, gint n)
        gtk_tree_view_column_set_cell_data_func(column, renderer, vficon_cell_data_cb, cd, g_free);
 
        gtk_tree_view_append_column(GTK_TREE_VIEW(vf->listview), column);
+       
+       g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(vficon_mark_toggled_cb), vf);
 }
 
 /*