[egg-list-box/row-widget: 7/7] listbox: Move focusability to row widget
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [egg-list-box/row-widget: 7/7] listbox: Move focusability to row widget
- Date: Mon, 10 Jun 2013 08:43:50 +0000 (UTC)
commit db44b5ef9a24ef7ad8e0a785ed182e575d946deb
Author: Alexander Larsson <alexl redhat com>
Date: Fri Jun 7 17:03:34 2013 +0200
listbox: Move focusability to row widget
We set the focused widget to be the actual row, rather
than the listbox.
egg-list-box.c | 236 +++++++++++++++++++++++++++++---------------------------
1 files changed, 121 insertions(+), 115 deletions(-)
---
diff --git a/egg-list-box.c b/egg-list-box.c
index c6851fc..abe7c8e 100644
--- a/egg-list-box.c
+++ b/egg-list-box.c
@@ -224,7 +224,6 @@ egg_list_box_init (EggListBox *list_box)
list_box->priv = priv =
G_TYPE_INSTANCE_GET_PRIVATE (list_box, EGG_TYPE_LIST_BOX, EggListBoxPrivate);
- gtk_widget_set_can_focus (GTK_WIDGET (list_box), TRUE);
gtk_widget_set_has_window (GTK_WIDGET (list_box), TRUE);
gtk_widget_set_redraw_on_allocate (GTK_WIDGET (list_box), TRUE);
priv->selection_mode = GTK_SELECTION_SINGLE;
@@ -794,8 +793,8 @@ egg_list_box_update_cursor (EggListBox *list_box,
EggListBoxPrivate *priv = list_box->priv;
priv->cursor_row = row;
- gtk_widget_grab_focus (GTK_WIDGET (list_box));
- gtk_widget_queue_draw (GTK_WIDGET (list_box));
+ gtk_widget_grab_focus (GTK_WIDGET (row));
+ gtk_widget_queue_draw (GTK_WIDGET (row));
if (row != NULL && priv->adjustment != NULL)
{
GtkAllocation allocation;
@@ -1026,134 +1025,65 @@ egg_list_box_real_focus (GtkWidget* widget, GtkDirectionType direction)
{
EggListBox *list_box = EGG_LIST_BOX (widget);
EggListBoxPrivate *priv = list_box->priv;
- gboolean had_focus = FALSE;
- gboolean focus_into = FALSE;
- EggListBoxRow *recurse_into;
- EggListBoxRow *current_focus_row;
+ GtkWidget *focus_child;
EggListBoxRow *next_focus_row;
- gboolean modify_selection_pressed;
- GdkModifierType state = 0;
-
- recurse_into = NULL;
- focus_into = TRUE;
- g_object_get (GTK_WIDGET (list_box), "has-focus", &had_focus, NULL);
- current_focus_row = NULL;
+ focus_child = gtk_container_get_focus_child ((GtkContainer*) list_box);
next_focus_row = NULL;
- if (had_focus)
+ if (focus_child != NULL)
{
- /* If on row, going right, enter into possible container */
- if (direction == GTK_DIR_RIGHT || direction == GTK_DIR_TAB_FORWARD)
- {
- if (priv->cursor_row != NULL)
- recurse_into = priv->cursor_row;
- }
- current_focus_row = priv->cursor_row;
- /* Unless we're going up/down we're always leaving
- the container */
- if (direction != GTK_DIR_UP && direction != GTK_DIR_DOWN)
- focus_into = FALSE;
- }
- else if (gtk_container_get_focus_child ((GtkContainer*) list_box) != NULL)
- {
- /* There is a focus child, always navigate inside it first */
- recurse_into = EGG_LIST_BOX_ROW (gtk_container_get_focus_child ((GtkContainer*) list_box));
- current_focus_row = recurse_into;
+ GSequenceIter* i;
- /* If exiting child container to the right, exit row */
- if (direction == GTK_DIR_RIGHT || direction == GTK_DIR_TAB_FORWARD)
- focus_into = FALSE;
+ if (gtk_widget_child_focus (focus_child, direction))
+ return TRUE;
- /* If exiting child container to the left, select row or out */
- if (direction == GTK_DIR_LEFT || direction == GTK_DIR_TAB_BACKWARD)
- next_focus_row = current_focus_row;
+ if (direction == GTK_DIR_UP || direction == GTK_DIR_TAB_BACKWARD)
+ {
+ i = egg_list_box_get_previous_visible (list_box, priv->cursor_row->priv->iter);
+ if (i != NULL)
+ next_focus_row = g_sequence_get (i);
+ }
+ else if (direction == GTK_DIR_DOWN || direction == GTK_DIR_TAB_FORWARD)
+ {
+ i = egg_list_box_get_next_visible (list_box, priv->cursor_row->priv->iter);
+ if (!g_sequence_iter_is_end (i))
+ next_focus_row = g_sequence_get (i);
+ }
}
else
{
- /* If coming from the left, enter into possible container */
- if (direction == GTK_DIR_LEFT || direction == GTK_DIR_TAB_BACKWARD)
- {
- if (priv->selected_row != NULL)
- recurse_into = priv->selected_row;
- }
- }
-
- if (recurse_into != NULL)
- {
- if (gtk_widget_child_focus (GTK_WIDGET (recurse_into), direction))
- return TRUE;
- }
-
- if (!focus_into)
- return FALSE; /* Focus is leaving us */
+ /* No current focus row */
- /* TODO: This doesn't handle up/down going into a focusable separator */
-
- if (next_focus_row == NULL)
- {
- if (current_focus_row != NULL)
- {
- GSequenceIter* i;
- if (direction == GTK_DIR_UP)
- {
- i = egg_list_box_get_previous_visible (list_box, current_focus_row->priv->iter);
- if (i != NULL)
- next_focus_row = g_sequence_get (i);
-
- }
- else
- {
- i = egg_list_box_get_next_visible (list_box, current_focus_row->priv->iter);
- if (!g_sequence_iter_is_end (i))
- next_focus_row = g_sequence_get (i);
- }
- }
- else
- {
- switch (direction)
- {
- case GTK_DIR_UP:
- case GTK_DIR_TAB_BACKWARD:
- next_focus_row = priv->selected_row;
- if (next_focus_row == NULL)
- next_focus_row = egg_list_box_get_last_visible (list_box);
- break;
- default:
- next_focus_row = priv->selected_row;
- if (next_focus_row == NULL)
- next_focus_row =
- egg_list_box_get_first_visible (list_box);
- break;
- }
- }
+ switch (direction)
+ {
+ case GTK_DIR_UP:
+ case GTK_DIR_TAB_BACKWARD:
+ next_focus_row = priv->selected_row;
+ if (next_focus_row == NULL)
+ next_focus_row = egg_list_box_get_last_visible (list_box);
+ break;
+ default:
+ next_focus_row = priv->selected_row;
+ if (next_focus_row == NULL)
+ next_focus_row =
+ egg_list_box_get_first_visible (list_box);
+ break;
+ }
}
if (next_focus_row == NULL)
{
if (direction == GTK_DIR_UP || direction == GTK_DIR_DOWN)
- {
+ {
if (gtk_widget_keynav_failed (GTK_WIDGET (list_box), direction))
- return TRUE;
- }
+ return TRUE;
+ }
return FALSE;
}
- modify_selection_pressed = FALSE;
- if (gtk_get_current_event_state (&state))
- {
- GdkModifierType modify_mod_mask;
- modify_mod_mask =
- gtk_widget_get_modifier_mask (GTK_WIDGET (list_box),
- GDK_MODIFIER_INTENT_MODIFY_SELECTION);
- if ((state & modify_mod_mask) == modify_mod_mask)
- modify_selection_pressed = TRUE;
- }
-
- if (modify_selection_pressed)
- egg_list_box_update_cursor (list_box, next_focus_row);
- else
- egg_list_box_update_selected (list_box, next_focus_row);
+ if (gtk_widget_child_focus (GTK_WIDGET (next_focus_row), direction))
+ return TRUE;
return TRUE;
}
@@ -2022,6 +1952,7 @@ egg_list_box_row_init (EggListBoxRow *row)
row->priv = priv =
G_TYPE_INSTANCE_GET_PRIVATE (row, EGG_TYPE_LIST_BOX_ROW, EggListBoxRowPrivate);
+ gtk_widget_set_can_focus (GTK_WIDGET (row), TRUE);
gtk_widget_set_redraw_on_allocate (GTK_WIDGET (row), TRUE);
}
@@ -2066,6 +1997,83 @@ egg_list_box_row_get_box (EggListBoxRow *row)
}
static void
+egg_list_box_row_set_focus (EggListBoxRow *row)
+{
+ EggListBox *list_box = egg_list_box_row_get_box (row);
+ GdkModifierType state = 0;
+ gboolean modify_selection_pressed;
+
+ modify_selection_pressed = FALSE;
+ if (gtk_get_current_event_state (&state))
+ {
+ GdkModifierType modify_mod_mask;
+ modify_mod_mask =
+ gtk_widget_get_modifier_mask (GTK_WIDGET (list_box),
+ GDK_MODIFIER_INTENT_MODIFY_SELECTION);
+ if ((state & modify_mod_mask) == modify_mod_mask)
+ modify_selection_pressed = TRUE;
+ }
+
+ if (modify_selection_pressed)
+ egg_list_box_update_cursor (list_box, row);
+ else
+ egg_list_box_update_selected (list_box, row);
+}
+
+static gboolean
+egg_list_box_row_real_focus (GtkWidget* widget, GtkDirectionType direction)
+{
+ EggListBoxRow *row = EGG_LIST_BOX_ROW (widget);
+ gboolean had_focus = FALSE;
+ GtkWidget *child;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+
+ g_object_get (widget, "has-focus", &had_focus, NULL);
+ if (had_focus)
+ {
+ /* If on row, going right, enter into possible container */
+ if (child &&
+ (direction == GTK_DIR_RIGHT || direction == GTK_DIR_TAB_FORWARD))
+ {
+ if (gtk_widget_child_focus (GTK_WIDGET (child), direction))
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+ else if (gtk_container_get_focus_child (GTK_CONTAINER (row)) != NULL)
+ {
+ /* Child has focus, always navigate inside it first */
+
+ if (gtk_widget_child_focus (child, direction))
+ return TRUE;
+
+ /* If exiting child container to the left, select row */
+ if (direction == GTK_DIR_LEFT || direction == GTK_DIR_TAB_BACKWARD)
+ {
+ egg_list_box_row_set_focus (row);
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+ else
+ {
+ /* If coming from the left, enter into possible container */
+ if (child &&
+ (direction == GTK_DIR_LEFT || direction == GTK_DIR_TAB_BACKWARD))
+ {
+ if (gtk_widget_child_focus (child, direction))
+ return TRUE;
+ }
+
+ egg_list_box_row_set_focus (row);
+ return TRUE;
+ }
+}
+
+static void
egg_list_box_row_real_show (GtkWidget *widget)
{
EggListBoxRow *row = EGG_LIST_BOX_ROW (widget);
@@ -2095,7 +2103,6 @@ static gboolean
egg_list_box_row_real_draw (GtkWidget* widget, cairo_t* cr)
{
EggListBoxRow *row = EGG_LIST_BOX_ROW (widget);
- EggListBox *list_box;
GtkAllocation allocation = {0};
GtkStyleContext* context;
GtkStateFlags state;
@@ -2109,9 +2116,7 @@ egg_list_box_row_real_draw (GtkWidget* widget, cairo_t* cr)
gtk_render_background (context, cr, (gdouble) 0, (gdouble) 0, (gdouble) allocation.width, (gdouble)
allocation.height);
gtk_render_frame (context, cr, (gdouble) 0, (gdouble) 0, (gdouble) allocation.width, (gdouble)
allocation.height);
- list_box = egg_list_box_row_get_box (row);
- if (list_box && gtk_widget_has_visible_focus (GTK_WIDGET (list_box)) &&
- row == list_box->priv->cursor_row)
+ if (gtk_widget_has_visible_focus (GTK_WIDGET (row)))
{
gtk_style_context_get_border (context, state, &border);
@@ -2318,4 +2323,5 @@ egg_list_box_row_class_init (EggListBoxRowClass *klass)
widget_class->get_preferred_width = egg_list_box_row_real_get_preferred_width;
widget_class->get_preferred_width_for_height = egg_list_box_row_real_get_preferred_width_for_height;
widget_class->size_allocate = egg_list_box_row_real_size_allocate;
+ widget_class->focus = egg_list_box_row_real_focus;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]