[recipes] Sort lists by name or recency
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [recipes] Sort lists by name or recency
- Date: Tue, 27 Jun 2017 03:13:09 +0000 (UTC)
commit 5f1ff5fa6eb7f9f592f6247275cef87cb54e4a81
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Jun 26 23:12:06 2017 -0400
Sort lists by name or recency
Following recent mockups, we now allow to sort lists by either
name or recency. We persist this as a setting.
data/org.gnome.Recipes.gschema.xml | 15 ++++++-
src/gr-list-page.c | 53 +++++++++++++++++++++--
src/gr-list-page.h | 5 ++
src/gr-search-page.c | 54 +++++++++++++++++++++--
src/gr-window.c | 65 +++++++++++++++++++++------
src/gr-window.ui | 84 ++++++++++++++++++++++++++++++++++-
6 files changed, 248 insertions(+), 28 deletions(-)
---
diff --git a/data/org.gnome.Recipes.gschema.xml b/data/org.gnome.Recipes.gschema.xml
index c822a6d..eafda34 100644
--- a/data/org.gnome.Recipes.gschema.xml
+++ b/data/org.gnome.Recipes.gschema.xml
@@ -7,6 +7,11 @@
<value nick="locale" value="2"/>
</enum>
+ <enum id="org.gnome.recipes.SortKey">
+ <value nick="name" value="0"/>
+ <value nick="recency" value="1"/>
+ </enum>
+
<schema path="/org/gnome/recipes/" id="org.gnome.Recipes" gettext-domain="gnome-recipes">
<key type="s" name="user">
@@ -68,8 +73,7 @@
The list of recipes to be exported. Each entry in the list is the ID of a recipe.
</description>
</key>
-
- <key name="temperature-unit" enum="org.gnome.recipes.TemperatureUnit">
+ <key name="temperature-unit" enum="org.gnome.recipes.TemperatureUnit">
<default>'locale'</default>
<summary>The setting for which unit temperatures should be displayed in. </summary>
<description>
@@ -77,6 +81,13 @@
which means to use the LC_MEASUREMENT category of the current locale to decide.
</description>
</key>
+ <key name="sort-key" enum="org.gnome.recipes.SortKey">
+ <default>'name'</default>
+ <summary>By which key to sort lists.</summary>
+ <description>
+ The setting determines which key is used to sort lists of recipes by.
+ </description>
+ </key>
</schema>
diff --git a/src/gr-list-page.c b/src/gr-list-page.c
index 69759cc..f59749c 100644
--- a/src/gr-list-page.c
+++ b/src/gr-list-page.c
@@ -32,6 +32,7 @@
#include "gr-category-tile.h"
#include "gr-image.h"
#include "gr-app.h"
+#include "gr-settings.h"
struct _GrListPage
{
@@ -191,9 +192,9 @@ search_finished (GrRecipeSearch *search,
}
static int
-sort_func (GtkFlowBoxChild *child1,
- GtkFlowBoxChild *child2,
- gpointer data)
+name_sort_func (GtkFlowBoxChild *child1,
+ GtkFlowBoxChild *child2,
+ gpointer data)
{
GtkWidget *tile1 = gtk_bin_get_child (GTK_BIN (child1));
GtkWidget *tile2 = gtk_bin_get_child (GTK_BIN (child2));
@@ -205,6 +206,49 @@ sort_func (GtkFlowBoxChild *child1,
return strcmp (name1, name2);
}
+static int
+date_sort_func (GtkFlowBoxChild *child1,
+ GtkFlowBoxChild *child2,
+ gpointer data)
+{
+ GtkWidget *tile1 = gtk_bin_get_child (GTK_BIN (child1));
+ GtkWidget *tile2 = gtk_bin_get_child (GTK_BIN (child2));
+ GrRecipe *recipe1 = gr_recipe_tile_get_recipe (GR_RECIPE_TILE (tile1));
+ GrRecipe *recipe2 = gr_recipe_tile_get_recipe (GR_RECIPE_TILE (tile2));
+ GDateTime *mtime1 = gr_recipe_get_mtime (recipe1);
+ GDateTime *mtime2 = gr_recipe_get_mtime (recipe2);
+
+ return g_date_time_compare (mtime2, mtime1);
+}
+
+static void
+gr_list_page_set_sort (GrListPage *page,
+ GrSortKey sort)
+{
+ switch (sort) {
+ case SORT_BY_NAME:
+ gtk_flow_box_set_sort_func (GTK_FLOW_BOX (page->flow_box), name_sort_func, page, NULL);
+ break;
+ case SORT_BY_RECENCY:
+ gtk_flow_box_set_sort_func (GTK_FLOW_BOX (page->flow_box), date_sort_func, page, NULL);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static void
+sort_key_changed (GrListPage *page)
+{
+ GrSortKey sort;
+
+ if (!gtk_widget_get_visible (GTK_WIDGET (page)))
+ return;
+
+ sort = g_settings_get_enum (gr_settings_get (), "sort-key");
+ gr_list_page_set_sort (page, sort);
+}
+
static void
gr_list_page_init (GrListPage *page)
{
@@ -218,7 +262,8 @@ gr_list_page_init (GrListPage *page)
g_signal_connect (page->search, "hits-removed", G_CALLBACK (search_hits_removed), page);
g_signal_connect (page->search, "finished", G_CALLBACK (search_finished), page);
- gtk_flow_box_set_sort_func (GTK_FLOW_BOX (page->flow_box), sort_func, page, NULL);
+ g_signal_connect_swapped (gr_settings_get (), "changed::sort-key", G_CALLBACK (sort_key_changed),
page);
+ g_signal_connect (page, "notify::visible", G_CALLBACK (sort_key_changed), NULL);
}
static void
diff --git a/src/gr-list-page.h b/src/gr-list-page.h
index 4c33c02..b696eb0 100644
--- a/src/gr-list-page.h
+++ b/src/gr-list-page.h
@@ -46,4 +46,9 @@ void gr_list_page_populate_from_new (GrListPage *self);
void gr_list_page_clear (GrListPage *self);
void gr_list_page_repopulate (GrListPage *self);
+typedef enum {
+ SORT_BY_NAME,
+ SORT_BY_RECENCY
+} GrSortKey;
+
G_END_DECLS
diff --git a/src/gr-search-page.c b/src/gr-search-page.c
index 6e1dcdc..4faeb45 100644
--- a/src/gr-search-page.c
+++ b/src/gr-search-page.c
@@ -28,6 +28,8 @@
#include "gr-recipe.h"
#include "gr-recipe-tile.h"
#include "gr-utils.h"
+#include "gr-list-page.h"
+#include "gr-settings.h"
struct _GrSearchPage
@@ -113,9 +115,9 @@ search_finished (GrRecipeSearch *search,
}
static int
-sort_func (GtkFlowBoxChild *child1,
- GtkFlowBoxChild *child2,
- gpointer data)
+name_sort_func (GtkFlowBoxChild *child1,
+ GtkFlowBoxChild *child2,
+ gpointer data)
{
GtkWidget *tile1 = gtk_bin_get_child (GTK_BIN (child1));
GtkWidget *tile2 = gtk_bin_get_child (GTK_BIN (child2));
@@ -127,6 +129,49 @@ sort_func (GtkFlowBoxChild *child1,
return strcmp (name1, name2);
}
+static int
+date_sort_func (GtkFlowBoxChild *child1,
+ GtkFlowBoxChild *child2,
+ gpointer data)
+{
+ GtkWidget *tile1 = gtk_bin_get_child (GTK_BIN (child1));
+ GtkWidget *tile2 = gtk_bin_get_child (GTK_BIN (child2));
+ GrRecipe *recipe1 = gr_recipe_tile_get_recipe (GR_RECIPE_TILE (tile1));
+ GrRecipe *recipe2 = gr_recipe_tile_get_recipe (GR_RECIPE_TILE (tile2));
+ GDateTime *mtime1 = gr_recipe_get_mtime (recipe1);
+ GDateTime *mtime2 = gr_recipe_get_mtime (recipe2);
+
+ return g_date_time_compare (mtime2, mtime1);
+}
+
+static void
+gr_search_page_set_sort (GrSearchPage *page,
+ GrSortKey sort)
+{
+ switch (sort) {
+ case SORT_BY_NAME:
+ gtk_flow_box_set_sort_func (GTK_FLOW_BOX (page->flow_box), name_sort_func, page, NULL);
+ break;
+ case SORT_BY_RECENCY:
+ gtk_flow_box_set_sort_func (GTK_FLOW_BOX (page->flow_box), date_sort_func, page, NULL);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static void
+sort_key_changed (GrSearchPage *page)
+{
+ GrSortKey sort;
+
+ if (!gtk_widget_get_visible (GTK_WIDGET (page)))
+ return;
+
+ sort = g_settings_get_enum (gr_settings_get (), "sort-key");
+ gr_search_page_set_sort (page, sort);
+}
+
static void
gr_search_page_init (GrSearchPage *page)
{
@@ -140,7 +185,8 @@ gr_search_page_init (GrSearchPage *page)
g_signal_connect (page->search, "hits-removed", G_CALLBACK (search_hits_removed), page);
g_signal_connect (page->search, "finished", G_CALLBACK (search_finished), page);
- gtk_flow_box_set_sort_func (GTK_FLOW_BOX (page->flow_box), sort_func, page, NULL);
+ g_signal_connect_swapped (gr_settings_get (), "changed::sort-key", G_CALLBACK (sort_key_changed),
page);
+ g_signal_connect (page, "notify::visible", G_CALLBACK (sort_key_changed), NULL);
}
static void
diff --git a/src/gr-window.c b/src/gr-window.c
index 6038dc6..6402b07 100644
--- a/src/gr-window.c
+++ b/src/gr-window.c
@@ -46,6 +46,7 @@
#include "gr-account.h"
#include "gr-utils.h"
#include "gr-appdata.h"
+#include "gr-settings.h"
struct _GrWindow
@@ -75,6 +76,11 @@ struct _GrWindow
GtkWidget *image_page;
GtkWidget *cooking_page;
+ GtkWidget *sort_by_label;
+ GtkWidget *sort_by_name_button;
+ GtkWidget *sort_by_recency_button;
+ GtkWidget *sort_popover;
+
GtkWidget *undo_revealer;
GtkWidget *undo_label;
GrRecipe *undo_recipe;
@@ -298,7 +304,7 @@ search_mode_changed (GrWindow *window)
static void
switch_to_search (GrWindow *window)
{
- configure_window (window, "", "main", "main", "search", "search");
+ configure_window (window, "", "main", "main", "list", "search");
}
void
@@ -541,17 +547,6 @@ window_delete_handler (GtkWidget *widget)
return FALSE;
}
-static void
-hide_or_show_header_end_stack (GObject *object,
- GParamSpec *pspec,
- GrWindow *window)
-{
- const char *visible;
-
- visible = gtk_stack_get_visible_child_name (GTK_STACK (window->header_end_stack));
- gtk_widget_set_visible (window->header_end_stack, strcmp (visible, "list") != 0);
-}
-
GrWindow *
gr_window_new (GrApp *app)
{
@@ -876,6 +871,37 @@ make_save_sensitive (GrEditPage *edit_page,
}
static void
+update_sort_menu (GrWindow *window)
+{
+ switch (g_settings_get_enum (gr_settings_get (), "sort-key")) {
+ case SORT_BY_NAME:
+ g_object_set (window->sort_by_name_button, "active", TRUE, NULL);
+ g_object_set (window->sort_by_recency_button, "active", FALSE, NULL);
+ g_object_set (window->sort_by_label, "label", _("Sorted by Name"), NULL);
+ break;
+ case SORT_BY_RECENCY:
+ g_object_set (window->sort_by_name_button, "active", FALSE, NULL);
+ g_object_set (window->sort_by_recency_button, "active", TRUE, NULL);
+ g_object_set (window->sort_by_label, "label", _("Sorted by Recency"), NULL);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static void
+sort_clicked (GtkWidget *button,
+ GrWindow *window)
+{
+ GSettings *settings = gr_settings_get ();
+
+ gtk_popover_popdown (GTK_POPOVER (window->sort_popover));
+ g_settings_set_enum (settings, "sort-key",
+ button == window->sort_by_name_button ? SORT_BY_NAME : SORT_BY_RECENCY);
+ update_sort_menu (window);
+}
+
+static void
gr_window_class_init (GrWindowClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -913,13 +939,16 @@ gr_window_class_init (GrWindowClass *klass)
gtk_widget_class_bind_template_child (widget_class, GrWindow, remind_label);
gtk_widget_class_bind_template_child (widget_class, GrWindow, shopping_added_revealer);
gtk_widget_class_bind_template_child (widget_class, GrWindow, shopping_done_revealer);
+ gtk_widget_class_bind_template_child (widget_class, GrWindow, sort_by_label);
+ gtk_widget_class_bind_template_child (widget_class, GrWindow, sort_by_name_button);
+ gtk_widget_class_bind_template_child (widget_class, GrWindow, sort_by_recency_button);
+ gtk_widget_class_bind_template_child (widget_class, GrWindow, sort_popover);
gtk_widget_class_bind_template_callback (widget_class, new_recipe);
gtk_widget_class_bind_template_callback (widget_class, go_back);
gtk_widget_class_bind_template_callback (widget_class, add_recipe);
gtk_widget_class_bind_template_callback (widget_class, visible_page_changed);
gtk_widget_class_bind_template_callback (widget_class, start_cooking);
- gtk_widget_class_bind_template_callback (widget_class, hide_or_show_header_end_stack);
gtk_widget_class_bind_template_callback (widget_class, search_changed);
gtk_widget_class_bind_template_callback (widget_class, stop_search);
gtk_widget_class_bind_template_callback (widget_class, search_mode_changed);
@@ -939,6 +968,7 @@ gr_window_class_init (GrWindowClass *klass)
gtk_widget_class_bind_template_callback (widget_class, close_shopping_done);
gtk_widget_class_bind_template_callback (widget_class, back_to_shopping);
gtk_widget_class_bind_template_callback (widget_class, make_save_sensitive);
+ gtk_widget_class_bind_template_callback (widget_class, sort_clicked);
}
static GtkClipboard *
@@ -995,13 +1025,18 @@ gr_window_init (GrWindow *self)
g_action_map_add_action_entries (G_ACTION_MAP (self),
entries, G_N_ELEMENTS (entries),
self);
+
+ update_sort_menu (self);
}
void
gr_window_go_back (GrWindow *window)
{
- if (g_queue_is_empty (window->back_entry_stack)) {
- configure_window (window, _("Recipes"), "main", "main", "search", "recipes");
+ if (gtk_search_bar_get_search_mode (GTK_SEARCH_BAR (window->search_bar))) {
+ gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (window->search_bar), FALSE);
+ }
+ else if (g_queue_is_empty (window->back_entry_stack)) {
+ configure_window (window, _("Recipes"), "main", "main", "main", "recipes");
}
else {
go_back (window);
diff --git a/src/gr-window.ui b/src/gr-window.ui
index 874a56b..0bac3f7 100644
--- a/src/gr-window.ui
+++ b/src/gr-window.ui
@@ -85,7 +85,6 @@
<object class="GtkStack" id="header_end_stack">
<property name="visible">1</property>
<property name="hhomogeneous">0</property>
- <signal name="notify::visible-child-name" handler="hide_or_show_header_end_stack"/>
<child>
<object class="GtkToggleButton" id="search_button">
<property name="visible">1</property>
@@ -106,7 +105,7 @@
</child>
</object>
<packing>
- <property name="name">search</property>
+ <property name="name">main</property>
</packing>
</child>
<child>
@@ -152,8 +151,61 @@
</packing>
</child>
<child>
- <object class="GtkEventBox">
+ <object class="GtkBox">
<property name="visible">1</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkMenuButton">
+ <property name="visible">1</property>
+ <property name="popover">sort_popover</property>
+ <style>
+ <class name="text-button"/>
+ </style>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">1</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">10</property>
+ <property name="halign">fill</property>
+ <child>
+ <object class="GtkLabel" id="sort_by_label">
+ <property name="visible">1</property>
+ <property name="label">Sorted by Name</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">1</property>
+ <property name="icon-name">pan-down-symbolic</property>
+ <property name="icon-size">1</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="search_button2">
+ <property name="visible">1</property>
+ <property name="active" bind-source="search_button" bind-property="active"
bind-flags="bidirectional"/>
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child internal-child="accessible">
+ <object class="AtkObject">
+ <property name="accessible-name" translatable="yes">Search</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">1</property>
+ <property name="icon-name">edit-find-symbolic</property>
+ <property name="icon-size">1</property>
+ </object>
+ </child>
+ </object>
+ </child>
</object>
<packing>
<property name="name">list</property>
@@ -505,4 +557,30 @@
</object>
</child>
</template>
+ <object class="GtkPopover" id="sort_popover">
+ <child>
+ <object class="GtkBox">
+ <property name="visible">1</property>
+ <property name="orientation">vertical</property>
+ <property name="margin">10</property>
+ <child>
+ <object class="GtkModelButton" id="sort_by_name_button">
+ <property name="visible">1</property>
+ <property name="role">radio</property>
+ <property name="active">1</property>
+ <property name="text" translatable="yes">Name</property>
+ <signal name="clicked" handler="sort_clicked"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkModelButton" id="sort_by_recency_button">
+ <property name="visible">1</property>
+ <property name="role">radio</property>
+ <property name="text" translatable="yes">Recency</property>
+ <signal name="clicked" handler="sort_clicked"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
</interface>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]