[recipes] edit: Use GrIngredientsViewer



commit dc916738f70e6b4ce2ce8cad88412432b42db667
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Apr 27 21:27:13 2017 -0400

    edit: Use GrIngredientsViewer
    
    Use the new widget, in editable mode.

 src/gr-edit-page.c  |  987 ++++-----------------------------------------------
 src/gr-edit-page.ui |  200 +----------
 2 files changed, 75 insertions(+), 1112 deletions(-)
---
diff --git a/src/gr-edit-page.c b/src/gr-edit-page.c
index ac67075..1e601fe 100644
--- a/src/gr-edit-page.c
+++ b/src/gr-edit-page.c
@@ -50,6 +50,7 @@
 #include "gr-account.h"
 #include "gr-recipe-tile.h"
 #include "gr-recipe-formatter.h"
+#include "gr-ingredients-viewer.h"
 
 
 struct _GrEditPage
@@ -84,24 +85,10 @@ struct _GrEditPage
         GtkWidget *default_image_image;
         GtkWidget *rotate_image_right_button;
         GtkWidget *rotate_image_left_button;
-        GtkWidget *ingredient_popover;
-        GtkWidget *new_ingredient_name;
-        GtkWidget *new_ingredient_amount;
-        GtkWidget *new_ingredient_unit;
-        GtkWidget *new_ingredient_add_button;
         GtkWidget *author_label;
         GtkWidget *ingredients_box;
         GtkWidget *cooking_view;
 
-        GtkWidget *ing_list;
-        GtkWidget *ing_search_button;
-        GtkWidget *ing_search_button_label;
-        GtkWidget *ing_search_revealer;
-
-        GtkWidget *unit_list;
-        GtkWidget *amount_search_button;
-        GtkWidget *amount_search_button_label;
-        GtkWidget *amount_search_revealer;
         GtkWidget *recipe_popover;
         GtkWidget *recipe_list;
         GtkWidget *recipe_filter_entry;
@@ -163,7 +150,8 @@ dismiss_error (GrEditPage *page)
 }
 
 static void add_image_cb (GrEditPage *page);
-static void set_unsaved (GrEditPage *page);
+static void set_unsaved  (GrEditPage *page);
+static void add_list     (GrEditPage *page);
 
 static void
 populate_image_flowbox (GrEditPage *page)
@@ -429,675 +417,27 @@ populate_season_combo (GrEditPage *page)
         }
 }
 
-static void
-ingredient_changed (GrEditPage *page)
-{
-        const char *text;
-
-        text = gtk_entry_get_text (GTK_ENTRY (page->new_ingredient_name));
-        gtk_widget_set_sensitive (page->new_ingredient_add_button, strlen (text) > 0);
-}
-
-static void hide_ingredients_search_list (GrEditPage *self,
-                                          gboolean    animate);
-
-static void hide_units_search_list (GrEditPage *self,
-                                    gboolean    animate);
-
-static void
-add_ingredient (GtkButton *button, GrEditPage *page)
-{
-        gtk_entry_set_text (GTK_ENTRY (page->new_ingredient_name), "");
-        gtk_entry_set_text (GTK_ENTRY (page->new_ingredient_amount), "1");
-        gtk_entry_set_text (GTK_ENTRY (page->new_ingredient_unit), "");
-        gtk_label_set_label (GTK_LABEL (page->ing_search_button_label), _("Ingredient"));
-        gtk_label_set_label (GTK_LABEL (page->amount_search_button_label), _("Amount"));
-
-        gtk_popover_set_relative_to (GTK_POPOVER (page->ingredient_popover), GTK_WIDGET (button));
-        gtk_button_set_label (GTK_BUTTON (page->new_ingredient_add_button), _("Add"));
-        ingredient_changed (page);
-
-        hide_ingredients_search_list (page, FALSE);
-        hide_units_search_list (page, FALSE);
-
-        gtk_popover_popup (GTK_POPOVER (page->ingredient_popover));
-}
-
-static void
-remove_ingredient (GtkButton *button, GrEditPage *page)
-{
-        GtkWidget *row;
-
-        row = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_LIST_BOX_ROW);
-        if (!row)
-                return;
-
-        if (row == page->active_row)
-                page->active_row = NULL;
-
-        gtk_widget_destroy (row);
-        set_unsaved (page);
-}
-
-static void
-edit_ingredients_row (GtkListBoxRow *row,
-                      GrEditPage    *page)
-{
-        const char *amount;
-        const char *unit;
-        const char *ingredient;
-        char *tmp;
-
-        amount = (const char *)g_object_get_data (G_OBJECT (row), "amount");
-        unit = (const char *)g_object_get_data (G_OBJECT (row), "unit");
-        ingredient = (const char *)g_object_get_data (G_OBJECT (row), "ingredient");
-
-        gtk_entry_set_text (GTK_ENTRY (page->new_ingredient_name), ingredient);
-        gtk_entry_set_text (GTK_ENTRY (page->new_ingredient_amount), amount);
-        gtk_entry_set_text (GTK_ENTRY (page->new_ingredient_unit), unit);
-        gtk_label_set_label (GTK_LABEL (page->ing_search_button_label), ingredient);
-        tmp = g_strconcat (amount, " ", unit, NULL);
-        gtk_label_set_label (GTK_LABEL (page->amount_search_button_label), tmp);
-        g_free (tmp);
-
-        gtk_popover_set_relative_to (GTK_POPOVER (page->ingredient_popover), GTK_WIDGET (row));
-        gtk_button_set_label (GTK_BUTTON (page->new_ingredient_add_button), _("Apply"));
-        ingredient_changed (page);
-
-        hide_ingredients_search_list (page, FALSE);
-        hide_units_search_list (page, FALSE);
-
-        gtk_popover_popup (GTK_POPOVER (page->ingredient_popover));
-}
-
-static void
-edit_ingredient (GtkButton *button, GrEditPage *page)
-{
-        GtkWidget *row;
-
-        row = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_LIST_BOX_ROW);
-        if (!row)
-                return;
-
-        edit_ingredients_row (GTK_LIST_BOX_ROW (row), page);
-}
-
-static void selected_rows_changed (GtkListBox *list,
-                                   GrEditPage *page);
-
-static void
-set_active_row (GrEditPage *page,
-                GtkWidget *row)
-{
-        GtkWidget *stack;
-        GtkWidget *list;
-        GtkWidget *active_list;
-
-        if (page->active_row) {
-                stack = g_object_get_data (G_OBJECT (page->active_row), "buttons-stack");
-                gtk_stack_set_visible_child_name (GTK_STACK (stack), "empty");
-
-                list = row ? gtk_widget_get_parent (row) : NULL;
-                active_list = gtk_widget_get_parent (page->active_row);
-                if (list != active_list) {
-                        g_signal_handlers_block_by_func (active_list, selected_rows_changed, page);
-                        gtk_list_box_unselect_row (GTK_LIST_BOX (active_list), GTK_LIST_BOX_ROW 
(page->active_row));
-                        g_signal_handlers_unblock_by_func (active_list, selected_rows_changed, page);
-                }
-        }
-
-        if (page->active_row == row) {
-                page->active_row = NULL;
-                return;
-        }
-
-        page->active_row = row;
-
-        if (page->active_row) {
-                stack = g_object_get_data (G_OBJECT (page->active_row), "buttons-stack");
-                gtk_stack_set_visible_child_name (GTK_STACK (stack), "buttons");
-        }
-}
-
-static void
-selected_rows_changed (GtkListBox *list,
-                       GrEditPage *page)
-{
-        GtkListBoxRow *row;
-
-        row = gtk_list_box_get_selected_row (list);
-        set_active_row (page, GTK_WIDGET (row));
-}
-
-static void
-update_ingredient_row (GtkWidget  *row,
-                       const char *amount,
-                       const char *unit,
-                       const char *ingredient)
-{
-        GtkWidget *label;
-        char *tmp;
-
-        label = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "unit-label"));
-        tmp = g_strconcat (amount, " ", unit, NULL);
-        gtk_label_set_label (GTK_LABEL (label), tmp);
-        g_free (tmp);
-
-        label = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "ingredient-label"));
-        gtk_label_set_label (GTK_LABEL (label), ingredient);
-
-        g_object_set_data_full (G_OBJECT (row), "amount", g_strdup (amount), g_free);
-        g_object_set_data_full (G_OBJECT (row), "unit", g_strdup (unit), g_free);
-        g_object_set_data_full (G_OBJECT (row), "ingredient", g_strdup (ingredient), g_free);
-}
-
-static void
-up_ingredient (GtkButton  *button,
-               GrEditPage *page)
-{
-        GtkWidget *list;
-        GtkWidget *row;
-        gint selected_index;
-
-        row = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_LIST_BOX_ROW);
-        if (!row)
-                return;
-
-        list = gtk_widget_get_parent (row);
-
-        if (row == page->active_row) {
-                page->active_row = NULL;
-                selected_index = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (row));
-                g_object_ref (row);
-                gtk_container_remove (GTK_CONTAINER (list), GTK_WIDGET (row));
-                gtk_list_box_insert (GTK_LIST_BOX (list), GTK_WIDGET (row), selected_index - 1);
-                g_object_unref (row);
-                gtk_list_box_unselect_all (GTK_LIST_BOX (list));
-                gtk_list_box_select_row (GTK_LIST_BOX (list), GTK_LIST_BOX_ROW (row));
-        }
-
-        set_unsaved (page);
-}
-
-static void
-down_ingredient (GtkButton  *button,
-                 GrEditPage *page)
-{
-        GtkWidget *list;
-        GtkWidget *row;
-        gint selected_index;
-
-        row = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_LIST_BOX_ROW);
-        if (!row)
-                return;
-
-        list = gtk_widget_get_parent (row);
-
-        if (row == page->active_row) {
-                page->active_row = NULL;
-                selected_index = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (row));
-                g_object_ref (row);
-                gtk_container_remove (GTK_CONTAINER (list), GTK_WIDGET (row));
-                gtk_list_box_insert (GTK_LIST_BOX (list), GTK_WIDGET (row), selected_index + 1);
-                g_object_unref (row);
-                gtk_list_box_unselect_all (GTK_LIST_BOX (list));
-                gtk_list_box_select_row (GTK_LIST_BOX (list), GTK_LIST_BOX_ROW (row));
-        }
-
-        set_unsaved (page);
-}
-
-static GtkWidget *
-add_ingredient_row (GrEditPage   *page,
-                    GtkWidget    *list,
-                    GtkSizeGroup *group)
-{
-        GtkWidget *box;
-        GtkWidget *unit_label;
-        GtkWidget *ingredient_label;
-        GtkWidget *row;
-        GtkWidget *stack;
-        GtkWidget *buttons;
-        GtkWidget *button;
-        GtkWidget *image;
-
-        box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-        gtk_widget_show (box);
-
-        unit_label = gtk_label_new ("");
-        g_object_set (unit_label,
-                      "visible", TRUE,
-                      "xalign", 0.0,
-                      "margin", 10,
-                      NULL);
-        gtk_style_context_add_class (gtk_widget_get_style_context (unit_label), "dim-label");
-        gtk_container_add (GTK_CONTAINER (box), unit_label);
-        gtk_size_group_add_widget (group, unit_label);
-
-        ingredient_label = gtk_label_new ("");
-        g_object_set (ingredient_label,
-                      "visible", TRUE,
-                      "xalign", 0.0,
-                      "margin", 10,
-                      NULL);
-        gtk_container_add (GTK_CONTAINER (box), ingredient_label);
-
-        stack = gtk_stack_new ();
-        gtk_widget_set_halign (stack, GTK_ALIGN_END);
-        gtk_stack_set_transition_type (GTK_STACK (stack), GTK_STACK_TRANSITION_TYPE_NONE);
-        gtk_widget_show (stack);
-        image = gtk_image_new ();
-        gtk_widget_show (image);
-        gtk_widget_set_opacity (image, 0);
-        gtk_stack_add_named (GTK_STACK (stack), image, "empty");
-        buttons = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-        g_object_set (buttons, "margin", 4, NULL);
-        button = gtk_button_new ();
-        gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
-        g_signal_connect (button, "clicked", G_CALLBACK (up_ingredient), page);
-        image = gtk_image_new_from_icon_name ("go-up-symbolic", 1);
-        gtk_container_add (GTK_CONTAINER (button), image);
-        gtk_style_context_add_class (gtk_widget_get_style_context (button), "image-button");
-        gtk_style_context_add_class (gtk_widget_get_style_context (button), "circular");
-        gtk_container_add (GTK_CONTAINER (buttons), button);
-        button = gtk_button_new ();
-        gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
-        g_signal_connect (button, "clicked", G_CALLBACK (down_ingredient), page);
-        image = gtk_image_new_from_icon_name ("go-down-symbolic", 1);
-        gtk_container_add (GTK_CONTAINER (button), image);
-        gtk_style_context_add_class (gtk_widget_get_style_context (button), "image-button");
-        gtk_style_context_add_class (gtk_widget_get_style_context (button), "circular");
-        gtk_container_add (GTK_CONTAINER (buttons), button);
-        button = gtk_button_new ();
-        gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
-        g_signal_connect (button, "clicked", G_CALLBACK (edit_ingredient), page);
-        image = gtk_image_new_from_icon_name ("document-edit-symbolic", 1);
-        gtk_container_add (GTK_CONTAINER (button), image);
-        gtk_style_context_add_class (gtk_widget_get_style_context (button), "image-button");
-        gtk_style_context_add_class (gtk_widget_get_style_context (button), "circular");
-        gtk_container_add (GTK_CONTAINER (buttons), button);
-        button = gtk_button_new ();
-        gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
-        g_signal_connect (button, "clicked", G_CALLBACK (remove_ingredient), page);
-        image = gtk_image_new_from_icon_name ("user-trash-symbolic", 1);
-        gtk_container_add (GTK_CONTAINER (button), image);
-        gtk_style_context_add_class (gtk_widget_get_style_context (button), "image-button");
-        gtk_style_context_add_class (gtk_widget_get_style_context (button), "circular");
-        gtk_container_add (GTK_CONTAINER (buttons), button);
-        gtk_widget_show_all (buttons);
-        gtk_stack_add_named (GTK_STACK (stack), buttons, "buttons");
-        gtk_box_pack_end (GTK_BOX (box), stack, TRUE, TRUE, 0);
-
-        gtk_container_add (GTK_CONTAINER (list), box);
-        row = gtk_widget_get_parent (box);
-        g_object_set_data (G_OBJECT (row), "unit-label", unit_label);
-        g_object_set_data (G_OBJECT (row), "ingredient-label", ingredient_label);
-        g_object_set_data (G_OBJECT (row), "buttons-stack", stack);
-
-        gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), TRUE);
-
-        return row;
-}
-
-static void
-format_unit_for_display (const char *amount,
-                         const char *unit,
-                         char **amount_out,
-                         char **unit_out)
-{
-        if (amount[0] != '\0') {
-                GrNumber number;
-                char *a = (char *)amount;
-                if (gr_number_parse (&number, &a, NULL))
-                       *amount_out = gr_number_format (&number);
-                else
-                       *amount_out = g_strdup (amount);
-        }
-        else
-                *amount_out = g_strdup (amount);
-
-        if (unit[0] != '\0') {
-                const char *name;
-                char *u = (char *)unit;
-                name = gr_unit_parse (&u, NULL);
-                if (name)
-                        *unit_out = g_strdup (gr_unit_get_abbreviation (name));
-                else
-                        *unit_out = g_strdup (unit);
-        }
-        else
-                *unit_out = g_strdup (unit);
-}
-
-static void
-add_ingredient2 (GtkButton *button, GrEditPage *page)
-{
-        const char *ingredient;
-        g_autofree char *amount = NULL;
-        g_autofree  char *unit = NULL;
-        GtkWidget *list;
-        GtkWidget *b;
-        GtkWidget *row;
-
-        gtk_popover_popdown (GTK_POPOVER (page->ingredient_popover));
-
-        b = gtk_popover_get_relative_to (GTK_POPOVER (page->ingredient_popover));
-        if (GTK_IS_LIST_BOX_ROW (b)) {
-             row = b;
-        }
-        else {
-                list = GTK_WIDGET (g_object_get_data (G_OBJECT (b), "list"));
-                row = add_ingredient_row (page, list, page->group);
-        }
-
-        ingredient = gtk_entry_get_text (GTK_ENTRY (page->new_ingredient_name));
-        format_unit_for_display (gtk_entry_get_text (GTK_ENTRY (page->new_ingredient_amount)),
-                                 gtk_entry_get_text (GTK_ENTRY (page->new_ingredient_unit)),
-                                 &amount, &unit);
-        update_ingredient_row (row, amount, unit, ingredient);
-        set_unsaved (page);
-}
-
 static char *
 collect_ingredients (GrEditPage *page)
 {
         GString *s;
-        GtkWidget *segment;
-        GtkWidget *list;
-        GtkWidget *entry;
-        GList *children, *l, *k;
+        GList *children, *l;
 
         s = g_string_new ("");
-        for (k = page->segments; k; k = k->next) {
-                segment = k->data;
-                list = GTK_WIDGET (g_object_get_data (G_OBJECT (segment), "list"));
-                entry = GTK_WIDGET (g_object_get_data (G_OBJECT (segment), "entry"));
-                children = gtk_container_get_children (GTK_CONTAINER (list));
-                for (l = children; l; l = l->next) {
-                        GtkWidget *row = l->data;
-                        const char *amount;
-                        const char *unit;
-                        const char *ingredient;
-                        const char *id;
-
-                        amount = (const char *)g_object_get_data (G_OBJECT (row), "amount");
-                        unit = (const char *)g_object_get_data (G_OBJECT (row), "unit");
-                        ingredient = (const char *)g_object_get_data (G_OBJECT (row), "ingredient");
-                        id = gr_ingredient_get_id (ingredient);
-                        if (s->len > 0)
-                                g_string_append (s, "\n");
-                        g_string_append (s, amount);
-                        g_string_append (s, "\t");
-                        g_string_append (s, unit);
-                        g_string_append (s, "\t");
-                        g_string_append (s, id ? id : ingredient);
-                        g_string_append (s, "\t");
-                        g_string_append (s, gtk_entry_get_text (GTK_ENTRY (entry)));
-                }
-                g_list_free (children);
-        }
-
-        return g_string_free (s, FALSE);
-}
-
-static void
-show_ingredients_search_list (GrEditPage *self)
-{
-        gtk_widget_hide (self->ing_search_button);
-        gtk_widget_show (self->ing_search_revealer);
-        gtk_revealer_set_reveal_child (GTK_REVEALER (self->ing_search_revealer), TRUE);
-}
-
-static void
-hide_ingredients_search_list (GrEditPage *self,
-                              gboolean    animate)
-{
-        gtk_widget_show (self->ing_search_button);
-        if (!animate)
-                gtk_revealer_set_transition_type (GTK_REVEALER (self->ing_search_revealer),
-                                                  GTK_REVEALER_TRANSITION_TYPE_NONE);
-        gtk_revealer_set_reveal_child (GTK_REVEALER (self->ing_search_revealer), FALSE);
-        if (!animate)
-                gtk_revealer_set_transition_type (GTK_REVEALER (self->ing_search_revealer),
-                                                  GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN);
-}
-
-static void
-ing_search_button_clicked (GtkButton  *button,
-                           GrEditPage *self)
-{
-        hide_units_search_list (self, TRUE);
-        show_ingredients_search_list (self);
-}
-
-static void
-ing_row_activated (GtkListBox    *list,
-                   GtkListBoxRow *row,
-                   GrEditPage *self)
-{
-        const char *ingredient;
-
-        ingredient = gr_ingredient_row_get_ingredient (GR_INGREDIENT_ROW (row));
-        gtk_entry_set_text (GTK_ENTRY (self->new_ingredient_name), ingredient);
-        gtk_label_set_label (GTK_LABEL (self->ing_search_button_label), ingredient);
-        hide_ingredients_search_list (self, TRUE);
-}
-
-static gboolean
-ing_filter_func (GtkListBoxRow *row,
-                 gpointer       data)
-{
-        GrEditPage *self = data;
-        const char *cf;
-
-        if (!GR_IS_INGREDIENT_ROW (row))
-                return TRUE;
 
-        if (!self->ing_term)
-                return TRUE;
-
-        cf = gr_ingredient_row_get_filter_term (GR_INGREDIENT_ROW (row));
+        children = gtk_container_get_children (GTK_CONTAINER (page->ingredients_box));
+        for (l = children; l; l = l->next) {
+                GtkWidget *list = l->data;
+                g_autofree char *segment = NULL;
 
-        return g_str_has_prefix (cf, self->ing_term);
-}
-
-static void
-ing_filter_changed (GrEditPage *self)
-{
-        const char *term;
-
-        term = gtk_entry_get_text (GTK_ENTRY (self->new_ingredient_name));
-        g_free (self->ing_term);
-        self->ing_term = g_utf8_casefold (term, -1);
-        gtk_list_box_invalidate_filter (GTK_LIST_BOX (self->ing_list));
-}
-
-static void
-ing_filter_stop (GrEditPage *self)
-{
-        gtk_entry_set_text (GTK_ENTRY (self->new_ingredient_name), "");
-}
-
-static void
-ing_filter_activated (GrEditPage *self)
-{
-        const char *ingredient;
-
-        ingredient = gtk_entry_get_text (GTK_ENTRY (self->new_ingredient_name));
-        gtk_label_set_label (GTK_LABEL (self->ing_search_button_label), ingredient);
-        hide_ingredients_search_list (self, TRUE);
-}
-
-static void
-populate_ingredients_list (GrEditPage *self)
-{
-        int i;
-        const char **ingredients;
-        GtkWidget *row;
-
-        ingredients = gr_ingredient_get_names (NULL);
-        for (i = 0; ingredients[i]; i++) {
-                row = GTK_WIDGET (gr_ingredient_row_new (ingredients[i]));
-                gtk_widget_show (row);
-                gtk_container_add (GTK_CONTAINER (self->ing_list), row);
+                g_object_get (list, "ingredients", &segment, NULL);
+                if (s->len > 0)
+                        g_string_append (s, "\n");
+                g_string_append (s, segment);
         }
+        g_list_free (children);
 
-        gtk_list_box_set_header_func (GTK_LIST_BOX (self->ing_list),
-                                      all_headers, self, NULL);
-
-        gtk_list_box_set_filter_func (GTK_LIST_BOX (self->ing_list),
-                                      ing_filter_func, self, NULL);
-
-        g_signal_connect (self->ing_list, "row-activated",
-                          G_CALLBACK (ing_row_activated), self);
-}
-
-static void
-show_units_search_list (GrEditPage *self)
-{
-        gtk_widget_hide (self->amount_search_button);
-        gtk_widget_show (self->amount_search_revealer);
-        gtk_revealer_set_reveal_child (GTK_REVEALER (self->amount_search_revealer), TRUE);
-}
-
-static void
-hide_units_search_list (GrEditPage *self,
-                        gboolean    animate)
-{
-        gtk_widget_show (self->amount_search_button);
-        if (!animate)
-                gtk_revealer_set_transition_type (GTK_REVEALER (self->amount_search_revealer),
-                                                  GTK_REVEALER_TRANSITION_TYPE_NONE);
-        gtk_revealer_set_reveal_child (GTK_REVEALER (self->amount_search_revealer), FALSE);
-        if (!animate)
-                gtk_revealer_set_transition_type (GTK_REVEALER (self->amount_search_revealer),
-                                                  GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN);
-}
-
-static void
-amount_search_button_clicked (GtkButton  *button,
-                              GrEditPage *self)
-{
-        hide_ingredients_search_list (self, TRUE);
-        show_units_search_list (self);
-}
-
-static void
-unit_row_activated (GtkListBox    *list,
-                    GtkListBoxRow *row,
-                    GrEditPage *self)
-{
-        g_autofree char *unit = NULL;
-        g_autofree char *amount = NULL;
-        char *tmp;
-
-        format_unit_for_display (gtk_entry_get_text (GTK_ENTRY (self->new_ingredient_amount)),
-                                 (const char *) g_object_get_data (G_OBJECT (row), "unit"),
-                                 &amount, &unit);
-
-        gtk_entry_set_text (GTK_ENTRY (self->new_ingredient_unit), unit);
-        tmp = g_strconcat (amount, " ", unit, NULL);
-        gtk_label_set_label (GTK_LABEL (self->amount_search_button_label), tmp);
-        g_free (tmp);
-
-        hide_units_search_list (self, TRUE);
-}
-
-static gboolean
-unit_filter_func (GtkListBoxRow *row,
-                  gpointer       data)
-{
-        GrEditPage *self = data;
-        const char *unit;
-        g_autofree char *cf1 = NULL;
-        g_autofree char *cf2 = NULL;
-
-        if (!self->unit_term)
-                return TRUE;
-
-        unit = (const char *)g_object_get_data (G_OBJECT (row), "unit");
-        cf1 = g_utf8_casefold (gr_unit_get_abbreviation (unit), -1);
-        cf2 = g_utf8_casefold (gr_unit_get_display_name (unit), -1);
-
-        return g_str_has_prefix (cf1, self->unit_term) ||
-               g_str_has_prefix (cf2, self->unit_term);
-}
-
-static void
-unit_filter_changed (GrEditPage *self)
-{
-        const char *term;
-
-        term = gtk_entry_get_text (GTK_ENTRY (self->new_ingredient_unit));
-        g_free (self->unit_term);
-        self->unit_term = g_utf8_casefold (term, -1);
-        gtk_list_box_invalidate_filter (GTK_LIST_BOX (self->unit_list));
-}
-
-static void
-unit_filter_stop (GrEditPage *self)
-{
-        gtk_entry_set_text (GTK_ENTRY (self->new_ingredient_unit), "");
-}
-
-static void
-unit_filter_activated (GrEditPage *self)
-{
-        const char *amount;
-        const char *unit;
-        g_autofree char *amount_out = NULL;
-        g_autofree char *unit_out = NULL;
-        g_autofree char *parsed = NULL;
-
-        amount = gtk_entry_get_text (GTK_ENTRY (self->new_ingredient_amount));
-        unit = gtk_entry_get_text (GTK_ENTRY (self->new_ingredient_unit));
-        format_unit_for_display (amount, unit, &amount_out, &unit_out);
-        parsed = g_strconcat (amount_out, " ", unit_out, NULL);
-        gtk_label_set_label (GTK_LABEL (self->amount_search_button_label), parsed);
-        hide_units_search_list (self, TRUE);
-}
-
-static void
-populate_units_list (GrEditPage *self)
-{
-        const char **units;
-        GtkWidget *row;
-        GtkWidget *label;
-        int i;
-        const char *name, *abbrev;
-
-        units = gr_unit_get_names ();
-        for (i = 0; units[i]; i++) {
-                row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
-                gtk_widget_show (row);
-                g_object_set (row, "margin", 10, NULL);
-                name = gr_unit_get_display_name (units[i]);
-                abbrev = gr_unit_get_abbreviation (units[i]);
-                if (strcmp (name, abbrev) == 0)
-                        label = gtk_label_new (name);
-                else {
-                        char *tmp;
-                        tmp = g_strdup_printf ("%s (%s)", name, abbrev);
-                        label = gtk_label_new (tmp);
-                        g_free (tmp);
-                }
-                gtk_widget_show (label);
-                gtk_label_set_xalign (GTK_LABEL (label), 0.0);
-                gtk_box_pack_start (GTK_BOX (row), label, TRUE, TRUE, 0);
-
-                gtk_container_add (GTK_CONTAINER (self->unit_list), row);
-                row = gtk_widget_get_parent (row);
-                g_object_set_data (G_OBJECT (row), "unit", (gpointer)units[i]);
-        }
-
-        gtk_list_box_set_header_func (GTK_LIST_BOX (self->unit_list),
-                                      all_headers, self, NULL);
-
-        gtk_list_box_set_filter_func (GTK_LIST_BOX (self->unit_list),
-                                      unit_filter_func, self, NULL);
-
-        g_signal_connect (self->unit_list, "row-activated",
-                          G_CALLBACK (unit_row_activated), self);
+        return g_string_free (s, FALSE);
 }
 
 static void
@@ -1400,8 +740,6 @@ gr_edit_page_init (GrEditPage *page)
         populate_cuisine_combo (page);
         populate_category_combo (page);
         populate_season_combo (page);
-        populate_ingredients_list (page);
-        populate_units_list (page);
 
 #ifdef ENABLE_GSPELL
         {
@@ -1416,42 +754,6 @@ gr_edit_page_init (GrEditPage *page)
 #endif
 }
 
-static gboolean
-popover_keypress_handler (GtkWidget  *widget,
-                          GdkEvent   *event,
-                          GrEditPage *page)
-{
-        GtkWidget *focus;
-
-        focus = gtk_window_get_focus (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (page))));
-
-        if (gtk_revealer_get_child_revealed (GTK_REVEALER (page->ing_search_revealer))) {
-                if (focus == NULL || !gtk_widget_is_ancestor (focus, page->ing_search_revealer)) {
-                        gtk_widget_grab_focus (page->new_ingredient_name);
-                        return gtk_widget_event (page->new_ingredient_name, event);
-                }
-        }
-        else if (gtk_revealer_get_child_revealed (GTK_REVEALER (page->amount_search_revealer))) {
-                if (focus == NULL || !gtk_widget_is_ancestor (focus, page->amount_search_revealer)) {
-                        gtk_widget_grab_focus (page->new_ingredient_unit);
-                        return gtk_widget_event (page->new_ingredient_unit, event);
-                }
-        }
-        else if (gtk_widget_is_sensitive (page->new_ingredient_add_button)) {
-                if (event->type == GDK_KEY_PRESS) {
-                        GdkEventKey *e = (GdkEventKey *) event;
-                        if (e->keyval == GDK_KEY_Return ||
-                            e->keyval == GDK_KEY_ISO_Enter ||
-                            e->keyval == GDK_KEY_KP_Enter) {
-                                gtk_widget_activate (page->new_ingredient_add_button);
-                                return GDK_EVENT_STOP;
-                        }
-                }
-        }
-        
-        return GDK_EVENT_PROPAGATE;
-}
-
 static void
 update_steppers (GrEditPage *page)
 {
@@ -1553,7 +855,7 @@ gr_edit_page_get_property (GObject    *object,
 static void
 set_unsaved (GrEditPage *page)
 {
-        g_object_set (G_OBJECT (page),"unsaved", TRUE, NULL);
+        g_object_set (G_OBJECT (page), "unsaved", TRUE, NULL);
 }
 
 static void
@@ -1611,20 +913,7 @@ gr_edit_page_class_init (GrEditPageClass *klass)
         gtk_widget_class_bind_template_child (widget_class, GrEditPage, rotate_image_right_button);
         gtk_widget_class_bind_template_child (widget_class, GrEditPage, author_label);
         gtk_widget_class_bind_template_child (widget_class, GrEditPage, ingredients_box);
-        gtk_widget_class_bind_template_child (widget_class, GrEditPage, ingredient_popover);
-        gtk_widget_class_bind_template_child (widget_class, GrEditPage, new_ingredient_name);
-        gtk_widget_class_bind_template_child (widget_class, GrEditPage, new_ingredient_amount);
-        gtk_widget_class_bind_template_child (widget_class, GrEditPage, new_ingredient_unit);
-        gtk_widget_class_bind_template_child (widget_class, GrEditPage, new_ingredient_add_button);
-        gtk_widget_class_bind_template_child (widget_class, GrEditPage, ing_list);
-        gtk_widget_class_bind_template_child (widget_class, GrEditPage, ing_search_button);
-        gtk_widget_class_bind_template_child (widget_class, GrEditPage, ing_search_button_label);
-        gtk_widget_class_bind_template_child (widget_class, GrEditPage, ing_search_revealer);
-
-        gtk_widget_class_bind_template_child (widget_class, GrEditPage, unit_list);
-        gtk_widget_class_bind_template_child (widget_class, GrEditPage, amount_search_button);
-        gtk_widget_class_bind_template_child (widget_class, GrEditPage, amount_search_button_label);
-        gtk_widget_class_bind_template_child (widget_class, GrEditPage, amount_search_revealer);
+
         gtk_widget_class_bind_template_child (widget_class, GrEditPage, add_step_button);
         gtk_widget_class_bind_template_child (widget_class, GrEditPage, link_image_button);
         gtk_widget_class_bind_template_child (widget_class, GrEditPage, timer_button);
@@ -1649,20 +938,7 @@ gr_edit_page_class_init (GrEditPageClass *klass)
         gtk_widget_class_bind_template_callback (widget_class, rotate_image_right_cb);
         gtk_widget_class_bind_template_callback (widget_class, images_changed);
         gtk_widget_class_bind_template_callback (widget_class, index_changed);
-        gtk_widget_class_bind_template_callback (widget_class, add_ingredient2);
-        gtk_widget_class_bind_template_callback (widget_class, remove_ingredient);
-        gtk_widget_class_bind_template_callback (widget_class, ingredient_changed);
-
-        gtk_widget_class_bind_template_callback (widget_class, ing_filter_changed);
-        gtk_widget_class_bind_template_callback (widget_class, ing_filter_stop);
-        gtk_widget_class_bind_template_callback (widget_class, ing_filter_activated);
-        gtk_widget_class_bind_template_callback (widget_class, ing_search_button_clicked);
-
-        gtk_widget_class_bind_template_callback (widget_class, unit_filter_changed);
-        gtk_widget_class_bind_template_callback (widget_class, unit_filter_stop);
-        gtk_widget_class_bind_template_callback (widget_class, unit_filter_activated);
-        gtk_widget_class_bind_template_callback (widget_class, amount_search_button_clicked);
-        gtk_widget_class_bind_template_callback (widget_class, popover_keypress_handler);
+
         gtk_widget_class_bind_template_callback (widget_class, add_image_link);
         gtk_widget_class_bind_template_callback (widget_class, add_timer);
         gtk_widget_class_bind_template_callback (widget_class, add_step);
@@ -1680,6 +956,8 @@ gr_edit_page_class_init (GrEditPageClass *klass)
         gtk_widget_class_bind_template_callback (widget_class, prev_step);
         gtk_widget_class_bind_template_callback (widget_class, next_step);
         gtk_widget_class_bind_template_callback (widget_class, set_unsaved);
+
+        gtk_widget_class_bind_template_callback (widget_class, add_list);
 }
 
 GtkWidget *
@@ -1773,216 +1051,85 @@ get_spiciness (GrEditPage *page)
                 return 0;
 }
 
-static void add_list    (GtkButton *button, GrEditPage *page);
-static void remove_list (GtkButton *button, GrEditPage *page);
-static void update_segments (GrEditPage *page);
-
-static GtkWidget *
-add_ingredients_segment (GrEditPage *page,
-                         const char *segment_label)
+static void
+remove_list2 (GrIngredientsViewer *viewer, GrEditPage *page)
 {
-        GtkWidget *segment;
-        GtkWidget *label;
-        GtkWidget *entry;
-        GtkWidget *list;
-        GtkWidget *box;
-        GtkWidget *button;
-        GtkWidget *stack;
-        GtkWidget *image;
-
-        segment = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-        gtk_widget_set_margin_top (segment, 20);
-        gtk_widget_show (segment);
-        gtk_container_add (GTK_CONTAINER (page->ingredients_box), segment);
-
-        stack = gtk_stack_new ();
-        g_object_set_data (G_OBJECT (segment), "stack", stack);
-        gtk_widget_show (stack);
-        gtk_container_add (GTK_CONTAINER (segment), stack);
-
-        label = g_object_new (GTK_TYPE_LABEL,
-                              "label", segment_label[0] ? segment_label : _("Ingredients"),
-                              "xalign", 0.0,
-                              "visible", TRUE,
-                              NULL);
-        gtk_style_context_add_class (gtk_widget_get_style_context (label), "heading");
-        gtk_stack_add_named (GTK_STACK (stack), label, "label");
-
-        box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
-        gtk_widget_set_valign (box, GTK_ALIGN_START);
-        gtk_widget_show (box);
-
-        entry = gtk_entry_new ();
-        g_object_set_data (G_OBJECT (segment), "entry", entry);
-        gtk_widget_set_halign (box, GTK_ALIGN_FILL);
-        gtk_widget_show (entry);
-        gtk_entry_set_placeholder_text (GTK_ENTRY (entry), _("Name of the List"));
-        gtk_entry_set_text (GTK_ENTRY (entry), segment_label[0] ? segment_label : "");
-        g_signal_connect_swapped (entry, "notify::text", G_CALLBACK (set_unsaved),page);
-
-#if defined(ENABLE_GSPELL) && defined(GSPELL_TYPE_ENTRY)
-        {
-                GspellEntry *gspell_entry;
-
-                gspell_entry = gspell_entry_get_from_gtk_entry (GTK_ENTRY (entry));
-                gspell_entry_basic_setup (gspell_entry);
-        }
-#endif
-
-        gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 0);
-
-        button = gtk_button_new_with_label (_("Remove"));
-        g_object_set_data (G_OBJECT (button), "segment", segment);
-        g_object_set_data (G_OBJECT (segment), "remove-list", button);
-        g_signal_connect (button, "clicked", G_CALLBACK (remove_list), page);
-        gtk_widget_show (button);
-        gtk_container_add (GTK_CONTAINER (box), button);
-
-        gtk_stack_add_named (GTK_STACK (stack), box, "entry");
-
-        list = gtk_list_box_new ();
-        g_object_set_data (G_OBJECT (segment), "list", list);
-        gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_SINGLE);
-        g_signal_connect (list, "selected-rows-changed", G_CALLBACK (selected_rows_changed), page);
-
-        gtk_widget_show (list);
-        gtk_style_context_add_class (gtk_widget_get_style_context (list), "frame");
-        gtk_list_box_set_header_func (GTK_LIST_BOX (list), all_headers, NULL, NULL);
-
-        label = g_object_new (GTK_TYPE_LABEL,
-                              "label", _("No ingredients added yet"),
-                              "xalign", 0.5,
-                              "halign", GTK_ALIGN_FILL,
-                              "margin-start", 20,
-                              "margin-end", 20,
-                              "margin-top", 10,
-                              "margin-bottom", 10,
-                              "visible", TRUE,
-                              NULL);
-        gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label");
-        gtk_list_box_set_placeholder (GTK_LIST_BOX (list), label);
-
-        gtk_container_add (GTK_CONTAINER (segment), list);
-
-        box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
-        gtk_widget_set_halign (box, GTK_ALIGN_START);
-        gtk_widget_show (box);
-
-        button = gtk_button_new ();
-        gtk_widget_set_tooltip_text (button, _("Add Ingredient"));
-        image = gtk_image_new_from_icon_name ("list-add-symbolic", 1);
-        gtk_widget_show (image);
-        gtk_widget_set_margin_top (button, 10);
-        gtk_container_add (GTK_CONTAINER (button), image);
-        gtk_style_context_add_class (gtk_widget_get_style_context (button), "dim-label");
-        gtk_style_context_add_class (gtk_widget_get_style_context (button), "image-button");
-        gtk_style_context_remove_class (gtk_widget_get_style_context (button), "text-button");
-        g_signal_connect (button, "clicked", G_CALLBACK (add_ingredient), page);
-        gtk_widget_show (button);
-        gtk_container_add (GTK_CONTAINER (box), button);
-        g_object_set_data (G_OBJECT (button), "list", list);
-
-        gtk_container_add (GTK_CONTAINER (segment), box);
-
-        page->segments = g_list_append (page->segments, segment);
-
-        return list;
+        gtk_widget_destroy (GTK_WIDGET (viewer));
 }
 
 static void
-add_list (GtkButton *button, GrEditPage *page)
+active_changed (GrIngredientsViewer *viewer,
+                GParamSpec          *pspec,
+                GrEditPage          *page)
 {
-        add_ingredients_segment (page, "");
+        gboolean active;
+        GList *children, *l;
 
-        update_segments (page);
-        set_active_row (page, NULL);
+        g_object_get (viewer, "active", &active, NULL);
+
+        if (!active)
+                return;
+
+        children = gtk_container_get_children (GTK_CONTAINER (page->ingredients_box));
+        for (l = children; l; l = l->next) {
+                GrIngredientsViewer *list = l->data;
+                if (list != viewer)
+                        g_object_set (list, "active", FALSE, NULL);
+        }
+        g_list_free (children);
 }
 
 static void
-remove_list (GtkButton *button, GrEditPage *page)
+add_list_full (GrEditPage *page,
+               const char *title,
+               const char *ingredients,
+               gboolean    editable_title)
 {
-        GtkWidget *segment;
+        GtkWidget *list;
 
-        segment = GTK_WIDGET (g_object_get_data (G_OBJECT (button), "segment"));
+        list = g_object_new (GR_TYPE_INGREDIENTS_VIEWER,
+                             "title", title,
+                             "ingredients", ingredients,
+                             "editable-title", editable_title,
+                             "editable", TRUE,
+                             NULL);
 
-        page->segments = g_list_remove (page->segments, segment);
-        gtk_widget_destroy (segment);
+        g_signal_connect_swapped (list, "notify::title", G_CALLBACK (set_unsaved), page);
+        g_signal_connect_swapped (list, "notify::ingredients", G_CALLBACK (set_unsaved), page);
+        g_signal_connect (list, "notify::active", G_CALLBACK (active_changed), page);
+        g_signal_connect (list, "delete", G_CALLBACK (remove_list2), page);
 
-        update_segments (page);
-        set_active_row (page, NULL);
-        set_unsaved (page);
+        gtk_container_add (GTK_CONTAINER (page->ingredients_box), list);
 }
 
 static void
-update_segments (GrEditPage *page)
+add_list (GrEditPage *page)
 {
-        GList *l;
-        GtkWidget *segment;
-        GtkWidget *stack;
-        GtkWidget *button;
-
-        for (l = page->segments; l; l = l->next) {
-                segment = l->data;
-                stack = GTK_WIDGET (g_object_get_data (G_OBJECT (segment), "stack"));
-                button = GTK_WIDGET (g_object_get_data (G_OBJECT (segment), "remove-list"));
-                if (page->segments->next == NULL)
-                        gtk_stack_set_visible_child_name (GTK_STACK (stack), "label");
-                else {
-                        gtk_stack_set_visible_child_name (GTK_STACK (stack), "entry");
-                        gtk_widget_set_visible (button, l != page->segments);
-                }
-        }
+        add_list_full (page, "", "", TRUE);
 }
 
 static void
 populate_ingredients (GrEditPage *page,
                       const char *text)
 {
-        g_autoptr(GrIngredientsList) ingredients = NULL;
-        g_autofree char **segs = NULL;
-        int i, j;
-        GtkWidget *button;
-
         container_remove_all (GTK_CONTAINER (page->ingredients_box));
-        g_list_free (page->segments);
-        page->segments = NULL;
-        page->active_row = NULL;
 
-        if (strcmp (text, "") == 0)
-                add_list (NULL, page);
+        if (strcmp (text, "") == 0) {
+                add_list_full (page, "", "", FALSE);
+        }
         else {
+                g_autoptr(GrIngredientsList) ingredients = NULL;
+                g_autofree char **segs = NULL;
+                gboolean editable_title;
+                int j;
+
                 ingredients = gr_ingredients_list_new (text);
                 segs = gr_ingredients_list_get_segments (ingredients);
+                editable_title = g_strv_length (segs) > 1;
                 for (j = 0; segs[j]; j++) {
-                        GtkWidget *list;
-                        g_auto(GStrv) ings = NULL;
-
-                        list = add_ingredients_segment (page, segs[j]);
-                        ings = gr_ingredients_list_get_ingredients (ingredients, segs[j]);
-                        for (i = 0; ings[i]; i++) {
-                                g_autofree char *s = NULL;
-                                g_auto(GStrv) strv = NULL;
-                                const char *amount;
-                                const char *unit;
-                                GtkWidget *row;
-
-                                s = gr_ingredients_list_scale_unit (ingredients, segs[j], ings[i], 1, 1);
-                                strv = g_strsplit (s, " ", 2);
-                                amount = strv[0];
-                                unit = strv[1] ? strv[1] : "";
-                                row = add_ingredient_row (page, list, page->group);
-                                update_ingredient_row (row, amount, unit, ings[i]);
-                        }
+                        add_list_full (page, segs[j], text, editable_title);
                 }
         }
-
-        button = gtk_button_new_with_label (_("Add List"));
-        gtk_widget_show (button);
-        gtk_widget_set_halign (button, GTK_ALIGN_FILL);
-        gtk_widget_set_margin_top (button, 20);
-        gtk_box_pack_end (GTK_BOX (page->ingredients_box), button, FALSE, TRUE, 0);
-        g_signal_connect (button, "clicked", G_CALLBACK (add_list), page);
-        update_segments (page);
 }
 
 static void
diff --git a/src/gr-edit-page.ui b/src/gr-edit-page.ui
index 717a840..60da901 100644
--- a/src/gr-edit-page.ui
+++ b/src/gr-edit-page.ui
@@ -242,6 +242,14 @@
                         <property name="orientation">vertical</property>
                       </object>
                     </child>
+                    <child>
+                      <object class="GtkButton">
+                        <property name="visible">1</property>
+                        <property name="margin-top">20</property>
+                        <property name="label" translatable="yes">Add List</property>
+                        <signal name="clicked" handler="add_list" swapped="yes"/>
+                      </object>
+                    </child>
                   </object>
                   <packing>
                     <property name="left-attach">0</property>
@@ -851,198 +859,6 @@
       </object>
     </child>
   </template>
-  <object class="GtkPopover" id="ingredient_popover">
-    <property name="constrain-to">none</property>
-    <signal name="key-press-event" handler="popover_keypress_handler" after="yes"/>
-    <child>
-      <object class="GtkBox">
-        <property name="visible">1</property>
-        <property name="margin">12</property>
-        <property name="spacing">12</property>
-        <property name="orientation">vertical</property>
-        <child>
-          <object class="GtkLabel">
-            <property name="visible">1</property>
-            <property name="label" translatable="yes">Ingredient</property>
-            <property name="xalign">0</property>
-            <style>
-              <class name="dim-label"/>
-            </style>
-          </object>
-        </child>
-        <child>
-          <object class="GtkButton" id="ing_search_button">
-            <property name="visible">1</property>
-            <signal name="clicked" handler="ing_search_button_clicked"/>
-            <child>
-              <object class="GtkBox">
-                <property name="visible">1</property>
-                <property name="spacing">10</property>
-                <child>
-                  <object class="GtkLabel" id="ing_search_button_label">
-                    <property name="visible">1</property>
-                    <property name="xalign">0</property>
-                    <property name="ellipsize">end</property>
-                    <property name="max-width-chars">25</property>
-                    <property name="label" translatable="yes">Ingredient</property>
-                  </object>
-                  <packing>
-                    <property name="expand">1</property>
-                  </packing>
-                </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="GtkRevealer" id="ing_search_revealer">
-            <property name="visible">1</property>
-            <child>
-              <object class="GtkBox">
-                <property name="visible">1</property>
-                <property name="orientation">vertical</property>
-                <property name="spacing">10</property>
-                <child>
-                  <object class="GtkSearchEntry" id="new_ingredient_name">
-                    <property name="visible">1</property>
-                    <property name="placeholder-text" translatable="yes">Search…</property>
-                    <signal name="search-changed" handler="ing_filter_changed" swapped="yes"/>
-                    <signal name="stop-search" handler="ing_filter_stop" swapped="yes"/>
-                    <signal name="activate" handler="ing_filter_activated" swapped="yes"/>
-                    <signal name="notify::text" handler="ingredient_changed" swapped="yes"/>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkScrolledWindow">
-                    <property name="visible">1</property>
-                    <property name="shadow-type">in</property>
-                    <property name="hscrollbar-policy">never</property>
-                    <property name="propagate-natural-height">1</property>
-                    <property name="max-content-height">220</property>
-                    <property name="height-request">220</property>
-                    <child>
-                      <object class="GtkListBox" id="ing_list">
-                        <property name="visible">1</property>
-                        <property name="selection-mode">none</property>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-            </child>
-          </object>
-        </child>
-        <child>
-          <object class="GtkLabel">
-            <property name="visible">1</property>
-            <property name="label" translatable="yes">Amount</property>
-            <property name="xalign">0</property>
-            <style>
-              <class name="dim-label"/>
-            </style>
-          </object>
-        </child>
-        <child>
-          <object class="GtkButton" id="amount_search_button">
-            <property name="visible">1</property>
-            <signal name="clicked" handler="amount_search_button_clicked"/>
-            <child>
-              <object class="GtkBox">
-                <property name="visible">1</property>
-                <property name="spacing">10</property>
-                <child>
-                  <object class="GtkLabel" id="amount_search_button_label">
-                    <property name="visible">1</property>
-                    <property name="xalign">0</property>
-                    <property name="ellipsize">end</property>
-                    <property name="max-width-chars">25</property>
-                    <property name="label" translatable="yes">Amount</property>
-                  </object>
-                  <packing>
-                    <property name="expand">1</property>
-                  </packing>
-                </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="GtkRevealer" id="amount_search_revealer">
-            <property name="visible">1</property>
-            <child>
-              <object class="GtkBox">
-                <property name="visible">1</property>
-                <property name="orientation">vertical</property>
-                <property name="spacing">10</property>
-                <child>
-                  <object class="GtkBox">
-                    <property name="visible">1</property>
-                    <style>
-                      <class name="linked"/>
-                    </style>
-                    <child>
-                      <object class="GtkEntry" id="new_ingredient_amount">
-                        <property name="visible">1</property>
-                        <property name="width-chars">6</property>
-                        <signal name="activate" handler="unit_filter_activated" swapped="yes"/>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkSearchEntry" id="new_ingredient_unit">
-                        <property name="visible">1</property>
-                        <property name="placeholder-text" translatable="yes">Search…</property>
-                        <signal name="search-changed" handler="unit_filter_changed" swapped="yes"/>
-                        <signal name="stop-search" handler="unit_filter_stop" swapped="yes"/>
-                        <signal name="activate" handler="unit_filter_activated" swapped="yes"/>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkScrolledWindow">
-                    <property name="visible">1</property>
-                    <property name="shadow-type">in</property>
-                    <property name="hscrollbar-policy">never</property>
-                    <property name="propagate-natural-height">1</property>
-                    <property name="max-content-height">220</property>
-                    <property name="height-request">220</property>
-                    <child>
-                      <object class="GtkListBox" id="unit_list">
-                        <property name="visible">1</property>
-                        <property name="selection-mode">none</property>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-            </child>
-          </object>
-        </child>
-        <child>
-          <object class="GtkButton" id="new_ingredient_add_button">
-            <property name="visible">1</property>
-            <property name="label" translatable="yes">Add</property>
-            <property name="halign">end</property>
-            <signal name="clicked" handler="add_ingredient2"/>
-          </object>
-        </child>
-      </object>
-    </child>
-  </object>
   <object class="GtkPopover" id="image_popover">
     <property name="relative-to">link_image_button</property>
     <property name="constrain-to">none</property>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]