[recipes] Redo the edit page



commit 5aca3f0f1518a4f3d4032c8b88120bc85d13a48d
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Dec 16 20:36:14 2016 -0500

    Redo the edit page
    
    This is a roughly working experiment, trying to use a similar
    2 column layout on the edit page, with a more structured editor
    for ingredients.
    
    More work is needed on the ingredients list, but this is
    functional enough for now.

 src/gr-edit-page.c  |  224 ++++++++----
 src/gr-edit-page.ui |  990 +++++++++++++++++++++++++++++----------------------
 2 files changed, 718 insertions(+), 496 deletions(-)
---
diff --git a/src/gr-edit-page.c b/src/gr-edit-page.c
index 442ffcf..d1c5090 100644
--- a/src/gr-edit-page.c
+++ b/src/gr-edit-page.c
@@ -53,16 +53,14 @@ struct _GrEditPage
         GtkWidget *error_revealer;
         GtkWidget *error_label;
         GtkWidget *name_entry;
-        GtkWidget *description_field;
         GtkWidget *cuisine_combo;
         GtkWidget *category_combo;
         GtkWidget *season_combo;
         GtkWidget *spiciness_combo;
         GtkWidget *prep_time_combo;
         GtkWidget *cook_time_combo;
-        GtkWidget *ingredients_field;
+        GtkWidget *ingredients_list;
         GtkWidget *instructions_field;
-        GtkWidget *notes_field;
         GtkWidget *serves_spin;
         GtkWidget *gluten_free_check;
         GtkWidget *nut_free_check;
@@ -74,6 +72,14 @@ struct _GrEditPage
         GtkWidget *remove_image_button;
         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 *remove_ingredient_button;
+
+        GtkSizeGroup *group;
 
         guint account_response_signal_id;
 };
@@ -98,10 +104,6 @@ images_changed (GrEditPage *page)
         gtk_widget_set_sensitive (page->remove_image_button, length > 0);
         gtk_widget_set_sensitive (page->rotate_image_left_button, length > 0);
         gtk_widget_set_sensitive (page->rotate_image_right_button, length > 0);
-
-        gtk_container_child_set (GTK_CONTAINER (gtk_widget_get_parent (page->images)), page->images,
-                                 "width", length >= 2 ? 2 : 1,
-                                 NULL);
 }
 
 static void
@@ -134,6 +136,7 @@ edit_page_finalize (GObject *object)
         GrEditPage *self = GR_EDIT_PAGE (object);
 
         g_clear_object (&self->recipe);
+        g_clear_object (&self->group);
 
         G_OBJECT_CLASS (gr_edit_page_parent_class)->finalize (object);
 }
@@ -186,23 +189,120 @@ populate_season_combo (GrEditPage *page)
 }
 
 static void
-ingredients_changed (GrEditPage *page)
+add_ingredient (GrEditPage *page)
 {
-        GtkWidget *sw;
-        GtkStyleContext *context;
+        gtk_popover_popup (GTK_POPOVER (page->ingredient_popover));
+}
+
+static void
+remove_ingredient (GrEditPage *page)
+{
+        GtkListBoxRow *row;
+
+        row = gtk_list_box_get_selected_row (GTK_LIST_BOX (page->ingredients_list));
+        if (!row)
+                return;
+
+        gtk_container_remove (GTK_CONTAINER (page->ingredients_list), GTK_WIDGET (row));
 
-        sw = gtk_widget_get_ancestor (page->ingredients_field, GTK_TYPE_SCROLLED_WINDOW);
-        context = gtk_widget_get_style_context (sw);
-        gtk_style_context_remove_class (context, "error");
 }
 
 static void
-connect_ingredients_signals (GrEditPage *page)
+selected_rows_changed (GrEditPage *page)
 {
-        GtkTextBuffer *buffer;
+        GtkListBoxRow *row;
+
+        row = gtk_list_box_get_selected_row (GTK_LIST_BOX (page->ingredients_list));
+        gtk_widget_set_sensitive (page->remove_ingredient_button, row != NULL);
+}
+
+static void
+add_ingredient_row (GrEditPage *page,
+                    const char *unit,
+                    const char *ingredient)
+{
+        GtkWidget *box;
+        GtkWidget *label;
+        GtkWidget *row;
+
+        box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+        gtk_widget_show (box);
+
+        label = gtk_label_new (unit);
+        g_object_set (label,
+                      "visible", TRUE,
+                      "xalign", 0.0,
+                      "margin", 10,
+                      NULL);
+        gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label");
+        gtk_container_add (GTK_CONTAINER (box), label);
+        gtk_size_group_add_widget (page->group, label);
+
+        label = gtk_label_new (ingredient);
+        g_object_set (label,
+                      "visible", TRUE,
+                      "xalign", 0.0,
+                      "margin", 10,
+                      NULL);
+        gtk_container_add (GTK_CONTAINER (box), label);
+
+        gtk_container_add (GTK_CONTAINER (page->ingredients_list), box);
+        row = gtk_widget_get_parent (box);
+        g_object_set_data_full (G_OBJECT (row), "ingredient", g_strdup_printf ("%s %s", unit, ingredient), 
g_free);
+
+        gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), FALSE);
+}
+
+static void
+add_ingredient2 (GrEditPage *page)
+{
+        const char *ingredient;
+        double amount;
+        const char *unit;
+        g_autofree char *s = NULL;
+
+        gtk_popover_popdown (GTK_POPOVER (page->ingredient_popover));
+
+        ingredient = gtk_entry_get_text (GTK_ENTRY (page->new_ingredient_name));
+        amount = gtk_spin_button_get_value (GTK_SPIN_BUTTON (page->new_ingredient_amount));
+        unit = gtk_entry_get_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (page->new_ingredient_unit))));
+
+        s = g_strdup_printf ("%g %s", amount, unit);
+        add_ingredient_row (page, s, ingredient);
+}
+
+static char *
+collect_ingredients (GrEditPage *page)
+{
+        GString *s;
+        GList *children, *l;
+
+        s = g_string_new ("");
+        children = gtk_container_get_children (GTK_CONTAINER (page->ingredients_list));
+        for (l = children; l; l = l->next) {
+                GtkWidget *row = l->data;
+                if (s->len > 0)
+                        g_string_append (s, "\n");
+                g_string_append (s, (const char *)g_object_get_data (G_OBJECT (row), "ingredient"));
+        }
+        g_list_free (children);
 
-        buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (page->ingredients_field));
-        g_signal_connect_swapped (buffer, "changed", G_CALLBACK (ingredients_changed), page);
+        return g_string_free (s, FALSE);
+}
+
+static void
+all_headers (GtkListBoxRow *row,
+             GtkListBoxRow *before,
+             gpointer       user_data)
+{
+        GtkWidget *header;
+
+        header = gtk_list_box_row_get_header (row);
+        if (header)
+                return;
+
+        header = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+        gtk_list_box_row_set_header (row, header);
 }
 
 static void
@@ -211,10 +311,14 @@ gr_edit_page_init (GrEditPage *page)
         gtk_widget_set_has_window (GTK_WIDGET (page), FALSE);
         gtk_widget_init_template (GTK_WIDGET (page));
 
+        page->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+        gtk_list_box_set_header_func (GTK_LIST_BOX (page->ingredients_list),
+                                      all_headers, NULL, NULL);
+
         populate_cuisine_combo (page);
         populate_category_combo (page);
         populate_season_combo (page);
-        connect_ingredients_signals (page);
 }
 
 static void
@@ -230,7 +334,6 @@ gr_edit_page_class_init (GrEditPageClass *klass)
         gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, error_revealer);
         gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, error_label);
         gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, name_entry);
-        gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, description_field);
         gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, cuisine_combo);
         gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, category_combo);
         gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, season_combo);
@@ -238,9 +341,8 @@ gr_edit_page_class_init (GrEditPageClass *klass)
         gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, cook_time_combo);
         gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, serves_spin);
         gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, spiciness_combo);
-        gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, ingredients_field);
+        gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, ingredients_list);
         gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, instructions_field);
-        gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, notes_field);
         gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, gluten_free_check);
         gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, nut_free_check);
         gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, vegan_check);
@@ -251,6 +353,11 @@ gr_edit_page_class_init (GrEditPageClass *klass)
         gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, remove_image_button);
         gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, 
rotate_image_left_button);
         gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, 
rotate_image_right_button);
+        gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, ingredient_popover);
+        gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, new_ingredient_name);
+        gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, new_ingredient_amount);
+        gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, new_ingredient_unit);
+        gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GrEditPage, 
remove_ingredient_button);
 
         gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), dismiss_error);
         gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), add_image);
@@ -258,6 +365,10 @@ gr_edit_page_class_init (GrEditPageClass *klass)
         gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), rotate_image_left);
         gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), rotate_image_right);
         gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), images_changed);
+        gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), add_ingredient);
+        gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), add_ingredient2);
+        gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), remove_ingredient);
+        gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), selected_rows_changed);
 }
 
 GtkWidget *
@@ -355,7 +466,6 @@ gr_edit_page_clear (GrEditPage *page)
         GArray *images;
 
         gtk_entry_set_text (GTK_ENTRY (page->name_entry), "");
-        set_text_view_text (GTK_TEXT_VIEW (page->description_field), "");
         set_combo_value (GTK_COMBO_BOX (page->cuisine_combo), "");
         set_combo_value (GTK_COMBO_BOX (page->category_combo), "");
         set_combo_value (GTK_COMBO_BOX (page->season_combo), "");
@@ -363,9 +473,8 @@ gr_edit_page_clear (GrEditPage *page)
         set_combo_value (GTK_COMBO_BOX (page->cook_time_combo), "");
         gtk_spin_button_set_value (GTK_SPIN_BUTTON (page->serves_spin), 1);
         set_spiciness (page, 0);
-        set_text_view_text (GTK_TEXT_VIEW (page->ingredients_field), "");
+        container_remove_all (GTK_CONTAINER (page->ingredients_list));
         set_text_view_text (GTK_TEXT_VIEW (page->instructions_field), "");
-        set_text_view_text (GTK_TEXT_VIEW (page->notes_field), "");
         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->gluten_free_check), FALSE);
         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->nut_free_check), FALSE);
         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->vegan_check), FALSE);
@@ -379,12 +488,30 @@ gr_edit_page_clear (GrEditPage *page)
         g_clear_object (&page->recipe);
 }
 
+static void
+populate_ingredients (GrEditPage *page,
+                       GrRecipe   *recipe)
+{
+        g_autoptr(GrIngredientsList) ingredients = NULL;
+        g_auto(GStrv) ings = NULL;
+        int i;
+
+        container_remove_all (GTK_CONTAINER (page->ingredients_list));
+
+        ingredients = gr_ingredients_list_new (gr_recipe_get_ingredients (recipe));
+        ings = gr_ingredients_list_get_ingredients (ingredients);
+        for (i = 0; ings[i]; i++) {
+                g_autofree char *s = NULL;
+                s = gr_ingredients_list_scale_unit (ingredients, ings[i], 1, 1);
+                add_ingredient_row (page,  s, ings[i]);
+        }
+}
+
 void
 gr_edit_page_edit (GrEditPage *page,
                    GrRecipe   *recipe)
 {
         const char *name;
-        const char *description;
         const char *cuisine;
         const char *category;
         const char *season;
@@ -392,16 +519,13 @@ gr_edit_page_edit (GrEditPage *page,
         const char *cook_time;
         int serves;
         int spiciness;
-        const char *ingredients;
         const char *instructions;
-        const char *notes;
         g_autofree char *image_path = NULL;
         g_autoptr(GdkPixbuf) pixbuf = NULL;
         GrDiets diets;
         g_autoptr(GArray) images = NULL;
 
         name = gr_recipe_get_name (recipe);
-        description = gr_recipe_get_description (recipe);
         serves = gr_recipe_get_serves (recipe);
         spiciness = gr_recipe_get_spiciness (recipe);
         cuisine = gr_recipe_get_cuisine (recipe);
@@ -410,14 +534,11 @@ gr_edit_page_edit (GrEditPage *page,
         prep_time = gr_recipe_get_prep_time (recipe);
         cook_time = gr_recipe_get_cook_time (recipe);
         diets = gr_recipe_get_diets (recipe);
-        ingredients = gr_recipe_get_ingredients (recipe);
         instructions = gr_recipe_get_instructions (recipe);
-        notes = gr_recipe_get_notes (recipe);
 
         g_object_get (recipe, "images", &images, NULL);
 
         gtk_entry_set_text (GTK_ENTRY (page->name_entry), name);
-        set_text_view_text (GTK_TEXT_VIEW (page->description_field), description);
         set_combo_value (GTK_COMBO_BOX (page->cuisine_combo), cuisine);
         set_combo_value (GTK_COMBO_BOX (page->category_combo), category);
         set_combo_value (GTK_COMBO_BOX (page->season_combo), season);
@@ -425,9 +546,9 @@ gr_edit_page_edit (GrEditPage *page,
         set_combo_value (GTK_COMBO_BOX (page->cook_time_combo), cook_time);
         set_spiciness (page, spiciness);
         gtk_spin_button_set_value (GTK_SPIN_BUTTON (page->serves_spin), serves);
-        set_text_view_text (GTK_TEXT_VIEW (page->ingredients_field), ingredients);
         set_text_view_text (GTK_TEXT_VIEW (page->instructions_field), instructions);
-        set_text_view_text (GTK_TEXT_VIEW (page->notes_field), notes);
+
+        populate_ingredients (page, recipe);
 
         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->gluten_free_check), (diets & 
GR_DIET_GLUTEN_FREE) != 0);
         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->nut_free_check), (diets & GR_DIET_NUT_FREE) 
!= 0);
@@ -440,10 +561,6 @@ gr_edit_page_edit (GrEditPage *page,
         g_set_object (&page->recipe, recipe);
 }
 
-static gboolean validate_ingredients (GrEditPage  *page,
-                                      const char  *ingredients,
-                                      GError     **error);
-
 static void
 account_response (GDBusConnection *connection,
                   const char *sender_name,
@@ -671,7 +788,6 @@ gboolean
 gr_edit_page_save (GrEditPage *page)
 {
         const char *name;
-        const char *description;
         g_autofree char *cuisine = NULL;
         g_autofree char *category = NULL;
         g_autofree char *season = NULL;
@@ -681,7 +797,6 @@ gr_edit_page_save (GrEditPage *page)
         int spiciness;
         g_autofree char *ingredients = NULL;
         g_autofree char *instructions = NULL;
-        g_autofree char *notes = NULL;
         GrRecipeStore *store;
         g_autoptr(GError) error = NULL;
         gboolean ret = TRUE;
@@ -691,7 +806,6 @@ gr_edit_page_save (GrEditPage *page)
         store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
 
         name = gtk_entry_get_text (GTK_ENTRY (page->name_entry));
-        description = get_text_view_text (GTK_TEXT_VIEW (page->description_field));
         cuisine = get_combo_value (GTK_COMBO_BOX (page->cuisine_combo));
         category = get_combo_value (GTK_COMBO_BOX (page->category_combo));
         season = get_combo_value (GTK_COMBO_BOX (page->season_combo));
@@ -699,18 +813,14 @@ gr_edit_page_save (GrEditPage *page)
         cook_time = get_combo_value (GTK_COMBO_BOX (page->cook_time_combo));
         spiciness = get_spiciness (page);
         serves = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (page->serves_spin));
-        ingredients = get_text_view_text (GTK_TEXT_VIEW (page->ingredients_field));
+        ingredients = collect_ingredients (page);
         instructions = get_text_view_text (GTK_TEXT_VIEW (page->instructions_field));
-        notes = get_text_view_text (GTK_TEXT_VIEW (page->notes_field));
         diets = (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->gluten_free_check)) ? 
GR_DIET_GLUTEN_FREE : 0) |
                 (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->nut_free_check)) ? GR_DIET_NUT_FREE 
: 0) |
                 (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->vegan_check)) ? GR_DIET_VEGAN : 0) |
                (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->vegetarian_check)) ? 
GR_DIET_VEGETARIAN : 0) |
                 (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->milk_free_check)) ? 
GR_DIET_MILK_FREE : 0);
 
-        if (!validate_ingredients (page, ingredients, &error))
-                goto error;
-
         g_object_get (page->images, "images", &images, NULL);
 
         if (page->recipe) {
@@ -724,7 +834,6 @@ gr_edit_page_save (GrEditPage *page)
                 g_object_set (page->recipe,
                               "id", id,
                               "name", name,
-                              "description", description,
                               "cuisine", cuisine,
                               "category", category,
                               "season", season,
@@ -734,7 +843,6 @@ gr_edit_page_save (GrEditPage *page)
                               "spiciness", spiciness,
                               "ingredients", ingredients,
                               "instructions", instructions,
-                              "notes", notes,
                               "diets", diets,
                               "images", images,
                               NULL);
@@ -751,7 +859,6 @@ gr_edit_page_save (GrEditPage *page)
                 recipe = g_object_new (GR_TYPE_RECIPE,
                                        "id", id,
                                        "name", name,
-                                       "description", description,
                                        "author", author,
                                        "cuisine", cuisine,
                                        "category", category,
@@ -762,7 +869,6 @@ gr_edit_page_save (GrEditPage *page)
                                        "spiciness", spiciness,
                                        "ingredients", ingredients,
                                        "instructions", instructions,
-                                       "notes", notes,
                                        "diets", diets,
                                        "images", images,
                                        NULL);
@@ -784,23 +890,3 @@ error:
 
         return FALSE;
 }
-
-static gboolean
-validate_ingredients (GrEditPage  *page,
-                      const char  *ingredients,
-                      GError     **error)
-{
-        if (!gr_ingredients_list_validate (ingredients, error)) {
-                GtkWidget *sw;
-                GtkStyleContext *context;
-
-                sw = gtk_widget_get_ancestor (page->ingredients_field, GTK_TYPE_SCROLLED_WINDOW);
-                context = gtk_widget_get_style_context (sw);
-                gtk_style_context_add_class (context, "error");
-
-                return FALSE;
-        }
-        else {
-                return TRUE;
-        }
-}
diff --git a/src/gr-edit-page.ui b/src/gr-edit-page.ui
index fbe43f5..9558fba 100644
--- a/src/gr-edit-page.ui
+++ b/src/gr-edit-page.ui
@@ -66,522 +66,588 @@
             <property name="expand">1</property>
             <property name="hscrollbar-policy">never</property>
             <child>
-              <object class="GtkGrid">
+              <object class="GtkBox">
                 <property name="visible">1</property>
+                <property name="homogeneous">1</property>
+                <property name="expand">1</property>
                 <property name="halign">center</property>
                 <property name="valign">start</property>
-                <property name="row-spacing">20</property>
-                <property name="column-spacing">40</property>
-                <property name="margin-top">40</property>
-                <property name="margin-bottom">40</property>
-                <property name="margin-start">48</property>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">1</property>
-                    <property name="use-underline">1</property>
-                    <property name="mnemonic-widget">name_entry</property>
-                    <property name="label" translatable="yes">_Name your recipe</property>
-                    <property name="xalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkEntry" id="name_entry">
-                    <property name="visible">1</property>
-                    <property name="valign">center</property>
-                  </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">1</property>
-                    <property name="use-underline">1</property>
-                    <property name="mnemonic-widget">serves_spin</property>
-                    <property name="label" translatable="yes">Ser_ves</property>
-                    <property name="xalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">2</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkSpinButton" id="serves_spin">
-                    <property name="visible">1</property>
-                    <property name="adjustment">serves_adjustment</property>
-                    <property name="valign">center</property>
-                  </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">3</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GrImageViewer" id="images">
-                    <signal name="notify::images" handler="images_changed" swapped="yes"/>
-                    <accessibility>
-                      <relation target="add_image_button" type="controlled-by"/>
-                      <relation target="remove_image_button" type="controlled-by"/>
-                      <relation target="rotate_image_left_button" type="controlled-by"/>
-                      <relation target="rotate_image_right_button" type="controlled-by"/>
-                    </accessibility>
-                  </object>
-                  <packing>
-                    <property name="left-attach">1</property>
-                    <property name="top-attach">0</property>
-                    <property name="height">4</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">1</property>
-                    <property name="use-underline">1</property>
-                    <property name="mnemonic-widget">description_field</property>
-                    <property name="label" translatable="yes">_Description</property>
-                    <property name="xalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">4</property>
-                  </packing>
-                </child>
+                <property name="margin-start">40</property>
+                <property name="margin-end">40</property>
+                <property name="margin-bottom">20</property>
+                <property name="spacing">20</property>
                 <child>
                   <object class="GtkBox">
                     <property name="visible">1</property>
-                    <property name="spacing">10</property>
+                    <property name="orientation">vertical</property>
+                    <property name="spacing">20</property>
+                    <property name="margin-top">20</property>
+                    <property name="valign">start</property>
+                    <property name="halign">end</property>
                     <child>
-                      <object class="GtkButton" id="add_image_button">
+                      <object class="GrImageViewer" id="images">
                         <property name="visible">1</property>
-                        <property name="halign">center</property>
-                        <property name="valign">start</property>
-                        <property name="tooltip-text" translatable="yes">Add an image</property>
+                        <signal name="notify::images" handler="images_changed" swapped="yes"/>
                         <accessibility>
-                          <relation target="images" type="controller-for"/>
+                          <relation target="add_image_button" type="controlled-by"/>
+                          <relation target="rotate_image_left_button" type="controlled-by"/>
+                          <relation target="rotate_image_right_button" type="controlled-by"/>
+                          <relation target="remove_image_button" type="controlled-by"/>
                         </accessibility>
-                        <style>
-                          <class name="image-button"/>
-                          <class name="circular"/>
-                          <class name="dim-label"/>
-                        </style>
-                        <signal name="clicked" handler="add_image" swapped="yes"/>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkBox">
+                        <property name="visible">1</property>
+                        <property name="spacing">10</property>
+                        <property name="halign">start</property>
                         <child>
-                          <object class="GtkImage">
+                          <object class="GtkButton" id="add_image_button">
+                            <property name="visible">1</property>
+                            <property name="halign">center</property>
+                            <property name="valign">start</property>
+                            <property name="tooltip-text" translatable="yes">Add an image</property>
+                            <accessibility>
+                              <relation target="images" type="controller-for"/>
+                            </accessibility>
+                            <style>
+                              <class name="image-button"/>
+                              <class name="circular"/>
+                              <class name="dim-label"/>
+                            </style>
+                            <signal name="clicked" handler="add_image" swapped="yes"/>
+                            <child>
+                              <object class="GtkImage">
+                                <property name="visible">1</property>
+                                <property name="icon-name">list-add-symbolic</property>
+                                <property name="pixel-size">20</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkButton" id="rotate_image_left_button">
                             <property name="visible">1</property>
-                            <property name="icon-name">list-add-symbolic</property>
-                            <property name="pixel-size">20</property>
+                            <property name="halign">center</property>
+                            <property name="valign">start</property>
+                            <property name="tooltip-text" translatable="yes">Rotate image</property>
+                            <accessibility>
+                              <relation target="images" type="controller-for"/>
+                            </accessibility>
+                            <style>
+                              <class name="image-button"/>
+                              <class name="circular"/>
+                              <class name="dim-label"/>
+                            </style>
+                            <signal name="clicked" handler="rotate_image_left" swapped="yes"/>
+                            <child>
+                              <object class="GtkImage">
+                                <property name="visible">1</property>
+                                <property name="icon-name">object-rotate-left-symbolic</property>
+                                <property name="pixel-size">20</property>
+                              </object>
+                            </child>
                           </object>
+                          <packing>
+                            <property name="expand">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkButton" id="rotate_image_right_button">
+                            <property name="visible">1</property>
+                            <property name="halign">center</property>
+                            <property name="valign">start</property>
+                            <property name="tooltip-text" translatable="yes">Rotate image</property>
+                            <accessibility>
+                              <relation target="images" type="controller-for"/>
+                            </accessibility>
+                            <style>
+                              <class name="image-button"/>
+                              <class name="circular"/>
+                              <class name="dim-label"/>
+                            </style>
+                            <signal name="clicked" handler="rotate_image_right" swapped="yes"/>
+                            <child>
+                              <object class="GtkImage">
+                                <property name="visible">1</property>
+                                <property name="icon-name">object-rotate-right-symbolic</property>
+                                <property name="pixel-size">20</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkButton" id="remove_image_button">
+                            <property name="visible">1</property>
+                            <property name="halign">center</property>
+                            <property name="valign">start</property>
+                            <property name="tooltip-text" translatable="yes">Remove image</property>
+                            <accessibility>
+                              <relation target="images" type="controller-for"/>
+                            </accessibility>
+                            <style>
+                              <class name="image-button"/>
+                              <class name="circular"/>
+                              <class name="dim-label"/>
+                            </style>
+                            <signal name="clicked" handler="remove_image" swapped="yes"/>
+                            <child>
+                              <object class="GtkImage">
+                                <property name="visible">1</property>
+                                <property name="icon-name">edit-delete-symbolic</property>
+                                <property name="pixel-size">20</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">1</property>
+                          </packing>
                         </child>
                       </object>
                       <packing>
-                        <property name="expand">1</property>
+                        <property name="fill">1</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkButton" id="remove_image_button">
+                      <object class="GtkLabel">
                         <property name="visible">1</property>
-                        <property name="halign">center</property>
-                        <property name="valign">start</property>
-                        <property name="tooltip-text" translatable="yes">Remove image</property>
-                        <accessibility>
-                          <relation target="images" type="controller-for"/>
-                        </accessibility>
-                        <style>
-                          <class name="image-button"/>
-                          <class name="circular"/>
-                          <class name="dim-label"/>
-                        </style>
-                        <signal name="clicked" handler="remove_image" swapped="yes"/>
+                        <property name="label" translatable="yes">Ingredients</property>
+                        <property name="xalign">0</property>
+                        <style> <class name="heading"/> </style>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkScrolledWindow">
+                        <property name="visible">1</property>
+                        <property name="shadow-type">in</property>
+                        <property name="min-content-height">240</property>
                         <child>
-                          <object class="GtkImage">
+                          <object class="GtkListBox" id="ingredients_list">
                             <property name="visible">1</property>
-                            <property name="icon-name">edit-delete-symbolic</property>
-                            <property name="pixel-size">20</property>
+                            <property name="selection-mode">single</property>
+                            <signal name="selected-rows-changed" handler="selected_rows_changed" 
swapped="yes"/>
+                            <style>
+                              <class name="frame"/>
+                            </style>
+                            <accessibility>
+                              <relation target="add_ingredient_button" type="controlled-by"/>
+                              <relation target="remove_ingredient_button" type="controlled-by"/>
+                            </accessibility>
+                            <child type="placeholder">
+                              <object class="GtkLabel">
+                                <property name="visible">1</property>
+                                <property name="margin-start">40</property>
+                                <property name="margin-end">40</property>
+                                <property name="margin-top">10</property>
+                                <property name="margin-bottom">10</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">No ingredients added yet</property>
+                                <style> <class name="dim-label"/> </style>
+                              </object>
+                            </child>
                           </object>
                         </child>
                       </object>
-                      <packing>
-                        <property name="expand">1</property>
-                      </packing>
                     </child>
                     <child>
-                      <object class="GtkButton" id="rotate_image_left_button">
+                      <object class="GtkBox">
                         <property name="visible">1</property>
-                        <property name="halign">center</property>
-                        <property name="valign">start</property>
-                        <property name="tooltip-text" translatable="yes">Rotate image</property>
-                        <accessibility>
-                          <relation target="images" type="controller-for"/>
-                        </accessibility>
-                        <style>
-                          <class name="image-button"/>
-                          <class name="circular"/>
-                          <class name="dim-label"/>
-                        </style>
-                        <signal name="clicked" handler="rotate_image_left" swapped="yes"/>
+                        <property name="spacing">10</property>
+                        <property name="halign">start</property>
                         <child>
-                          <object class="GtkImage">
+                          <object class="GtkButton" id="add_ingredient_button">
                             <property name="visible">1</property>
-                            <property name="icon-name">object-rotate-left-symbolic</property>
-                            <property name="pixel-size">20</property>
+                            <property name="halign">center</property>
+                            <property name="valign">start</property>
+                            <property name="tooltip-text" translatable="yes">Add an ingredient</property>
+                            <accessibility>
+                              <relation target="ingredients_list" type="controller-for"/>
+                            </accessibility>
+                            <style>
+                              <class name="image-button"/>
+                              <class name="circular"/>
+                              <class name="dim-label"/>
+                            </style>
+                            <signal name="clicked" handler="add_ingredient" swapped="yes"/>
+                            <child>
+                              <object class="GtkImage">
+                                <property name="visible">1</property>
+                                <property name="icon-name">list-add-symbolic</property>
+                                <property name="pixel-size">20</property>
+                              </object>
+                            </child>
                           </object>
+                          <packing>
+                            <property name="expand">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkButton" id="remove_ingredient_button">
+                            <property name="visible">1</property>
+                            <property name="halign">center</property>
+                            <property name="valign">start</property>
+                            <property name="sensitive">0</property>
+                            <property name="tooltip-text" translatable="yes">Remove an ingredient</property>
+                            <accessibility>
+                              <relation target="ingredients_list" type="controller-for"/>
+                            </accessibility>
+                            <style>
+                              <class name="image-button"/>
+                              <class name="circular"/>
+                              <class name="dim-label"/>
+                            </style>
+                            <signal name="clicked" handler="remove_ingredient" swapped="yes"/>
+                            <child>
+                              <object class="GtkImage">
+                                <property name="visible">1</property>
+                                <property name="icon-name">edit-delete-symbolic</property>
+                                <property name="pixel-size">20</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">1</property>
+                          </packing>
                         </child>
                       </object>
                       <packing>
-                        <property name="expand">1</property>
+                        <property name="fill">1</property>
                       </packing>
                     </child>
+
                     <child>
-                      <object class="GtkButton" id="rotate_image_right_button">
+                      <object class="GtkFlowBox">
                         <property name="visible">1</property>
-                        <property name="halign">center</property>
-                        <property name="valign">start</property>
-                        <property name="tooltip-text" translatable="yes">Rotate image</property>
-                        <accessibility>
-                          <relation target="images" type="controller-for"/>
-                        </accessibility>
-                        <style>
-                          <class name="image-button"/>
-                          <class name="circular"/>
-                          <class name="dim-label"/>
-                        </style>
-                        <signal name="clicked" handler="rotate_image_right" swapped="yes"/>
+                        <property name="selection-mode">none</property>
+                        <property name="min-children-per-line">4</property>
+                        <property name="max-children-per-line">4</property>
                         <child>
-                          <object class="GtkImage">
+                          <object class="GtkCheckButton" id="gluten_free_check">
+                            <property name="visible">1</property>
+                            <property name="label" translatable="yes">Gluten free</property>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkCheckButton" id="nut_free_check">
                             <property name="visible">1</property>
-                            <property name="icon-name">object-rotate-right-symbolic</property>
-                            <property name="pixel-size">20</property>
+                            <property name="label" translatable="yes">Nut free</property>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkCheckButton" id="vegan_check">
+                            <property name="visible">1</property>
+                            <property name="label" translatable="yes">Vegan</property>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkCheckButton" id="vegetarian_check">
+                            <property name="visible">1</property>
+                            <property name="label" translatable="yes">Vegetarian</property>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkCheckButton" id="milk_free_check">
+                            <property name="visible">1</property>
+                            <property name="label" translatable="yes">Milk free</property>
                           </object>
                         </child>
                       </object>
+                    </child>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">1</property>
+                        <property name="label" translatable="yes">Other Information</property>
+                        <property name="xalign">0</property>
+                        <style> <class name="heading"/> </style>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkGrid">
+                        <property name="visible">1</property>
+                        <property name="row-spacing">20</property>
+                        <property name="column-spacing">40</property>
+                        <property name="halign">fill</property>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">1</property>
+                        <property name="use-underline">1</property>
+                        <property name="mnemonic-widget">cuisine_combo</property>
+                        <property name="label" translatable="yes">_Cuisine</property>
+                        <property name="xalign">1</property>
+                        <style> <class name="dim-label"/> </style>
+                      </object>
                       <packing>
-                        <property name="expand">1</property>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">0</property>
                       </packing>
                     </child>
-                  </object>
-                  <packing>
-                    <property name="left-attach">1</property>
-                    <property name="top-attach">4</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkEventBox">
-                    <property name="visible">1</property>
-                    <property name="width-request">8</property>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkScrolledWindow">
-                    <property name="visible">1</property>
-                    <property name="shadow-type">in</property>
-                    <property name="min-content-height">60</property>
                     <child>
-                      <object class="GtkTextView" id="description_field">
+                      <object class="GtkLabel">
                         <property name="visible">1</property>
-                        <property name="wrap-mode">word</property>
+                        <property name="use-underline">1</property>
+                        <property name="mnemonic-widget">category_combo</property>
+                        <property name="label" translatable="yes">_Meal</property>
+                        <property name="xalign">1</property>
+                        <style> <class name="dim-label"/> </style>
                       </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">1</property>
+                      </packing>
                     </child>
-                  </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">5</property>
-                    <property name="width">2</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">1</property>
-                    <property name="use-underline">1</property>
-                    <property name="mnemonic-widget">prep_time_combo</property>
-                    <property name="label" translatable="yes">_Preparation time</property>
-                    <property name="xalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">6</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">1</property>
-                    <property name="use-underline">1</property>
-                    <property name="mnemonic-widget">cook_time_combo</property>
-                    <property name="label" translatable="yes">C_ooking time</property>
-                    <property name="xalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="left-attach">1</property>
-                    <property name="top-attach">6</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkComboBoxText" id="prep_time_combo">
-                    <property name="visible">1</property>
-                    <property name="has-entry">1</property>
-                    <items>
-                      <item translatable="yes" id="Less than 15 minutes">Less than 15 minutes</item>
-                      <item translatable="yes" id="15 to 30 minutes">15 to 30 minutes</item>
-                      <item translatable="yes" id="30 to 45 minutes">30 to 45 minutes</item>
-                      <item translatable="yes" id="45 minutes to an hour">45 minutes to an hour</item>
-                      <item translatable="yes" id="More than an hour">More than an hour</item>
-                    </items>
-                  </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">7</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkComboBoxText" id="cook_time_combo">
-                    <property name="visible">1</property>
-                    <property name="has-entry">1</property>
-                    <items>
-                      <item translatable="yes" id="Less than 15 minutes">Less than 15 minutes</item>
-                      <item translatable="yes" id="15 to 30 minutes">15 to 30 minutes</item>
-                      <item translatable="yes" id="30 to 45 minutes">30 to 45 minutes</item>
-                      <item translatable="yes" id="45 minutes to an hour">45 minutes to an hour</item>
-                      <item translatable="yes" id="More than an hour">More than an hour</item>
-                    </items>
-                  </object>
-                  <packing>
-                    <property name="left-attach">1</property>
-                    <property name="top-attach">7</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">1</property>
-                    <property name="use-underline">1</property>
-                    <property name="mnemonic-widget">cuisine_combo</property>
-                    <property name="label" translatable="yes">_Cuisine</property>
-                    <property name="xalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">8</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">1</property>
-                    <property name="use-underline">1</property>
-                    <property name="mnemonic-widget">category_combo</property>
-                    <property name="label" translatable="yes">_Meal</property>
-                    <property name="xalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="left-attach">1</property>
-                    <property name="top-attach">8</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkComboBoxText" id="cuisine_combo">
-                    <property name="visible">1</property>
-                    <property name="has-entry">1</property>
-                  </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">9</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkComboBoxText" id="category_combo">
-                    <property name="visible">1</property>
-                    <property name="has-entry">1</property>
-                  </object>
-                  <packing>
-                    <property name="left-attach">1</property>
-                    <property name="top-attach">9</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">1</property>
-                    <property name="use-underline">1</property>
-                    <property name="mnemonic-widget">season_combo</property>
-                    <property name="label" translatable="yes">S_eason</property>
-                    <property name="xalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">10</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">1</property>
-                    <property name="use-underline">1</property>
-                    <property name="mnemonic-widget">spiciness_combo</property>
-                    <property name="label" translatable="yes">S_piciness</property>
-                    <property name="xalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="left-attach">1</property>
-                    <property name="top-attach">10</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkComboBoxText" id="season_combo">
-                    <property name="visible">1</property>
-                    <property name="has-entry">1</property>
-                  </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">11</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkComboBoxText" id="spiciness_combo">
-                    <property name="visible">1</property>
-                    <items>
-                      <item translatable="yes" id="mild">Mild</item>
-                      <item translatable="yes" id="spicy">Somewhat spicy</item>
-                      <item translatable="yes" id="hot">Hot</item>
-                      <item translatable="yes" id="extreme">Very spicy</item>
-                    </items>
-                  </object>
-                  <packing>
-                    <property name="left-attach">1</property>
-                    <property name="top-attach">11</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">1</property>
-                    <property name="use-underline">1</property>
-                    <property name="mnemonic-widget">ingredients_field</property>
-                    <property name="label" translatable="yes">_Ingredients</property>
-                    <property name="xalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">12</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkScrolledWindow">
-                    <property name="visible">1</property>
-                    <property name="shadow-type">in</property>
-                    <property name="min-content-height">120</property>
                     <child>
-                      <object class="GtkTextView" id="ingredients_field">
+                      <object class="GtkComboBoxText" id="cuisine_combo">
                         <property name="visible">1</property>
-                        <property name="wrap-mode">word</property>
+                        <property name="has-entry">1</property>
                       </object>
+                      <packing>
+                        <property name="left-attach">1</property>
+                        <property name="top-attach">0</property>
+                      </packing>
                     </child>
-                  </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">13</property>
-                    <property name="width">2</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkBox">
-                    <property name="visible">1</property>
                     <child>
-                      <object class="GtkCheckButton" id="gluten_free_check">
+                      <object class="GtkComboBoxText" id="category_combo">
                         <property name="visible">1</property>
-                        <property name="label" translatable="yes">Gluten free</property>
+                        <property name="has-entry">1</property>
                       </object>
+                      <packing>
+                        <property name="left-attach">1</property>
+                        <property name="top-attach">1</property>
+                      </packing>
                     </child>
                     <child>
-                      <object class="GtkCheckButton" id="nut_free_check">
+                      <object class="GtkLabel">
                         <property name="visible">1</property>
-                        <property name="label" translatable="yes">Nut free</property>
+                        <property name="use-underline">1</property>
+                        <property name="mnemonic-widget">season_combo</property>
+                        <property name="label" translatable="yes">S_eason</property>
+                        <property name="xalign">1</property>
+                        <style> <class name="dim-label"/> </style>
                       </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">2</property>
+                      </packing>
                     </child>
                     <child>
-                      <object class="GtkCheckButton" id="vegan_check">
+                      <object class="GtkLabel">
                         <property name="visible">1</property>
-                        <property name="label" translatable="yes">Vegan</property>
+                        <property name="use-underline">1</property>
+                        <property name="mnemonic-widget">spiciness_combo</property>
+                        <property name="label" translatable="yes">S_piciness</property>
+                        <property name="xalign">1</property>
+                        <style> <class name="dim-label"/> </style>
                       </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">3</property>
+                      </packing>
                     </child>
                     <child>
-                      <object class="GtkCheckButton" id="vegetarian_check">
+                      <object class="GtkComboBoxText" id="season_combo">
                         <property name="visible">1</property>
-                        <property name="label" translatable="yes">Vegetarian</property>
+                        <property name="has-entry">1</property>
                       </object>
+                      <packing>
+                        <property name="left-attach">1</property>
+                        <property name="top-attach">2</property>
+                      </packing>
                     </child>
                     <child>
-                      <object class="GtkCheckButton" id="milk_free_check">
+                      <object class="GtkComboBoxText" id="spiciness_combo">
                         <property name="visible">1</property>
-                        <property name="label" translatable="yes">Milk free</property>
+                        <items>
+                          <item translatable="yes" id="mild">Mild</item>
+                          <item translatable="yes" id="spicy">Somewhat spicy</item>
+                          <item translatable="yes" id="hot">Hot</item>
+                          <item translatable="yes" id="extreme">Very spicy</item>
+                        </items>
                       </object>
+                      <packing>
+                        <property name="left-attach">1</property>
+                        <property name="top-attach">3</property>
+                      </packing>
                     </child>
                   </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">14</property>
-                    <property name="width">2</property>
-                  </packing>
                 </child>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">1</property>
-                    <property name="use-underline">1</property>
-                    <property name="mnemonic-widget">instructions_field</property>
-                    <property name="label" translatable="yes">Instr_uctions</property>
-                    <property name="xalign">0</property>
                   </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">15</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkScrolledWindow">
+                  <object class="GtkGrid">
                     <property name="visible">1</property>
-                    <property name="shadow-type">in</property>
-                    <property name="min-content-height">120</property>
+                    <property name="halign">start</property>
+                    <property name="valign">start</property>
+                    <property name="row-spacing">20</property>
+                    <property name="column-spacing">40</property>
                     <child>
-                      <object class="GtkTextView" id="instructions_field">
+                      <object class="GtkLabel">
                         <property name="visible">1</property>
-                        <property name="wrap-mode">word</property>
+                        <property name="label" translatable="yes">Details</property>
+                        <property name="xalign">0</property>
+                        <style> <class name="heading"/> </style>
                       </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">-1</property>
+                        <property name="width">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">1</property>
+                        <property name="use-underline">1</property>
+                        <property name="mnemonic-widget">name_entry</property>
+                        <property name="label" translatable="yes">_Name your recipe</property>
+                        <property name="xalign">1</property>
+                        <property name="halign">fill</property>
+                        <style> <class name="dim-label"/> </style>
+                      </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">0</property>
+                      </packing>
                     </child>
-                  </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">16</property>
-                    <property name="width">2</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">1</property>
-                    <property name="use-underline">1</property>
-                    <property name="mnemonic-widget">notes_field</property>
-                    <property name="label" translatable="yes">_Additional notes</property>
-                    <property name="xalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">17</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkScrolledWindow">
-                    <property name="visible">1</property>
-                    <property name="shadow-type">in</property>
-                    <property name="min-content-height">120</property>
                     <child>
-                      <object class="GtkTextView" id="notes_field">
+                      <object class="GtkEntry" id="name_entry">
                         <property name="visible">1</property>
-                        <property name="wrap-mode">word</property>
+                        <property name="hexpand">1</property>
+                      </object>
+                      <packing>
+                        <property name="left-attach">1</property>
+                        <property name="top-attach">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">1</property>
+                        <property name="use-underline">1</property>
+                        <property name="mnemonic-widget">serves_spin</property>
+                        <property name="label" translatable="yes">Ser_ves</property>
+                        <property name="xalign">1</property>
+                        <style> <class name="dim-label"/> </style>
+                      </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="serves_spin">
+                        <property name="visible">1</property>
+                        <property name="adjustment">serves_adjustment</property>
+                        <property name="halign">start</property>
                       </object>
+                      <packing>
+                        <property name="left-attach">1</property>
+                        <property name="top-attach">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">1</property>
+                        <property name="use-underline">1</property>
+                        <property name="mnemonic-widget">prep_time_combo</property>
+                        <property name="label" translatable="yes">_Preparation time</property>
+                        <property name="xalign">1</property>
+                        <style> <class name="dim-label"/> </style>
+                      </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">1</property>
+                        <property name="use-underline">1</property>
+                        <property name="mnemonic-widget">cook_time_combo</property>
+                        <property name="label" translatable="yes">C_ooking time</property>
+                        <property name="xalign">1</property>
+                        <style> <class name="dim-label"/> </style>
+                      </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">3</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkComboBoxText" id="prep_time_combo">
+                        <property name="visible">1</property>
+                        <property name="has-entry">1</property>
+                        <property name="halign">fill</property>
+                        <items>
+                          <item translatable="yes" id="Less than 15 minutes">Less than 15 minutes</item>
+                          <item translatable="yes" id="15 to 30 minutes">15 to 30 minutes</item>
+                          <item translatable="yes" id="30 to 45 minutes">30 to 45 minutes</item>
+                          <item translatable="yes" id="45 minutes to an hour">45 minutes to an hour</item>
+                          <item translatable="yes" id="More than an hour">More than an hour</item>
+                        </items>
+                      </object>
+                      <packing>
+                        <property name="left-attach">1</property>
+                        <property name="top-attach">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkComboBoxText" id="cook_time_combo">
+                        <property name="visible">1</property>
+                        <property name="has-entry">1</property>
+                        <property name="halign">fill</property>
+                        <items>
+                          <item translatable="yes" id="Less than 15 minutes">Less than 15 minutes</item>
+                          <item translatable="yes" id="15 to 30 minutes">15 to 30 minutes</item>
+                          <item translatable="yes" id="30 to 45 minutes">30 to 45 minutes</item>
+                          <item translatable="yes" id="45 minutes to an hour">45 minutes to an hour</item>
+                          <item translatable="yes" id="More than an hour">More than an hour</item>
+                        </items>
+                      </object>
+                      <packing>
+                        <property name="left-attach">1</property>
+                        <property name="top-attach">3</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">1</property>
+                        <property name="label" translatable="yes">Directions</property>
+                        <property name="xalign">0</property>
+                        <style> <class name="heading"/> </style>
+                      </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">15</property>
+                        <property name="width">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkScrolledWindow">
+                        <property name="visible">1</property>
+                        <property name="shadow-type">in</property>
+                        <property name="min-content-height">360</property>
+                        <child>
+                          <object class="GtkTextView" id="instructions_field">
+                            <property name="visible">1</property>
+                            <property name="wrap-mode">word</property>
+                            <property name="top-margin">10</property>
+                            <property name="left-margin">10</property>
+                            <property name="right-margin">10</property>
+                            <property name="bottom-margin">10</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">16</property>
+                        <property name="width">2</property>
+                      </packing>
                     </child>
                   </object>
-                  <packing>
-                    <property name="left-attach">0</property>
-                    <property name="top-attach">18</property>
-                    <property name="width">2</property>
-                  </packing>
                 </child>
               </object>
             </child>
@@ -590,4 +656,74 @@
       </object>
     </child>
   </template>
+  <object class="GtkPopover" id="ingredient_popover">
+    <property name="relative-to">add_ingredient_button</property>
+    <property name="position">top</property>
+    <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">Name your ingredient</property>
+            <property name="xalign">0</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkEntry" id="new_ingredient_name">
+            <property name="visible">1</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">1</property>
+            <property name="label" translatable="yes">Amount</property>
+            <property name="xalign">0</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkSpinButton" id="new_ingredient_amount">
+            <property name="adjustment">amount_adjustment</property>
+            <property name="visible">1</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">1</property>
+            <property name="label" translatable="yes">Units</property>
+            <property name="xalign">0</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkComboBoxText" id="new_ingredient_unit">
+            <property name="visible">1</property>
+            <property name="has-entry">1</property>
+            <items>
+              <item id="g" translatable="yes">grams</item>
+              <item id="kg" translatable="yes">kilograms</item>
+              <item id="lb" translatable="yes">pounds</item>
+            </items>
+          </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" swapped="yes"/>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+  <object class="GtkAdjustment" id="amount_adjustment">
+    <property name="lower">0</property>
+    <property name="upper">1000</property>
+    <property name="page_size">0</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
 </interface>


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