[gtk+/treeview-refactor] Implemented focus handling in GtkCellAreaBox
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/treeview-refactor] Implemented focus handling in GtkCellAreaBox
- Date: Mon, 8 Nov 2010 02:29:04 +0000 (UTC)
commit 0336838366389dd22d185324f827538638b1b37f
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Sat Nov 6 16:14:38 2010 +0900
Implemented focus handling in GtkCellAreaBox
Now when the GtkCellAreaBox receives key events it cycles
the currently focused cell to the next focusable cell in the box
while observing the navigation direction, it then emits "focus-leave"
when hitting the boundries of the area.
gtk/gtkcellarea.c | 11 ++--
gtk/gtkcellarea.h | 3 +-
gtk/gtkcellareabox.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 145 insertions(+), 7 deletions(-)
---
diff --git a/gtk/gtkcellarea.c b/gtk/gtkcellarea.c
index d997af0..4032369 100644
--- a/gtk/gtkcellarea.c
+++ b/gtk/gtkcellarea.c
@@ -1725,8 +1725,6 @@ gtk_cell_area_grab_focus (GtkCellArea *area,
* @area: a #GtkCellArea
* @direction: the #GtkDirectionType in which focus
* is to leave @area
- * @path: the current #GtkTreePath string for the
- * event which was handled by @area
*
* Notifies that focus is to leave @area in the
* given @direction.
@@ -1740,12 +1738,15 @@ gtk_cell_area_grab_focus (GtkCellArea *area,
*/
void
gtk_cell_area_focus_leave (GtkCellArea *area,
- GtkDirectionType direction,
- const gchar *path)
+ GtkDirectionType direction)
{
+ GtkCellAreaPrivate *priv;
+
g_return_if_fail (GTK_IS_CELL_AREA (area));
- g_signal_emit (area, cell_area_signals[SIGNAL_FOCUS_LEAVE], 0, direction, path);
+ priv = area->priv;
+
+ g_signal_emit (area, cell_area_signals[SIGNAL_FOCUS_LEAVE], 0, direction, priv->current_path);
}
/**
diff --git a/gtk/gtkcellarea.h b/gtk/gtkcellarea.h
index a0cc50f..0e8a7a9 100644
--- a/gtk/gtkcellarea.h
+++ b/gtk/gtkcellarea.h
@@ -268,8 +268,7 @@ void gtk_cell_area_cell_get_property (GtkCellArea
void gtk_cell_area_grab_focus (GtkCellArea *area,
GtkDirectionType direction);
void gtk_cell_area_focus_leave (GtkCellArea *area,
- GtkDirectionType direction,
- const gchar *path);
+ GtkDirectionType direction);
void gtk_cell_area_update_focus (GtkCellArea *area);
void gtk_cell_area_set_can_focus (GtkCellArea *area,
gboolean can_focus);
diff --git a/gtk/gtkcellareabox.c b/gtk/gtkcellareabox.c
index a2f73bd..3cee4cb 100644
--- a/gtk/gtkcellareabox.c
+++ b/gtk/gtkcellareabox.c
@@ -862,6 +862,97 @@ gtk_cell_area_box_get_cell_allocation (GtkCellArea *area,
g_slist_free (allocated_cells);
}
+enum {
+ FOCUS_NONE,
+ FOCUS_PREV,
+ FOCUS_NEXT
+};
+
+static void
+gtk_cell_area_cycle_focus (GtkCellAreaBox *box,
+ GtkCellRenderer *focus_cell,
+ GtkDirectionType direction)
+{
+ GtkCellAreaBoxPrivate *priv = box->priv;
+ GtkCellArea *area = GTK_CELL_AREA (box);
+ gint cycle = FOCUS_NONE;
+
+ switch (direction)
+ {
+ case GTK_DIR_TAB_FORWARD:
+ cycle = FOCUS_NEXT;
+ break;
+ case GTK_DIR_TAB_BACKWARD:
+ cycle = FOCUS_PREV;
+ break;
+ case GTK_DIR_UP:
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ gtk_cell_area_focus_leave (area, direction);
+ else
+ cycle = FOCUS_PREV;
+ break;
+ case GTK_DIR_DOWN:
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ gtk_cell_area_focus_leave (area, direction);
+ else
+ cycle = FOCUS_NEXT;
+ break;
+ case GTK_DIR_LEFT:
+ if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+ gtk_cell_area_focus_leave (area, direction);
+ else
+ cycle = FOCUS_PREV;
+ break;
+ case GTK_DIR_RIGHT:
+ if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+ gtk_cell_area_focus_leave (area, direction);
+ else
+ cycle = FOCUS_NEXT;
+ break;
+ default:
+ break;
+ }
+
+ if (cycle != FOCUS_NONE)
+ {
+ gboolean found_cell = FALSE;
+ gboolean cycled_focus = FALSE;
+ GList *list;
+ gint i;
+
+ for (i = (cycle == FOCUS_NEXT) ? 0 : priv->groups->len -1;
+ i >= 0 && i < priv->groups->len;
+ i = (cycle == FOCUS_NEXT) ? i + 1 : i - 1)
+ {
+ CellGroup *group = &g_array_index (priv->groups, CellGroup, i);
+
+ for (list = (cycle == FOCUS_NEXT) ? g_list_first (group->cells) : g_list_last (group->cells);
+ list; list = (cycle == FOCUS_NEXT) ? list->next : list->prev)
+ {
+ CellInfo *info = list->data;
+
+ if (!found_cell && info->renderer == focus_cell)
+ found_cell = TRUE;
+ else if (found_cell)
+ {
+ if (gtk_cell_renderer_can_focus (info->renderer))
+ {
+ gtk_cell_area_set_focus_cell (area, info->renderer);
+
+ cycled_focus = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ /* We cycled right out of the area, signal the parent we
+ * need to focus out of the area */
+ if (!cycled_focus)
+ gtk_cell_area_focus_leave (area, direction);
+ }
+}
+
static gint
gtk_cell_area_box_event (GtkCellArea *area,
GtkCellAreaIter *iter,
@@ -887,6 +978,53 @@ gtk_cell_area_box_event (GtkCellArea *area,
* observe the orientation and push focus along to the next cell
* or signal that focus should leave the area.
*/
+ if (event->type == GDK_KEY_PRESS && (flags & GTK_CELL_RENDERER_FOCUSED) != 0)
+ {
+ GdkEventKey *key_event = (GdkEventKey *)event;
+ GtkCellRenderer *focus_cell;
+
+ focus_cell = gtk_cell_area_get_focus_cell (area);
+
+ if (focus_cell)
+ {
+ GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
+ GtkDirectionType direction = GTK_DIR_TAB_FORWARD;
+ gboolean have_direction = FALSE;
+
+ /* Check modifiers and TAB keys ! */
+ switch (key_event->keyval)
+ {
+ case GDK_KEY_KP_Up:
+ case GDK_KEY_Up:
+ direction = GTK_DIR_UP;
+ have_direction = TRUE;
+ break;
+ case GDK_KEY_KP_Down:
+ case GDK_KEY_Down:
+ direction = GTK_DIR_DOWN;
+ have_direction = TRUE;
+ break;
+ case GDK_KEY_KP_Left:
+ case GDK_KEY_Left:
+ direction = GTK_DIR_LEFT;
+ have_direction = TRUE;
+ break;
+ case GDK_KEY_KP_Right:
+ case GDK_KEY_Right:
+ direction = GTK_DIR_RIGHT;
+ have_direction = TRUE;
+ break;
+ default:
+ break;
+ }
+
+ if (have_direction)
+ {
+ gtk_cell_area_cycle_focus (box, focus_cell, direction);
+ return TRUE;
+ }
+ }
+ }
/* Also detect mouse events, for mouse events we need to allocate the renderers
* and find which renderer needs to be activated.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]