[gnome-builder/wip/chergert/perspective] search: implement up/down for omni search result display
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/perspective] search: implement up/down for omni search result display
- Date: Thu, 10 Dec 2015 23:27:42 +0000 (UTC)
commit abb7b0b11732fba5429c35dd2f304d2c1fa65181
Author: Christian Hergert <chergert redhat com>
Date: Thu Dec 10 13:01:45 2015 -0800
search: implement up/down for omni search result display
data/theme/shared.css | 7 ++
libide/search/ide-omni-search-display.c | 77 ++++++++++++++++++++
libide/search/ide-omni-search-display.h | 10 ++-
libide/search/ide-omni-search-entry.c | 34 +++++++++
libide/search/ide-omni-search-group.c | 120 +++++++++++++++++++++++++++++++
libide/search/ide-omni-search-group.h | 3 +
6 files changed, 247 insertions(+), 4 deletions(-)
---
diff --git a/data/theme/shared.css b/data/theme/shared.css
index af84c94..0587b1f 100644
--- a/data/theme/shared.css
+++ b/data/theme/shared.css
@@ -124,12 +124,19 @@ workbench IdePreferencesBin entry {
omnisearchrow {
+ background-image: none;
+ background-color: transparent;
padding-top: 9px;
padding-left: 12px;
padding-right: 12px;
padding-bottom: 9px;
}
+omnisearchrow:selected {
+ background-color: @theme_selected_bg_color;
+ color: @theme_selected_fg_color;
+}
+
greeter frame {
border: 1px solid alpha(@borders, 0.4);
diff --git a/libide/search/ide-omni-search-display.c b/libide/search/ide-omni-search-display.c
index 5f72fab..52b96c5 100644
--- a/libide/search/ide-omni-search-display.c
+++ b/libide/search/ide-omni-search-display.c
@@ -135,6 +135,83 @@ ide_omni_search_display_result_selected (IdeOmniSearchDisplay *self,
}
}
+void
+ide_omni_search_display_move_next_result (IdeOmniSearchDisplay *self)
+{
+ gint i;
+
+ g_return_if_fail (IDE_IS_OMNI_SEARCH_DISPLAY (self));
+
+ for (i = 0; i < self->providers->len; i++)
+ {
+ ProviderEntry *ptr = g_ptr_array_index (self->providers, i);
+
+ if (ide_omni_search_group_has_selection (ptr->group))
+ {
+ while (ptr && !ide_omni_search_group_move_next (ptr->group))
+ {
+ ide_omni_search_group_unselect (ptr->group);
+
+ if (i < (self->providers->len - 1))
+ ptr = g_ptr_array_index (self->providers, ++i);
+ else
+ ptr = NULL;
+ }
+
+ if (ptr == NULL)
+ break;
+
+ return;
+ }
+ }
+
+ for (i = 0; i < self->providers->len; i++)
+ {
+ ProviderEntry *ptr = g_ptr_array_index (self->providers, i);
+
+ if (ide_omni_search_group_move_next (ptr->group))
+ break;
+ }
+}
+
+void
+ide_omni_search_display_move_previous_result (IdeOmniSearchDisplay *self)
+{
+ gint i;
+
+ g_return_if_fail (IDE_IS_OMNI_SEARCH_DISPLAY (self));
+
+ for (i = self->providers->len - 1; i >= 0; i--)
+ {
+ ProviderEntry *ptr = g_ptr_array_index (self->providers, i);
+
+ if (ide_omni_search_group_has_selection (ptr->group))
+ {
+ while (ptr && !ide_omni_search_group_move_previous (ptr->group))
+ {
+ ide_omni_search_group_unselect (ptr->group);
+ if (i > 0)
+ ptr = g_ptr_array_index (self->providers, --i);
+ else
+ ptr = NULL;
+ }
+
+ if (ptr == NULL)
+ break;
+
+ return;
+ }
+ }
+
+ for (i = self->providers->len - 1; i >= 0; i--)
+ {
+ ProviderEntry *ptr = g_ptr_array_index (self->providers, i);
+
+ if (ide_omni_search_group_move_previous (ptr->group))
+ return;
+ }
+}
+
static gboolean
ide_omni_search_display_keynav_failed (IdeOmniSearchDisplay *self,
GtkDirectionType dir,
diff --git a/libide/search/ide-omni-search-display.h b/libide/search/ide-omni-search-display.h
index cf9a56c..be20f55 100644
--- a/libide/search/ide-omni-search-display.h
+++ b/libide/search/ide-omni-search-display.h
@@ -29,10 +29,12 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (IdeOmniSearchDisplay, ide_omni_search_display, IDE, OMNI_SEARCH_DISPLAY, GtkBin)
-IdeSearchContext *ide_omni_search_display_get_context (IdeOmniSearchDisplay *display);
-void ide_omni_search_display_set_context (IdeOmniSearchDisplay *display,
- IdeSearchContext *context);
-guint64 ide_omni_search_display_get_count (IdeOmniSearchDisplay *display);
+IdeSearchContext *ide_omni_search_display_get_context (IdeOmniSearchDisplay *self);
+void ide_omni_search_display_set_context (IdeOmniSearchDisplay *self,
+ IdeSearchContext *context);
+guint64 ide_omni_search_display_get_count (IdeOmniSearchDisplay *self);
+void ide_omni_search_display_move_next_result (IdeOmniSearchDisplay *self);
+void ide_omni_search_display_move_previous_result (IdeOmniSearchDisplay *self);
G_END_DECLS
diff --git a/libide/search/ide-omni-search-entry.c b/libide/search/ide-omni-search-entry.c
index 1e9e8d8..23e15c5 100644
--- a/libide/search/ide-omni-search-entry.c
+++ b/libide/search/ide-omni-search-entry.c
@@ -45,6 +45,8 @@ G_DEFINE_TYPE (IdeOmniSearchEntry, ide_omni_search_entry, GTK_TYPE_ENTRY)
enum {
CLEAR_SEARCH,
+ MOVE_NEXT_RESULT,
+ MOVE_PREVIOUS_RESULT,
LAST_SIGNAL
};
@@ -234,6 +236,22 @@ ide_omni_search_entry_popover_key_press_event (IdeOmniSearchEntry *self,
}
static void
+ide_omni_search_entry_move_next_result (IdeOmniSearchEntry *self)
+{
+ g_assert (IDE_IS_OMNI_SEARCH_ENTRY (self));
+
+ ide_omni_search_display_move_next_result (self->display);
+}
+
+static void
+ide_omni_search_entry_move_previous_result (IdeOmniSearchEntry *self)
+{
+ g_assert (IDE_IS_OMNI_SEARCH_ENTRY (self));
+
+ ide_omni_search_display_move_previous_result (self->display);
+}
+
+static void
ide_omni_search_entry_destroy (GtkWidget *widget)
{
IdeOmniSearchEntry *self = (IdeOmniSearchEntry *)widget;
@@ -263,10 +281,26 @@ ide_omni_search_entry_class_init (IdeOmniSearchEntryClass *klass)
G_CALLBACK (ide_omni_search_entry_clear_search),
NULL, NULL, NULL, G_TYPE_NONE, 0);
+ signals [MOVE_NEXT_RESULT] =
+ g_signal_new_class_handler ("move-next-result",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_CALLBACK (ide_omni_search_entry_move_next_result),
+ NULL, NULL, NULL, G_TYPE_NONE, 0);
+
+ signals [MOVE_PREVIOUS_RESULT] =
+ g_signal_new_class_handler ("move-previous-result",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_CALLBACK (ide_omni_search_entry_move_previous_result),
+ NULL, NULL, NULL, G_TYPE_NONE, 0);
+
binding_set = gtk_binding_set_by_class (klass);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_Escape, 0, "clear-search", 0);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0, "activate", 0);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0, "activate", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_Down, 0, "move-next-result", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_Up, 0, "move-previous-result", 0);
}
static void
diff --git a/libide/search/ide-omni-search-group.c b/libide/search/ide-omni-search-group.c
index 1bb5f6a..e9a8e19 100644
--- a/libide/search/ide-omni-search-group.c
+++ b/libide/search/ide-omni-search-group.c
@@ -455,3 +455,123 @@ ide_omni_search_group_get_count (IdeOmniSearchGroup *self)
return self->count;
}
+
+static void
+find_nth_row_cb (GtkWidget *widget,
+ gpointer user_data)
+{
+ struct {
+ GtkListBox *list;
+ GtkListBoxRow *row;
+ gint nth;
+ gint last_n;
+ } *lookup = user_data;
+ gint position;
+
+ /*
+ * This tries to find a matching index, but also handles the special case of
+ * -1, where we are trying to find the last row by position. This would not
+ * be very efficient if the lists were long, but currently the lists are
+ * all < 10 items.
+ */
+
+ if ((lookup->row != NULL) && (lookup->nth != -1))
+ return;
+
+ position = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (widget));
+
+ if (position == lookup->nth)
+ lookup->row = GTK_LIST_BOX_ROW (widget);
+ else if ((lookup->nth == -1) && (position > lookup->last_n))
+ {
+ lookup->row = GTK_LIST_BOX_ROW (widget);
+ lookup->last_n = position;
+ }
+}
+
+static GtkListBoxRow *
+find_nth_row (GtkListBox *list,
+ gint nth)
+{
+ struct {
+ GtkListBox *list;
+ GtkListBoxRow *row;
+ gint nth;
+ gint last_n;
+ } lookup = { list, NULL, nth, -1 };
+
+ g_assert (GTK_IS_LIST_BOX (list));
+ g_assert (nth >= -1);
+
+ gtk_container_foreach (GTK_CONTAINER (list), find_nth_row_cb, &lookup);
+
+ return lookup.row;
+}
+
+gboolean
+ide_omni_search_group_move_next (IdeOmniSearchGroup *self)
+{
+ GtkListBoxRow *row;
+
+ g_return_val_if_fail (IDE_IS_OMNI_SEARCH_GROUP (self), FALSE);
+
+ row = gtk_list_box_get_selected_row (self->rows);
+
+ if (row != NULL)
+ {
+ gint position;
+
+ position = gtk_list_box_row_get_index (row);
+ row = find_nth_row (self->rows, position + 1);
+ }
+ else
+ row = find_nth_row (self->rows, 0);
+
+ if (row != NULL)
+ {
+ gtk_list_box_select_row (self->rows, row);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+gboolean
+ide_omni_search_group_move_previous (IdeOmniSearchGroup *self)
+{
+ GtkListBoxRow *row;
+
+ g_return_val_if_fail (IDE_IS_OMNI_SEARCH_GROUP (self), FALSE);
+
+ row = gtk_list_box_get_selected_row (self->rows);
+
+ if (row != NULL)
+ {
+ gint position;
+
+ position = gtk_list_box_row_get_index (row);
+
+ if (position == 0)
+ return FALSE;
+
+ row = find_nth_row (self->rows, position - 1);
+ }
+ else
+ row = find_nth_row (self->rows, -1);
+
+ if (row != NULL)
+ {
+ gtk_list_box_select_row (self->rows, row);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+gboolean
+ide_omni_search_group_has_selection (IdeOmniSearchGroup *self)
+{
+ g_return_val_if_fail (IDE_IS_OMNI_SEARCH_GROUP (self), FALSE);
+
+ return !!gtk_list_box_get_selected_row (self->rows);
+}
diff --git a/libide/search/ide-omni-search-group.h b/libide/search/ide-omni-search-group.h
index f58d1ec..730c002 100644
--- a/libide/search/ide-omni-search-group.h
+++ b/libide/search/ide-omni-search-group.h
@@ -40,6 +40,9 @@ void ide_omni_search_group_focus_last (IdeOmniSearchGroup *grou
IdeSearchResult *ide_omni_search_group_get_first (IdeOmniSearchGroup *group);
gboolean ide_omni_search_group_activate (IdeOmniSearchGroup *group);
guint64 ide_omni_search_group_get_count (IdeOmniSearchGroup *self);
+gboolean ide_omni_search_group_has_selection (IdeOmniSearchGroup *self);
+gboolean ide_omni_search_group_move_next (IdeOmniSearchGroup *self);
+gboolean ide_omni_search_group_move_previous (IdeOmniSearchGroup *self);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]