search-button: Port results to GtkListView
Port the search results list to GtkListview. Use bindings to set the title, icon, and subtitle of each row. Remove GcalSearchHitRow as it's unused now.
This commit is contained in:
+102
-45
@@ -24,7 +24,6 @@
|
||||
#include "gcal-debug.h"
|
||||
#include "gcal-search-button.h"
|
||||
#include "gcal-search-hit.h"
|
||||
#include "gcal-search-hit-row.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@@ -36,8 +35,9 @@ struct _GcalSearchButton
|
||||
|
||||
GtkEditable *entry;
|
||||
GtkWidget *popover;
|
||||
GtkListBox *results_listbox;
|
||||
GtkListView *results_listview;
|
||||
GtkRevealer *results_revealer;
|
||||
GtkSingleSelection *results_selection_model;
|
||||
GtkStack *stack;
|
||||
|
||||
GCancellable *cancellable;
|
||||
@@ -88,11 +88,14 @@ quit_search_entry (GcalSearchButton *self)
|
||||
gtk_editable_set_text (self->entry, "");
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_widget_func (gpointer item,
|
||||
gpointer user_data)
|
||||
static inline void
|
||||
scroll_to_result (GcalSearchButton *self,
|
||||
guint position)
|
||||
{
|
||||
return gcal_search_hit_row_new (item);
|
||||
gtk_widget_activate_action (GTK_WIDGET (self->results_listview),
|
||||
"list.scroll-to-item",
|
||||
"u",
|
||||
position);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -101,11 +104,7 @@ set_model (GcalSearchButton *self,
|
||||
{
|
||||
GCAL_ENTRY;
|
||||
|
||||
gtk_list_box_bind_model (self->results_listbox,
|
||||
model,
|
||||
create_widget_func,
|
||||
self,
|
||||
NULL);
|
||||
gtk_single_selection_set_model (self->results_selection_model, model);
|
||||
|
||||
if (model)
|
||||
show_suggestions (self);
|
||||
@@ -120,6 +119,18 @@ set_model (GcalSearchButton *self,
|
||||
* Callbacks
|
||||
*/
|
||||
|
||||
static gchar *
|
||||
escape_markup_cb (GcalSearchHit *hit,
|
||||
const gchar *string)
|
||||
{
|
||||
g_autofree gchar *escaped_string = NULL;
|
||||
|
||||
escaped_string = g_markup_escape_text (string, -1);
|
||||
escaped_string = g_strstrip (escaped_string);
|
||||
|
||||
return g_steal_pointer (&escaped_string);
|
||||
}
|
||||
|
||||
static void
|
||||
on_button_clicked_cb (GtkButton *button,
|
||||
GcalSearchButton *self)
|
||||
@@ -164,6 +175,68 @@ on_search_finished_cb (GObject *source_object,
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
static void
|
||||
on_entry_activate_cb (GtkSearchEntry *entry,
|
||||
GcalSearchButton *self)
|
||||
{
|
||||
GcalSearchHit *hit;
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
hit = gtk_single_selection_get_selected_item (self->results_selection_model);
|
||||
|
||||
if (hit)
|
||||
{
|
||||
GCAL_TRACE_MSG ("Activating \"%s\"", gcal_search_hit_get_title (hit));
|
||||
|
||||
gcal_search_hit_activate (hit, GTK_WIDGET (self));
|
||||
quit_search_entry (self);
|
||||
}
|
||||
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
static void
|
||||
on_entry_next_match_cb (GtkSearchEntry *entry,
|
||||
GcalSearchButton *self)
|
||||
{
|
||||
guint selected;
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
selected = gtk_single_selection_get_selected (self->results_selection_model);
|
||||
|
||||
if (selected != GTK_INVALID_LIST_POSITION &&
|
||||
selected + 1 < g_list_model_get_n_items (G_LIST_MODEL (self->results_selection_model)))
|
||||
{
|
||||
GCAL_TRACE_MSG ("Changing selection to %u", selected + 1);
|
||||
gtk_single_selection_set_selected (self->results_selection_model, selected + 1);
|
||||
scroll_to_result (self, selected + 1);
|
||||
}
|
||||
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
static void
|
||||
on_entry_previous_match_cb (GtkSearchEntry *entry,
|
||||
GcalSearchButton *self)
|
||||
{
|
||||
guint selected;
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
selected = gtk_single_selection_get_selected (self->results_selection_model);
|
||||
|
||||
if (selected > 0 && selected != GTK_INVALID_LIST_POSITION)
|
||||
{
|
||||
GCAL_TRACE_MSG ("Changing selection to %u", selected - 1);
|
||||
gtk_single_selection_set_selected (self->results_selection_model, selected - 1);
|
||||
scroll_to_result (self, selected - 1);
|
||||
}
|
||||
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
static void
|
||||
on_entry_search_changed_cb (GtkSearchEntry *entry,
|
||||
GcalSearchButton *self)
|
||||
@@ -204,16 +277,18 @@ on_entry_stop_search_cb (GtkSearchEntry *search_entry,
|
||||
}
|
||||
|
||||
static void
|
||||
on_results_listbox_row_activated_cb (GtkListBox *listbox,
|
||||
GcalSearchHitRow *row,
|
||||
GcalSearchButton *self)
|
||||
on_results_listview_activated_cb (GtkListBox *listbox,
|
||||
guint position,
|
||||
GcalSearchButton *self)
|
||||
{
|
||||
GcalSearchHit *search_hit;
|
||||
|
||||
search_hit = gcal_search_hit_row_get_search_hit (row);
|
||||
search_hit = g_list_model_get_item (G_LIST_MODEL (self->results_selection_model), position);
|
||||
g_assert (GCAL_IS_SEARCH_HIT (search_hit));
|
||||
|
||||
gcal_search_hit_activate (search_hit, GTK_WIDGET (self));
|
||||
|
||||
hide_suggestions (self);
|
||||
quit_search_entry (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -225,32 +300,11 @@ on_results_revealer_child_reveal_state_changed_cb (GtkRevealer *revealer,
|
||||
gtk_popover_popdown (GTK_POPOVER (self->popover));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GtkWidget overrides
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
gcal_search_button_focus (GtkWidget *widget,
|
||||
GtkDirectionType direction)
|
||||
string_is_not_empty_cb (GcalSearchHit *hit,
|
||||
const gchar *string)
|
||||
{
|
||||
GcalSearchButton *self = GCAL_SEARCH_BUTTON (widget);
|
||||
|
||||
if (!gtk_widget_get_visible (GTK_WIDGET (self->popover)))
|
||||
return gtk_widget_child_focus (GTK_WIDGET (self->stack), direction);
|
||||
|
||||
if (direction == GTK_DIR_DOWN)
|
||||
{
|
||||
GtkListBoxRow *first_row = gtk_list_box_get_row_at_index (self->results_listbox, 0);
|
||||
|
||||
if (!first_row)
|
||||
return gtk_widget_child_focus (GTK_WIDGET (self->stack), direction);
|
||||
|
||||
gtk_widget_grab_focus (GTK_WIDGET (first_row));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return gtk_widget_child_focus (GTK_WIDGET (self->stack), direction);
|
||||
return string != NULL && *string != '\0';
|
||||
}
|
||||
|
||||
|
||||
@@ -319,7 +373,6 @@ gcal_search_button_set_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gcal_search_button_class_init (GcalSearchButtonClass *klass)
|
||||
{
|
||||
@@ -331,8 +384,6 @@ gcal_search_button_class_init (GcalSearchButtonClass *klass)
|
||||
object_class->get_property = gcal_search_button_get_property;
|
||||
object_class->set_property = gcal_search_button_set_property;
|
||||
|
||||
widget_class->focus = gcal_search_button_focus;
|
||||
|
||||
/**
|
||||
* GcalSearchButton::context:
|
||||
*
|
||||
@@ -350,16 +401,22 @@ gcal_search_button_class_init (GcalSearchButtonClass *klass)
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, GcalSearchButton, entry);
|
||||
gtk_widget_class_bind_template_child (widget_class, GcalSearchButton, popover);
|
||||
gtk_widget_class_bind_template_child (widget_class, GcalSearchButton, results_listbox);
|
||||
gtk_widget_class_bind_template_child (widget_class, GcalSearchButton, results_listview);
|
||||
gtk_widget_class_bind_template_child (widget_class, GcalSearchButton, results_selection_model);
|
||||
gtk_widget_class_bind_template_child (widget_class, GcalSearchButton, results_revealer);
|
||||
gtk_widget_class_bind_template_child (widget_class, GcalSearchButton, stack);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, escape_markup_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_button_clicked_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_focus_controller_leave_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_entry_activate_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_entry_next_match_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_entry_previous_match_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_entry_search_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_entry_stop_search_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_results_listbox_row_activated_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_results_listview_activated_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_results_revealer_child_reveal_state_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, string_is_not_empty_cb);
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "searchbutton");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user