shortcuts: Support direction-specific shortcuts

The prime example for direction-dependent shortcuts is using
<Alt>Left or <Alt>Right to go back. Support this by adding a
direction property to GtkShortcutsShortcut, and filtering by
the current text direction.

https://bugzilla.gnome.org/show_bug.cgi?id=757888
This commit is contained in:
Matthias Clasen
2015-11-14 22:34:19 -05:00
parent 705d371362
commit 9b041ae930
4 changed files with 113 additions and 11 deletions

View File

@@ -114,9 +114,13 @@ gtk_shortcuts_group_get_height (GtkShortcutsGroup *group)
children = gtk_container_get_children (GTK_CONTAINER (group));
for (l = children; l; l = l->next)
{
if (GTK_IS_SHORTCUTS_SHORTCUT (l->data))
GtkWidget *child = l->data;
if (!gtk_widget_get_visible (child))
continue;
else if (GTK_IS_SHORTCUTS_SHORTCUT (child))
height += 1;
else if (GTK_IS_SHORTCUTS_GESTURE (l->data))
else if (GTK_IS_SHORTCUTS_GESTURE (child))
height += 2;
}
g_list_free (children);
@@ -164,6 +168,14 @@ gtk_shortcuts_group_get_property (GObject *object,
}
}
static void
gtk_shortcuts_group_direction_changed (GtkWidget *widget,
GtkTextDirection previous_dir)
{
GTK_WIDGET_CLASS (gtk_shortcuts_group_parent_class)->direction_changed (widget, previous_dir);
g_object_notify (G_OBJECT (widget), "height");
}
static void
gtk_shortcuts_group_set_property (GObject *object,
guint prop_id,
@@ -209,13 +221,15 @@ gtk_shortcuts_group_finalize (GObject *object)
static void
gtk_shortcuts_group_class_init (GtkShortcutsGroupClass *klass)
{
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
object_class->finalize = gtk_shortcuts_group_finalize;
object_class->get_property = gtk_shortcuts_group_get_property;
object_class->set_property = gtk_shortcuts_group_set_property;
widget_class->direction_changed = gtk_shortcuts_group_direction_changed;
container_class->add = gtk_shortcuts_group_add;
/**

View File

@@ -557,12 +557,18 @@ gtk_shortcuts_section_reflow_groups (GtkShortcutsSection *self)
if (n_rows == 0 || n_rows + height > self->max_height)
{
GtkWidget *column;
GtkSizeGroup *group;
column = gtk_box_new (GTK_ORIENTATION_VERTICAL, 22);
gtk_widget_show (column);
g_object_set_data_full (G_OBJECT (column), "accel-size-group", gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL), g_object_unref);
g_object_set_data_full (G_OBJECT (column), "title-size-group", gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL), g_object_unref);
group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
gtk_size_group_set_ignore_hidden (group, TRUE);
g_object_set_data_full (G_OBJECT (column), "accel-size-group", group, g_object_unref);
group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
gtk_size_group_set_ignore_hidden (group, TRUE);
g_object_set_data_full (G_OBJECT (column), "title-size-group", group, g_object_unref);
if (n_columns % 2 == 0)
{
@@ -598,14 +604,19 @@ gtk_shortcuts_section_reflow_groups (GtkShortcutsSection *self)
if (n_columns % 2 == 1)
{
GtkWidget *column;
GtkSizeGroup *group;
GList *content;
guint n;
column = gtk_box_new (GTK_ORIENTATION_VERTICAL, 22);
gtk_widget_show (column);
g_object_set_data_full (G_OBJECT (column), "accel-size-group", gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL), g_object_unref);
g_object_set_data_full (G_OBJECT (column), "title-size-group", gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL), g_object_unref);
group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
gtk_size_group_set_ignore_hidden (group, TRUE);
g_object_set_data_full (G_OBJECT (column), "accel-size-group", group, g_object_unref);
group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
gtk_size_group_set_ignore_hidden (group, TRUE);
g_object_set_data_full (G_OBJECT (column), "title-size-group", group, g_object_unref);
gtk_container_add (GTK_CONTAINER (current_page), column);

View File

@@ -43,6 +43,8 @@ struct _GtkShortcutsShortcut
GtkSizeGroup *accel_size_group;
GtkSizeGroup *title_size_group;
GtkTextDirection direction;
};
struct _GtkShortcutsShortcutClass
@@ -58,6 +60,7 @@ enum {
PROP_TITLE,
PROP_ACCEL_SIZE_GROUP,
PROP_TITLE_SIZE_GROUP,
PROP_DIRECTION,
LAST_PROP
};
@@ -105,11 +108,46 @@ gtk_shortcuts_shortcut_get_property (GObject *object,
g_value_set_string (value, gtk_shortcut_label_get_accelerator (self->accelerator));
break;
case PROP_DIRECTION:
g_value_set_enum (value, self->direction);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
update_visible (GtkShortcutsShortcut *self)
{
if (self->direction == GTK_TEXT_DIR_NONE ||
self->direction == gtk_widget_get_direction (GTK_WIDGET (self)))
gtk_widget_set_visible (GTK_WIDGET (self), TRUE);
else
gtk_widget_set_visible (GTK_WIDGET (self), FALSE);
}
static void
gtk_shortcuts_shortcut_set_direction (GtkShortcutsShortcut *self,
GtkTextDirection direction)
{
if (self->direction == direction)
return;
self->direction = direction;
update_visible (self);
}
static void
gtk_shortcuts_shortcut_direction_changed (GtkWidget *widget,
GtkTextDirection previous_dir)
{
update_visible (GTK_SHORTCUTS_SHORTCUT (widget));
GTK_WIDGET_CLASS (gtk_shortcuts_shortcut_parent_class)->direction_changed (widget, previous_dir);
}
static void
gtk_shortcuts_shortcut_set_property (GObject *object,
guint prop_id,
@@ -136,6 +174,10 @@ gtk_shortcuts_shortcut_set_property (GObject *object,
gtk_shortcuts_shortcut_set_title_size_group (self, GTK_SIZE_GROUP (g_value_get_object (value)));
break;
case PROP_DIRECTION:
gtk_shortcuts_shortcut_set_direction (self, g_value_get_enum (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -169,13 +211,16 @@ gtk_shortcuts_shortcut_child_type (GtkContainer *container)
static void
gtk_shortcuts_shortcut_class_init (GtkShortcutsShortcutClass *klass)
{
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
object_class->finalize = gtk_shortcuts_shortcut_finalize;
object_class->get_property = gtk_shortcuts_shortcut_get_property;
object_class->set_property = gtk_shortcuts_shortcut_set_property;
widget_class->direction_changed = gtk_shortcuts_shortcut_direction_changed;
container_class->add = gtk_shortcuts_shortcut_add;
container_class->child_type = gtk_shortcuts_shortcut_child_type;
@@ -248,6 +293,14 @@ gtk_shortcuts_shortcut_class_init (GtkShortcutsShortcutClass *klass)
GTK_TYPE_SIZE_GROUP,
(G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
properties[PROP_DIRECTION] =
g_param_spec_enum ("direction",
P_("Direction"),
P_("Direction"),
GTK_TYPE_TEXT_DIRECTION,
GTK_TEXT_DIR_NONE,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, LAST_PROP, properties);
}
@@ -257,6 +310,8 @@ gtk_shortcuts_shortcut_init (GtkShortcutsShortcut *self)
gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_HORIZONTAL);
gtk_box_set_spacing (GTK_BOX (self), 12);
self->direction = GTK_TEXT_DIR_NONE;
self->accelerator = g_object_new (GTK_TYPE_SHORTCUT_LABEL,
"visible", TRUE,
NULL);

View File

@@ -184,6 +184,7 @@ gtk_shortcuts_window_add_search_item (GtkWidget *child, gpointer data)
gchar *title = NULL;
gchar *hash_key = NULL;
GIcon *icon = NULL;
GtkTextDirection direction;
gchar *str;
gchar *keywords;
@@ -192,6 +193,7 @@ gtk_shortcuts_window_add_search_item (GtkWidget *child, gpointer data)
g_object_get (child,
"accelerator", &accelerator,
"title", &title,
"direction", &direction,
NULL);
hash_key = g_strdup_printf ("%s-%s", title, accelerator);
@@ -206,9 +208,9 @@ gtk_shortcuts_window_add_search_item (GtkWidget *child, gpointer data)
g_hash_table_insert (priv->search_items_hash, hash_key, GINT_TO_POINTER (1));
item = g_object_new (GTK_TYPE_SHORTCUTS_SHORTCUT,
"visible", TRUE,
"accelerator", accelerator,
"title", title,
"direction", direction,
"accel-size-group", priv->search_image_group,
"title-size-group", priv->search_text_group,
NULL);
@@ -244,7 +246,6 @@ gtk_shortcuts_window_add_search_item (GtkWidget *child, gpointer data)
g_hash_table_insert (priv->search_items_hash, hash_key, GINT_TO_POINTER (1));
item = g_object_new (GTK_TYPE_SHORTCUTS_GESTURE,
"visible", TRUE,
"title", title,
"subtitle", subtitle,
"icon", icon,
@@ -379,6 +380,22 @@ gtk_shortcuts_window__list_box__row_activated (GtkShortcutsWindow *self,
gtk_widget_hide (GTK_WIDGET (priv->popover));
}
static gboolean
hidden_by_direction (GtkWidget *widget)
{
if (GTK_IS_SHORTCUTS_SHORTCUT (widget))
{
GtkTextDirection dir;
g_object_get (widget, "direction", &dir, NULL);
if (dir != GTK_TEXT_DIR_NONE &&
dir != gtk_widget_get_direction (widget))
return TRUE;
}
return FALSE;
}
static void
gtk_shortcuts_window__entry__changed (GtkShortcutsWindow *self,
GtkSearchEntry *search_entry)
@@ -400,6 +417,7 @@ gtk_shortcuts_window__entry__changed (GtkShortcutsWindow *self,
{
gtk_stack_set_visible_child_name (priv->stack, priv->last_section_name);
return;
}
}
@@ -423,7 +441,11 @@ gtk_shortcuts_window__entry__changed (GtkShortcutsWindow *self,
const gchar *keywords = value;
gboolean match;
match = strstr (keywords, downcase) != NULL;
if (hidden_by_direction (widget))
match = FALSE;
else
match = strstr (keywords, downcase) != NULL;
gtk_widget_set_visible (widget, match);
has_result |= match;
}