[gnome-builder/wip/chergert/shortcuts] shortcuts: bring back search
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/shortcuts] shortcuts: bring back search
- Date: Mon, 31 Aug 2015 06:35:33 +0000 (UTC)
commit c3f4f1c800e649bddf9da5fd8c2b2cb2d98f3a9e
Author: Christian Hergert <christian hergert me>
Date: Sun Aug 30 23:34:28 2015 -0700
shortcuts: bring back search
data/ui/gb-shortcuts-window.ui | 1 +
src/shortcuts/gb-shortcuts-dialog.c | 291 ++++++++++++++++++++++++++++++++-
src/shortcuts/gb-shortcuts-gesture.c | 28 +++-
src/shortcuts/gb-shortcuts-shortcut.c | 28 +++-
4 files changed, 343 insertions(+), 5 deletions(-)
---
diff --git a/data/ui/gb-shortcuts-window.ui b/data/ui/gb-shortcuts-window.ui
index d276aa5..9622b52 100644
--- a/data/ui/gb-shortcuts-window.ui
+++ b/data/ui/gb-shortcuts-window.ui
@@ -2,6 +2,7 @@
<interface>
<!-- interface-requires gtk+ 3.17 -->
<template class="GbShortcutsWindow" parent="GbShortcutsDialog">
+ <property name="view-name">editor</property>
<views>
<view name="editor">
<property name="title" translatable="yes">Editor Shortcuts</property>
diff --git a/src/shortcuts/gb-shortcuts-dialog.c b/src/shortcuts/gb-shortcuts-dialog.c
index 492a36e..1fd8fe4 100644
--- a/src/shortcuts/gb-shortcuts-dialog.c
+++ b/src/shortcuts/gb-shortcuts-dialog.c
@@ -17,6 +17,7 @@
*/
#include <glib/gi18n.h>
+#include <ide.h>
#include "egg-search-bar.h"
@@ -31,6 +32,12 @@
typedef struct
{
+ GHashTable *keywords;
+ gchar *initial_view;
+ gchar *last_view_name;
+ GtkSizeGroup *search_text_group;
+ GtkSizeGroup *search_image_group;
+
GtkStack *stack;
GtkMenuButton *menu_button;
GtkLabel *menu_label;
@@ -39,6 +46,8 @@ typedef struct
GtkHeaderBar *header_bar;
GtkPopover *popover;
GtkListBox *list_box;
+ GtkBox *search_gestures;
+ GtkBox *search_shortcuts;
} GbShortcutsDialogPrivate;
typedef struct
@@ -46,6 +55,7 @@ typedef struct
GbShortcutsDialog *self;
GtkBuilder *builder;
GQueue *stack;
+ GtkWidget *search_item;
GQueue *column_image_size_groups;
GQueue *column_desc_size_groups;
gchar *property_name;
@@ -63,6 +73,13 @@ enum {
LAST_SIGNAL
};
+enum {
+ PROP_0,
+ PROP_VIEW_NAME,
+ LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
static guint gSignals [LAST_SIGNAL];
static void
@@ -128,6 +145,15 @@ gb_shortcuts_dialog__stack__notify_visible_child (GbShortcutsDialog *self,
title = gb_shortcuts_view_get_title (GB_SHORTCUTS_VIEW (visible_child));
gtk_label_set_label (priv->menu_label, title);
}
+ else if (visible_child != NULL)
+ {
+ g_autofree gchar *title = NULL;
+
+ gtk_container_child_get (GTK_CONTAINER (stack), visible_child,
+ "title", &title,
+ NULL);
+ gtk_label_set_label (priv->menu_label, title);
+ }
}
static void
@@ -147,6 +173,112 @@ gb_shortcuts_dialog__list_box__row_activated (GbShortcutsDialog *self,
gtk_widget_hide (GTK_WIDGET (priv->popover));
}
+static void
+gb_shortcuts_dialog_add_search_item (GbShortcutsDialog *self,
+ GtkWidget *search_item)
+{
+ GbShortcutsDialogPrivate *priv = gb_shortcuts_dialog_get_instance_private (self);
+ GString *str = g_string_new (NULL);
+ gchar *downcase;
+
+ g_assert (GB_IS_SHORTCUTS_DIALOG (self));
+ g_assert (GB_IS_SHORTCUTS_SHORTCUT (search_item) || GB_IS_SHORTCUTS_GESTURE (search_item));
+
+ if (GB_IS_SHORTCUTS_SHORTCUT (search_item))
+ {
+ g_autofree gchar *accelerator = NULL;
+ g_autofree gchar *title = NULL;
+
+ g_object_get (search_item,
+ "accelerator", &accelerator,
+ "title", &title,
+ NULL);
+
+ g_object_set (search_item,
+ "accelerator-size-group", priv->search_image_group,
+ "title-size-group", priv->search_text_group,
+ NULL);
+
+ g_string_append_printf (str, "%s %s", accelerator, title);
+
+ gtk_container_add (GTK_CONTAINER (priv->search_shortcuts), search_item);
+ }
+ else if (GB_IS_SHORTCUTS_GESTURE (search_item))
+ {
+ g_autofree gchar *subtitle = NULL;
+ g_autofree gchar *title = NULL;
+
+ g_object_get (search_item,
+ "subtitle", &subtitle,
+ "title", &title,
+ NULL);
+
+ g_object_set (search_item,
+ "icon-size-group", priv->search_image_group,
+ "desc-size-group", priv->search_text_group,
+ NULL);
+
+ g_string_append_printf (str, "%s %s", title, subtitle);
+
+ gtk_container_add (GTK_CONTAINER (priv->search_gestures), search_item);
+ }
+
+ downcase = g_utf8_strdown (str->str, str->len);
+ g_hash_table_insert (priv->keywords, search_item, downcase);
+ g_string_free (str, TRUE);
+}
+
+static void
+gb_shortcuts_dialog__entry__changed (GbShortcutsDialog *self,
+ GtkSearchEntry *search_entry)
+{
+ GbShortcutsDialogPrivate *priv = gb_shortcuts_dialog_get_instance_private (self);
+ g_autoptr(IdePatternSpec) spec = NULL;
+ g_autofree gchar *downcase = NULL;
+ GHashTableIter iter;
+ const gchar *text;
+ const gchar *last_view_name;
+ gpointer key;
+ gpointer value;
+
+ g_assert (GB_IS_SHORTCUTS_DIALOG (self));
+ g_assert (GTK_IS_SEARCH_ENTRY (search_entry));
+
+ text = gtk_entry_get_text (GTK_ENTRY (search_entry));
+
+ if (!text || !*text)
+ {
+ if (priv->last_view_name != NULL)
+ {
+ gtk_stack_set_visible_child_name (priv->stack, priv->last_view_name);
+ return;
+ }
+ }
+
+ last_view_name = gtk_stack_get_visible_child_name (priv->stack);
+
+ if (g_strcmp0 (last_view_name, "internal-search") != 0)
+ {
+ g_free (priv->last_view_name);
+ priv->last_view_name = g_strdup (last_view_name);
+ }
+
+ gtk_stack_set_visible_child_name (priv->stack, "internal-search");
+
+ downcase = g_utf8_strdown (text, -1);
+ spec = ide_pattern_spec_new (downcase);
+
+ g_hash_table_iter_init (&iter, priv->keywords);
+
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ GtkWidget *widget = key;
+ const gchar *keywords = value;
+
+ gtk_widget_set_visible (widget, ide_pattern_spec_match (spec, keywords));
+ }
+}
+
static gboolean
check_parent (GMarkupParseContext *context,
const gchar *element_name,
@@ -263,6 +395,10 @@ views_parser_start_element (GMarkupParseContext *context,
accel_size_group = g_queue_peek_head (parser_data->column_image_size_groups);
desc_size_group = g_queue_peek_head (parser_data->column_desc_size_groups);
+ parser_data->search_item = g_object_new (GB_TYPE_SHORTCUTS_SHORTCUT,
+ "visible", TRUE,
+ NULL);
+
item = g_object_new (GB_TYPE_SHORTCUTS_SHORTCUT,
"accelerator-size-group", accel_size_group,
"title-size-group", desc_size_group,
@@ -281,6 +417,10 @@ views_parser_start_element (GMarkupParseContext *context,
accel_size_group = g_queue_peek_head (parser_data->column_image_size_groups);
desc_size_group = g_queue_peek_head (parser_data->column_desc_size_groups);
+ parser_data->search_item = g_object_new (GB_TYPE_SHORTCUTS_GESTURE,
+ "visible", TRUE,
+ NULL);
+
item = g_object_new (GB_TYPE_SHORTCUTS_GESTURE,
"desc-size-group", desc_size_group,
"icon-size-group", accel_size_group,
@@ -368,6 +508,13 @@ views_parser_end_element (GMarkupParseContext *context,
gtk_container_add (GTK_CONTAINER (parent), GTK_WIDGET (item));
g_clear_object (&item);
+ if ((g_strcmp0 (element_name, "shortcut") == 0) ||
+ (g_strcmp0 (element_name, "gesture") == 0))
+ {
+ gb_shortcuts_dialog_add_search_item (parser_data->self, parser_data->search_item);
+ parser_data->search_item = NULL;
+ }
+
if (g_strcmp0 (element_name, "column") == 0)
{
GtkSizeGroup *size_group;
@@ -446,6 +593,10 @@ views_parser_text (GMarkupParseContext *context,
pspec, text, &value, error))
return;
+ if (parser_data->search_item != NULL)
+ g_object_set_property (G_OBJECT (parser_data->search_item),
+ parser_data->property_name,
+ &value);
g_object_set_property (G_OBJECT (item), parser_data->property_name, &value);
g_value_unset (&value);
}
@@ -519,6 +670,34 @@ gb_shortcuts_dialog_custom_finished (GtkBuildable *buildable,
}
static void
+gb_shortcuts_dialog_constructed (GObject *object)
+{
+ GbShortcutsDialog *self = (GbShortcutsDialog *)object;
+ GbShortcutsDialogPrivate *priv = gb_shortcuts_dialog_get_instance_private (self);
+
+ G_OBJECT_CLASS (gb_shortcuts_dialog_parent_class)->constructed (object);
+
+ if (priv->initial_view != NULL)
+ gtk_stack_set_visible_child_name (priv->stack, priv->initial_view);
+}
+
+static void
+gb_shortcuts_dialog_finalize (GObject *object)
+{
+ GbShortcutsDialog *self = (GbShortcutsDialog *)object;
+ GbShortcutsDialogPrivate *priv = gb_shortcuts_dialog_get_instance_private (self);
+
+ g_clear_pointer (&priv->keywords, g_hash_table_unref);
+ g_clear_pointer (&priv->initial_view, g_free);
+ g_clear_pointer (&priv->last_view_name, g_free);
+
+ g_clear_object (&priv->search_image_group);
+ g_clear_object (&priv->search_text_group);
+
+ G_OBJECT_CLASS (gb_shortcuts_dialog_parent_class)->finalize (object);
+}
+
+static void
gtk_buildable_iface_init (GtkBuildableIface *iface)
{
iface->custom_tag_start = gb_shortcuts_dialog_custom_tag_start;
@@ -526,13 +705,82 @@ gtk_buildable_iface_init (GtkBuildableIface *iface)
}
static void
+gb_shortcuts_dialog_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GbShortcutsDialog *self = (GbShortcutsDialog *)object;
+ GbShortcutsDialogPrivate *priv = gb_shortcuts_dialog_get_instance_private (self);
+
+ switch (prop_id)
+ {
+ case PROP_VIEW_NAME:
+ {
+ GtkWidget *child = gtk_stack_get_visible_child (priv->stack);
+
+ if (child != NULL)
+ {
+ gchar *name = NULL;
+
+ gtk_container_child_get (GTK_CONTAINER (priv->stack), child,
+ "name", &name,
+ NULL);
+ g_value_take_string (value, name);
+ }
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gb_shortcuts_dialog_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GbShortcutsDialog *self = (GbShortcutsDialog *)object;
+ GbShortcutsDialogPrivate *priv = gb_shortcuts_dialog_get_instance_private (self);
+
+ switch (prop_id)
+ {
+ case PROP_VIEW_NAME:
+ g_free (priv->initial_view);
+ priv->initial_view = g_value_dup_string (value);
+ gtk_stack_set_visible_child_name (priv->stack, g_value_get_string (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
gb_shortcuts_dialog_class_init (GbShortcutsDialogClass *klass)
{
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
GtkBindingSet *binding_set = gtk_binding_set_by_class (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructed = gb_shortcuts_dialog_constructed;
+ object_class->finalize = gb_shortcuts_dialog_finalize;
+ object_class->get_property = gb_shortcuts_dialog_get_property;
+ object_class->set_property = gb_shortcuts_dialog_set_property;
container_class->add = gb_shortcuts_dialog_add;
+ gParamSpecs [PROP_VIEW_NAME] =
+ g_param_spec_string ("view-name",
+ "ViewName",
+ "ViewName",
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
+
gSignals [CLOSE] = g_signal_new ("close",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
@@ -557,11 +805,17 @@ gb_shortcuts_dialog_init (GbShortcutsDialog *self)
GtkScrolledWindow *scroller;
GtkBox *main_box;
GtkBox *menu_box;
+ GtkBox *box;
GtkArrow *arrow;
GtkSearchEntry *entry;
gtk_window_set_resizable (GTK_WINDOW (self), FALSE);
+ priv->keywords = g_hash_table_new_full (NULL, NULL, NULL, g_free);
+
+ priv->search_text_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ priv->search_image_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
priv->header_bar = g_object_new (GTK_TYPE_HEADER_BAR,
"show-close-button", TRUE,
"visible", TRUE,
@@ -609,7 +863,7 @@ gb_shortcuts_dialog_init (GbShortcutsDialog *self)
menu_box = g_object_new (GTK_TYPE_BOX,
"orientation", GTK_ORIENTATION_HORIZONTAL,
- "spacing", 3,
+ "spacing", 6,
"visible", TRUE,
NULL);
gtk_container_add (GTK_CONTAINER (priv->menu_button), GTK_WIDGET (menu_box));
@@ -660,10 +914,45 @@ gb_shortcuts_dialog_init (GbShortcutsDialog *self)
"placeholder-text", _("Search Shortcuts"),
"width-chars", 40,
NULL);
+ g_signal_connect_object (entry,
+ "changed",
+ G_CALLBACK (gb_shortcuts_dialog__entry__changed),
+ self,
+ G_CONNECT_SWAPPED);
g_signal_connect_object (priv->stack,
"notify::visible-child",
G_CALLBACK (gb_shortcuts_dialog__stack__notify_visible_child),
self,
G_CONNECT_SWAPPED);
+
+ scroller = g_object_new (GTK_TYPE_SCROLLED_WINDOW,
+ "visible", TRUE,
+ NULL);
+ box = g_object_new (GTK_TYPE_BOX,
+ "border-width", 24,
+ "halign", GTK_ALIGN_CENTER,
+ "spacing", 24,
+ "orientation", GTK_ORIENTATION_VERTICAL,
+ "visible", TRUE,
+ NULL);
+ gtk_container_add (GTK_CONTAINER (scroller), GTK_WIDGET (box));
+ gtk_stack_add_titled (priv->stack, GTK_WIDGET (scroller),
+ "internal-search", _("Search Results"));
+
+ priv->search_shortcuts = g_object_new (GTK_TYPE_BOX,
+ "halign", GTK_ALIGN_CENTER,
+ "spacing", 6,
+ "orientation", GTK_ORIENTATION_VERTICAL,
+ "visible", TRUE,
+ NULL);
+ gtk_container_add (GTK_CONTAINER (box), GTK_WIDGET (priv->search_shortcuts));
+
+ priv->search_gestures = g_object_new (GTK_TYPE_BOX,
+ "halign", GTK_ALIGN_CENTER,
+ "spacing", 6,
+ "orientation", GTK_ORIENTATION_VERTICAL,
+ "visible", TRUE,
+ NULL);
+ gtk_container_add (GTK_CONTAINER (box), GTK_WIDGET (priv->search_gestures));
}
diff --git a/src/shortcuts/gb-shortcuts-gesture.c b/src/shortcuts/gb-shortcuts-gesture.c
index d00c8c5..fbb752e 100644
--- a/src/shortcuts/gb-shortcuts-gesture.c
+++ b/src/shortcuts/gb-shortcuts-gesture.c
@@ -71,6 +71,29 @@ gb_shortcuts_gesture_set_icon_name (GbShortcutsGesture *self,
}
static void
+gb_shortcuts_gesture_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GbShortcutsGesture *self = GB_SHORTCUTS_GESTURE (object);
+
+ switch (prop_id)
+ {
+ case PROP_SUBTITLE:
+ g_value_set_string (value, gtk_label_get_label (self->subtitle));
+ break;
+
+ case PROP_TITLE:
+ g_value_set_string (value, gtk_label_get_label (self->title));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
gb_shortcuts_gesture_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -120,6 +143,7 @@ gb_shortcuts_gesture_class_init (GbShortcutsGestureClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->get_property = gb_shortcuts_gesture_get_property;
object_class->set_property = gb_shortcuts_gesture_set_property;
gParamSpecs [PROP_DESC_SIZE_GROUP] =
@@ -148,14 +172,14 @@ gb_shortcuts_gesture_class_init (GbShortcutsGestureClass *klass)
"Subtitle",
"Subtitle",
NULL,
- (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gParamSpecs [PROP_TITLE] =
g_param_spec_string ("title",
"Title",
"Title",
NULL,
- (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
}
diff --git a/src/shortcuts/gb-shortcuts-shortcut.c b/src/shortcuts/gb-shortcuts-shortcut.c
index a7a67a5..453553a 100644
--- a/src/shortcuts/gb-shortcuts-shortcut.c
+++ b/src/shortcuts/gb-shortcuts-shortcut.c
@@ -41,6 +41,29 @@ enum {
static GParamSpec *gParamSpecs [LAST_PROP];
static void
+gb_shortcuts_shortcut_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GbShortcutsShortcut *self = GB_SHORTCUTS_SHORTCUT (object);
+
+ switch (prop_id)
+ {
+ case PROP_TITLE:
+ g_value_set_string (value, gtk_label_get_label (self->title));
+ break;
+
+ case PROP_ACCELERATOR:
+ g_value_set_string (value, gb_accel_label_get_accelerator (self->accelerator));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
gb_shortcuts_shortcut_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -86,6 +109,7 @@ gb_shortcuts_shortcut_class_init (GbShortcutsShortcutClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->get_property = gb_shortcuts_shortcut_get_property;
object_class->set_property = gb_shortcuts_shortcut_set_property;
gParamSpecs [PROP_ACCELERATOR] =
@@ -93,7 +117,7 @@ gb_shortcuts_shortcut_class_init (GbShortcutsShortcutClass *klass)
"Accelerator",
"Accelerator",
NULL,
- (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gParamSpecs [PROP_ACCELERATOR_SIZE_GROUP] =
g_param_spec_object ("accelerator-size-group",
@@ -107,7 +131,7 @@ gb_shortcuts_shortcut_class_init (GbShortcutsShortcutClass *klass)
"Title",
"Title",
NULL,
- (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gParamSpecs [PROP_TITLE_SIZE_GROUP] =
g_param_spec_object ("title-size-group",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]