diff options
author | Tristan Van Berkom <tristan.van.berkom@gmail.com> | 2010-11-11 18:13:54 +0900 |
---|---|---|
committer | Tristan Van Berkom <tristan.van.berkom@gmail.com> | 2010-11-11 18:13:54 +0900 |
commit | 33db66e728357752c8d0ee90b324a5bfab469c72 (patch) | |
tree | 8355dc59dbede9cb52a97cf6fd1fc6849308e1ca /gtk/gtkcellareabox.c | |
parent | f330b40521cf1f5b2b33b33bf7c5df0f59355838 (diff) | |
download | gtk+-33db66e728357752c8d0ee90b324a5bfab469c72.tar.gz |
Added event handling to GtkCellAreaBox
Now GtkCellAreaBox handles the click event to activate renderers
and checks if the area is in a sibling of a focus renderer, possibly
activating the proper focus sibling renderer.
Also GtkCellArea gains a "focus-changed" signal to allow it to
change the currently focused row according to the button events.
Diffstat (limited to 'gtk/gtkcellareabox.c')
-rw-r--r-- | gtk/gtkcellareabox.c | 98 |
1 files changed, 97 insertions, 1 deletions
diff --git a/gtk/gtkcellareabox.c b/gtk/gtkcellareabox.c index 45355aebe5..0b0f23c624 100644 --- a/gtk/gtkcellareabox.c +++ b/gtk/gtkcellareabox.c @@ -892,9 +892,102 @@ gtk_cell_area_box_event (GtkCellArea *area, /* Also detect mouse events, for mouse events we need to allocate the renderers * and find which renderer needs to be activated. */ + if (event->type == GDK_BUTTON_PRESS) + { + GdkEventButton *button_event = (GdkEventButton *)event; + + if (button_event->button == 1) + { + GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area); + GtkCellAreaBoxPrivate *priv = box->priv; + GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter); + GSList *allocated_cells, *l; + GdkRectangle cell_background, inner_area; + GtkAllocation allocation; + gint event_x, event_y; + + gtk_widget_get_allocation (widget, &allocation); + + /* We may need some semantics to tell us the offset of the event + * window we are handling events for (i.e. GtkTreeView has a bin_window) */ + event_x = button_event->x; + event_y = button_event->y; + + cell_background = *cell_area; + + /* Get a list of cells with allocation sizes decided regardless + * of alignments and pack order etc. */ + allocated_cells = get_allocated_cells (box, box_iter, widget); + + for (l = allocated_cells; l; l = l->next) + { + AllocatedCell *cell = l->data; + + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + cell_background.x = cell_area->x + cell->position; + cell_background.width = cell->size; + } + else + { + cell_background.y = cell_area->y + cell->position; + cell_background.height = cell->size; + } + + /* Remove margins from the background area to produce the cell area + */ + gtk_cell_area_inner_cell_area (area, &cell_background, &inner_area); + + if (event_x >= inner_area.x && event_x <= inner_area.x + inner_area.width && + event_y >= inner_area.y && event_y <= inner_area.y + inner_area.height) + { + GtkCellRenderer *event_renderer = NULL; + if (gtk_cell_renderer_can_focus (cell->renderer)) + event_renderer = cell->renderer; + else + { + GtkCellRenderer *focus_renderer; + + /* A renderer can have focus siblings but that renderer might not be + * focusable for every row... so we go on to check can_focus here. */ + focus_renderer = gtk_cell_area_get_focus_from_sibling (area, cell->renderer); + + if (focus_renderer && gtk_cell_renderer_can_focus (focus_renderer)) + event_renderer = focus_renderer; + } - return 0; + if (event_renderer) + { + if (gtk_cell_area_get_edited_cell (area)) + { + /* XXX Was it really canceled in this case ? */ + gtk_cell_area_stop_editing (area, TRUE); + gtk_cell_area_set_focus_cell (area, event_renderer); + retval = TRUE; + } + else + { + /* If we are activating via a focus sibling, we need to fix the + * cell area */ + if (event_renderer != cell->renderer) + gtk_cell_area_inner_cell_area (area, cell_area, &cell_background); + + gtk_cell_area_set_focus_cell (area, event_renderer); + + retval = gtk_cell_area_activate_cell (area, widget, event_renderer, + event, &cell_background, flags); + } + break; + } + } + } + g_slist_foreach (allocated_cells, (GFunc)allocated_cell_free, NULL); + g_slist_free (allocated_cells); + } + } + + return retval; } static void @@ -948,6 +1041,9 @@ gtk_cell_area_box_render (GtkCellArea *area, */ gtk_cell_area_inner_cell_area (area, &cell_background, &inner_area); + /* XXX TODO Here after getting the inner area of the cell background, + * add portions of the background area to the cell background */ + if (focus_cell && (cell->renderer == focus_cell || gtk_cell_area_is_focus_sibling (area, focus_cell, cell->renderer))) |