[recipes] edit page: Use simple markup for instructions
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [recipes] edit page: Use simple markup for instructions
- Date: Wed, 1 Feb 2017 05:48:09 +0000 (UTC)
commit ed9455572fe1e7eee2430a23a2af0f8ff882711c
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Jan 31 19:57:20 2017 +0100
edit page: Use simple markup for instructions
This is a first attempt at structured editing for instructions,
with steps, images and timers.
We've lost support for recipe cross-references here, since they
don't work well with our new back button regime and the cooking
mode. Maybe they will come back in the description text at some
point.
src/gr-edit-page.c | 473 +++++++++++++++++----------------------------------
src/gr-edit-page.ui | 227 +++++++++++++++++--------
2 files changed, 316 insertions(+), 384 deletions(-)
---
diff --git a/src/gr-edit-page.c b/src/gr-edit-page.c
index d59b224..145c832 100644
--- a/src/gr-edit-page.c
+++ b/src/gr-edit-page.c
@@ -20,6 +20,8 @@
#include "config.h"
+#include <stdlib.h>
+
#include <glib/gi18n.h>
#include <gtk/gtk.h>
@@ -104,10 +106,11 @@ struct _GrEditPage
GtkWidget *recipe_popover;
GtkWidget *recipe_list;
GtkWidget *recipe_filter_entry;
- GtkWidget *add_recipe_button;
GtkWidget *link_image_button;
GtkWidget *image_popover;
GtkWidget *image_flowbox;
+ GtkWidget *timer_popover;
+ GtkWidget *timer_spin;
GrRecipeSearch *search;
@@ -159,8 +162,6 @@ populate_image_flowbox (GrEditPage *page)
}
}
-static void update_link_button_sensitivity (GrEditPage *page);
-
static void
update_image_button_sensitivity (GrEditPage *page)
{
@@ -208,7 +209,6 @@ static void
images_changed (GrEditPage *page)
{
update_image_button_sensitivity (page);
- update_link_button_sensitivity (page);
populate_image_flowbox (page);
update_default_button (page);
}
@@ -909,360 +909,207 @@ populate_units_list (GrEditPage *self)
G_CALLBACK (unit_row_activated), self);
}
-static gboolean
-recipe_filter_func (GtkListBoxRow *row,
- gpointer data)
-{
- GrEditPage *self = data;
- const char *cf;
- GrRecipe *r;
-
- if (!self->recipe_term)
- return TRUE;
-
- r = GR_RECIPE (g_object_get_data (G_OBJECT (row), "recipe"));
-
- if (self->recipe && strcmp (gr_recipe_get_id (r), gr_recipe_get_id (self->recipe)) == 0)
- return FALSE;
-
- cf = (const char *)g_object_get_data (G_OBJECT (row), "term");
-
- return g_str_has_prefix (cf, self->recipe_term);
-}
-
static void
-recipe_filter_changed (GrEditPage *self)
+remove_tag_if_found (GtkTextBuffer *buffer)
{
- const char *term;
-
- term = gtk_entry_get_text (GTK_ENTRY (self->recipe_filter_entry));
- g_free (self->recipe_term);
- self->recipe_term = g_utf8_casefold (term, -1);
- gtk_list_box_invalidate_filter (GTK_LIST_BOX (self->recipe_list));
-}
+ GtkTextIter start, end;
+ g_autofree char *text = NULL;
-static void
-recipe_filter_stop (GrEditPage *self)
-{
+ gtk_text_buffer_get_iter_at_mark (buffer, &start, gtk_text_buffer_get_insert (buffer));
+ gtk_text_iter_set_line_offset (&start, 0);
+ end = start;
+ gtk_text_iter_forward_to_line_end (&end);
+ text = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
+ if (g_str_has_prefix (text, "[image:") ||
+ g_str_has_prefix (text, "[timer:")) {
+ char *p = strstr (text, "]");
+ gtk_text_iter_set_line_index (&end, p - text + 1);
+ gtk_text_buffer_delete (buffer, &start, &end);
+ }
}
static void
-recipe_row_activated (GtkListBox *list,
- GtkListBoxRow *row,
- GrEditPage *self)
+add_tag_to_step (GrEditPage *self,
+ const char *tag)
{
- GrRecipe *recipe;
- const char *id;
- const char *name;
- g_autofree char *url = NULL;
GtkTextBuffer *buffer;
- GtkTextIter start, end;
- GtkTextTag *tag;
- GdkRGBA color;
- GtkStateFlags state = gtk_widget_get_state_flags (GTK_WIDGET (self->instructions_field));
- GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET (self->instructions_field));
-
- gtk_style_context_get_color (context, state | GTK_STATE_FLAG_LINK, &color);
-
- recipe = GR_RECIPE (g_object_get_data (G_OBJECT (row), "recipe"));
- id = gr_recipe_get_id (recipe);
- name = gr_recipe_get_name (recipe);
+ GtkTextIter start;
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->instructions_field));
- tag = gtk_text_buffer_create_tag (buffer, NULL,
- "foreground-rgba", &color,
- "underline", PANGO_UNDERLINE_SINGLE,
- NULL);
- url = g_strconcat ("recipe:", id, NULL);
- g_object_set_data_full (G_OBJECT (tag), "href", g_strdup (url), g_free);
-
- gtk_text_buffer_get_iter_at_mark (buffer, &start,
- gtk_text_buffer_get_insert (buffer));
- gtk_text_buffer_get_iter_at_mark (buffer, &end,
- gtk_text_buffer_get_mark (buffer, "saved_selection_bound"));
- gtk_text_buffer_delete (buffer, &start, &end);
- gtk_text_buffer_insert (buffer, &start, "", -1);
- gtk_text_buffer_get_iter_at_mark (buffer, &start,
- gtk_text_buffer_get_insert (buffer));
- gtk_text_buffer_insert_with_tags (buffer, &start, name, -1, tag, NULL);
-
- gtk_popover_popdown (GTK_POPOVER (self->recipe_popover));
- gtk_entry_set_text (GTK_ENTRY (self->recipe_filter_entry), "");
+ remove_tag_if_found (buffer);
- gtk_widget_grab_focus (self->instructions_field);
+ gtk_text_buffer_get_iter_at_mark (buffer, &start, gtk_text_buffer_get_insert (buffer));
+ gtk_text_iter_set_line_offset (&start, 0);
+
+ gtk_text_buffer_insert (buffer, &start, tag, -1);
}
static void
-recipe_filter_activated (GrEditPage *self)
+image_activated (GtkFlowBox *flowbox,
+ GtkFlowBoxChild *child,
+ GrEditPage *self)
{
- GtkListBoxRow *row;
+ int idx;
+ g_autofree char *text = NULL;
- row = gtk_list_box_get_row_at_index (GTK_LIST_BOX (self->recipe_list), 0);
- if (row) {
- recipe_row_activated (GTK_LIST_BOX (self->recipe_list), row, self);
- }
-}
+ idx = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (child), "image-idx"));
+ text = g_strdup_printf ("[image:%d]", idx);
+ add_tag_to_step (self, text);
-static void
-search_started (GrRecipeSearch *search,
- GrEditPage *page)
-{
+ gtk_popover_popdown (GTK_POPOVER (self->image_popover));
+ gtk_widget_grab_focus (self->instructions_field);
}
static void
-search_hits_added (GrRecipeSearch *search,
- GList *hits,
- GrEditPage *page)
+add_image_link (GtkButton *button, GrEditPage *page)
{
- GList *l;
- GrRecipeStore *store;
-
- store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
-
- for (l = hits; l; l = l->next) {
- GrRecipe *recipe = l->data;
- GtkWidget *box;
- GtkWidget *label;
- GtkWidget *row;
- const char *author;
- char *tmp;
- g_autoptr(GrChef) chef = NULL;
-
- box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 20);
- gtk_widget_show (box);
- g_object_set (box,
- "margin-start", 20,
- "margin-end", 20,
- "margin-top", 10,
- "margin-bottom", 10,
- NULL);
-
- label = gtk_label_new (gr_recipe_get_name (recipe));
- gtk_label_set_xalign (GTK_LABEL (label), 0.0);
- gtk_widget_show (label);
- gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
-
- store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
- author = gr_recipe_get_author (recipe);
- chef = gr_recipe_store_get_chef (store, author ? author : "");
- if (chef) {
- tmp = g_strdup_printf (_("by %s"), gr_chef_get_name (chef));
- label = gtk_label_new (tmp);
- g_free (tmp);
- gtk_label_set_xalign (GTK_LABEL (label), 1.0);
- gtk_widget_show (label);
- gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label");
- gtk_box_pack_start (GTK_BOX (box), label, FALSE, TRUE, 0);
- }
-
- gtk_container_add (GTK_CONTAINER (page->recipe_list), box);
- row = gtk_widget_get_parent (box);
- g_object_set_data_full (G_OBJECT (row), "recipe", g_object_ref (recipe), g_object_unref);
- g_object_set_data_full (G_OBJECT (row), "term", g_utf8_casefold (gr_recipe_get_name
(recipe), -1), g_free);
- }
+ gtk_popover_popup (GTK_POPOVER (page->image_popover));
}
-static void
-search_hits_removed (GrRecipeSearch *search,
- GList *hits,
- GrEditPage *page)
+static int
+time_spin_input (GtkSpinButton *spin_button,
+ double *new_val)
{
- GList *children, *l;
-
- children = gtk_container_get_children (GTK_CONTAINER (page->recipe_list));
- for (l = children; l; l = l->next) {
- GtkWidget *row = l->data;
- GrRecipe *recipe;
-
- recipe = GR_RECIPE (g_object_get_data (G_OBJECT (row), "recipe"));
- if (g_list_find (hits, recipe)) {
- gtk_container_remove (GTK_CONTAINER (page->recipe_list), row);
+ const char *text;
+ gboolean found = FALSE;
+
+ text = gtk_entry_get_text (GTK_ENTRY (spin_button));
+ if (!strchr (text, ':')) {
+ g_auto(GStrv) str = NULL;
+ int num;
+ char *endn;
+
+ str = g_strsplit (text, " ", 2);
+ num = strtol (str[0], &endn, 10);
+ if (!*endn) {
+ if (str[1] == NULL) {
+ *new_val = num; /* minutes */
+ found = TRUE;
+ }
+ else if (strcmp (str[1], _("hour")) == 0 ||
+ strcmp (str[1], _("hours")) == 0 ||
+ strcmp (str[1], C_("hour abbreviation", "h")) == 0) {
+ *new_val = num * 3600; /* hours */
+ found = TRUE;
+ }
+ else if (strcmp (str[1], _("minute")) == 0 ||
+ strcmp (str[1], _("minutes")) == 0 ||
+ strcmp (str[1], C_("minute abbreviation", "min")) == 0 ||
+ strcmp (str[1], C_("minute abbreviation", "m")) == 0) {
+ *new_val = num * 60;
+ found = TRUE;
+ }
+ else if (strcmp (str[1], _("second")) == 0 ||
+ strcmp (str[1], _("seconds")) == 0 ||
+ strcmp (str[1], C_("second abbreviation", "sec")) == 0 ||
+ strcmp (str[1], C_("second abbreviation", "s")) == 0) {
+ *new_val = num;
+ found = TRUE;
+ }
}
}
-}
-
-static void
-search_finished (GrRecipeSearch *search,
- GrEditPage *page)
-{
-}
-
-static void
-update_link_button_sensitivity (GrEditPage *page)
-{
- GtkTextBuffer *buffer;
- GtkTextIter iter;
- GSList *tags, *s;
- gboolean in_link = FALSE;
- g_autoptr(GArray) images = NULL;
- int length;
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (page->instructions_field));
-
- gtk_text_buffer_get_iter_at_mark (buffer, &iter,
- gtk_text_buffer_get_insert (buffer));
-
- tags = gtk_text_iter_get_tags (&iter);
- for (s = tags; s; s = s->next) {
- GtkTextTag *tag = s->data;
-
- if (g_object_get_data (G_OBJECT (tag), "href") != NULL) {
- in_link = TRUE;
- break;
+ else {
+ g_auto(GStrv) str = NULL;
+ int hours;
+ int minutes;
+ int seconds;
+ char *endh;
+ char *endm;
+ char *ends;
+
+ str = g_strsplit (text, ":", 3);
+
+ if (g_strv_length (str) == 3) {
+ hours = strtol (str[0], &endh,10);
+ minutes = strtol (str[1], &endm, 10);
+ seconds = strtol (str[2], &ends, 10);
+ if (!*endh && !*endm && !*ends &&
+ 0 <= hours && hours < 24 &&
+ 0 <= minutes && minutes < 60 &&
+ 0 <= seconds && seconds < 60) {
+ *new_val = (hours * 60 + minutes) * 60 + seconds;
+ found = TRUE;
+ }
+ }
+ else if (g_strv_length (str) == 2) {
+ hours = strtol (str[0], &endh, 10);
+ minutes = strtol (str[1], &endm, 10);
+ if (!*endh && !*endm &&
+ 0 <= hours && hours < 24 &&
+ 0 <= minutes && minutes < 60) {
+ *new_val = (hours * 60 + minutes) * 60;
+ found = TRUE;
+ }
}
-
}
- g_slist_free (tags);
- g_object_get (page->images, "images", &images, NULL);
- length = images->len;
-
- gtk_widget_set_sensitive (page->add_recipe_button, !in_link);
- gtk_widget_set_sensitive (page->link_image_button, !in_link && (length > 1));
-}
+ if (!found) {
+ *new_val = 0.0;
+ return GTK_INPUT_ERROR;
+ }
-static void
-cursor_moved (GObject *object,
- GParamSpec *pspec,
- GrEditPage *page)
-{
- update_link_button_sensitivity (page);
+ return TRUE;
}
-static void
-populate_recipe_list (GrEditPage *self)
-{
- GtkTextBuffer *buffer;
- GtkTextIter iter;
-
- gtk_list_box_set_header_func (GTK_LIST_BOX (self->recipe_list),
- all_headers, self, NULL);
-
- gtk_list_box_set_filter_func (GTK_LIST_BOX (self->recipe_list),
- recipe_filter_func, self, NULL);
-
- g_signal_connect (self->recipe_list, "row-activated",
- G_CALLBACK (recipe_row_activated), self);
-
- self->search = gr_recipe_search_new ();
- g_signal_connect (self->search, "started", G_CALLBACK (search_started), self);
- g_signal_connect (self->search, "hits-added", G_CALLBACK (search_hits_added), self);
- g_signal_connect (self->search, "hits-removed", G_CALLBACK (search_hits_removed), self);
- g_signal_connect (self->search, "finished", G_CALLBACK (search_finished), self);
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->instructions_field));
- g_signal_connect (buffer, "notify::cursor-position", G_CALLBACK (cursor_moved), self);
+static int
+time_spin_output (GtkSpinButton *spin_button)
+{
+ GtkAdjustment *adjustment;
+ double hours;
+ double minutes;
+ double seconds;
+ g_autofree char *buf = NULL;
+
+ adjustment = gtk_spin_button_get_adjustment (spin_button);
+ hours = gtk_adjustment_get_value (adjustment) / 3600.0;
+ minutes = (hours - floor (hours)) * 60.0;
+ seconds = (minutes - floor (minutes)) * 60.0;
+ buf = g_strdup_printf ("%02.0f:%02.0f:%02.0f", floor (hours), floor (minutes), floor (seconds +
0.5));
+ if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
+ gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
- gtk_text_buffer_get_start_iter (buffer, &iter);
- gtk_text_buffer_create_mark (buffer, "saved_selection_bound", &iter, TRUE);
+ return TRUE;
}
static void
-add_recipe_link (GtkButton *button, GrEditPage *page)
+time_spin_activate (GtkEntry *entry, GrEditPage *self)
{
- GtkTextBuffer *buffer;
- GtkTextIter start, end;
-
- if (gtk_list_box_get_row_at_index (GTK_LIST_BOX (page->recipe_list), 0) == NULL) {
- gr_recipe_search_stop (page->search);
- gr_recipe_search_set_query (page->search, "na:");
- }
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (page->instructions_field));
-
- gtk_text_buffer_get_iter_at_mark (buffer, &start, gtk_text_buffer_get_selection_bound (buffer));
- gtk_text_buffer_move_mark_by_name (buffer, "saved_selection_bound", &start);
+ GtkAdjustment *adjustment;
+ double hours;
+ double minutes;
+ double seconds;
+ g_autofree char *text = NULL;
- if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end)) {
- g_autofree char *text = NULL;
+ gtk_spin_button_update (GTK_SPIN_BUTTON (entry));
- text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
- gtk_entry_set_text (GTK_ENTRY (page->recipe_filter_entry), text);
- }
- else
- gtk_entry_set_text (GTK_ENTRY (page->recipe_filter_entry), "");
+ adjustment = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (entry));
+ hours = gtk_adjustment_get_value (adjustment) / 3600.0;
+ minutes = (hours - floor (hours)) * 60.0;
+ seconds = (minutes - floor (minutes)) * 60.0;
- gtk_popover_popup (GTK_POPOVER (page->recipe_popover));
-}
+ text = g_strdup_printf ("[timer:%02.0f:%02.0f:%02.0f]", floor (hours), floor (minutes), floor
(seconds + 0.5));
+ add_tag_to_step (self, text);
-static void
-recipe_reload (GrEditPage *page)
-{
- container_remove_all (GTK_CONTAINER (page->recipe_list));
+ gtk_popover_popdown (GTK_POPOVER (self->timer_popover));
+ gtk_widget_grab_focus (self->instructions_field);
}
static void
-connect_store_signals (GrEditPage *page)
+add_timer (GtkButton *button, GrEditPage *page)
{
- GrRecipeStore *store;
-
- store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
-
- g_signal_connect_swapped (store, "recipe-added", G_CALLBACK (recipe_reload), page);
- g_signal_connect_swapped (store, "recipe-removed", G_CALLBACK (recipe_reload), page);
- g_signal_connect_swapped (store, "recipe-changed", G_CALLBACK (recipe_reload), page);
+ gtk_popover_popup (GTK_POPOVER (page->timer_popover));
}
static void
-image_activated (GtkFlowBox *flowbox,
- GtkFlowBoxChild *child,
- GrEditPage *self)
+add_step (GtkButton *button, GrEditPage *self)
{
- int idx;
GtkTextBuffer *buffer;
- GtkTextIter start, end;
- GtkTextTag *tag;
- GdkRGBA color;
- g_autofree char *url = NULL;
- g_autofree char *text = NULL;
-
- gdk_rgba_parse (&color, "blue");
-
- idx = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (child), "image-idx"));
+ GtkTextIter end;
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->instructions_field));
- tag = gtk_text_buffer_create_tag (buffer, NULL,
- "foreground-rgba", &color,
- "underline", PANGO_UNDERLINE_SINGLE,
- NULL);
- url = g_strdup_printf ("image:%d", idx);
- g_object_set_data_full (G_OBJECT (tag), "href", g_strdup (url), g_free);
-
- gtk_text_buffer_get_iter_at_mark (buffer, &start,
- gtk_text_buffer_get_insert (buffer));
- gtk_text_buffer_get_iter_at_mark (buffer, &end,
- gtk_text_buffer_get_mark (buffer, "saved_selection_bound"));
- text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
- gtk_text_buffer_delete (buffer, &start, &end);
- gtk_text_buffer_insert (buffer, &start, "", -1);
-
- if (text[0] == '\0') {
- char buf[6];
- int len;
-
- len = g_unichar_to_utf8 (0x2460 + idx, buf);
- text = g_strndup (buf, len);
- }
-
- gtk_text_buffer_get_iter_at_mark (buffer, &start,
- gtk_text_buffer_get_insert (buffer));
- gtk_text_buffer_insert_with_tags (buffer, &start, text, -1, tag, NULL);
-
- gtk_popover_popdown (GTK_POPOVER (self->image_popover));
- gtk_widget_grab_focus (self->instructions_field);
-}
-
-static void
-add_image_link (GtkButton *button, GrEditPage *page)
-{
- GtkTextBuffer *buffer;
- GtkTextIter iter;
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (page->instructions_field));
- gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_selection_bound (buffer));
- gtk_text_buffer_move_mark_by_name (buffer, "saved_selection_bound", &iter);
-
- gtk_popover_popup (GTK_POPOVER (page->image_popover));
+ gtk_text_buffer_get_end_iter (buffer, &end);
+ gtk_text_buffer_place_cursor (buffer, &end);
+ gtk_text_buffer_insert_at_cursor (buffer, "\n\n", 2);
}
static void update_author_label (GrEditPage *page,
@@ -1316,8 +1163,6 @@ gr_edit_page_init (GrEditPage *page)
populate_season_combo (page);
populate_ingredients_list (page);
populate_units_list (page);
- populate_recipe_list (page);
- connect_store_signals (page);
#ifdef ENABLE_GSPELL
{
@@ -1419,13 +1264,11 @@ gr_edit_page_class_init (GrEditPageClass *klass)
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, recipe_popover);
- gtk_widget_class_bind_template_child (widget_class, GrEditPage, recipe_list);
- gtk_widget_class_bind_template_child (widget_class, GrEditPage, recipe_filter_entry);
- gtk_widget_class_bind_template_child (widget_class, GrEditPage, add_recipe_button);
gtk_widget_class_bind_template_child (widget_class, GrEditPage, link_image_button);
gtk_widget_class_bind_template_child (widget_class, GrEditPage, image_popover);
gtk_widget_class_bind_template_child (widget_class, GrEditPage, image_flowbox);
+ gtk_widget_class_bind_template_child (widget_class, GrEditPage, timer_popover);
+ gtk_widget_class_bind_template_child (widget_class, GrEditPage, timer_spin);
gtk_widget_class_bind_template_callback (widget_class, dismiss_error);
gtk_widget_class_bind_template_callback (widget_class, add_image);
@@ -1448,15 +1291,17 @@ gr_edit_page_class_init (GrEditPageClass *klass)
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_recipe_link);
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);
gtk_widget_class_bind_template_callback (widget_class, image_activated);
- gtk_widget_class_bind_template_callback (widget_class, recipe_filter_changed);
- gtk_widget_class_bind_template_callback (widget_class, recipe_filter_stop);
- gtk_widget_class_bind_template_callback (widget_class, recipe_filter_activated);
gtk_widget_class_bind_template_callback (widget_class, set_default_image);
gtk_widget_class_bind_template_callback (widget_class, edit_chef);
+
+ gtk_widget_class_bind_template_callback (widget_class, time_spin_input);
+ gtk_widget_class_bind_template_callback (widget_class, time_spin_output);
+ gtk_widget_class_bind_template_callback (widget_class, time_spin_activate);
}
GtkWidget *
diff --git a/src/gr-edit-page.ui b/src/gr-edit-page.ui
index b2086e7..96973aa 100644
--- a/src/gr-edit-page.ui
+++ b/src/gr-edit-page.ui
@@ -631,13 +631,37 @@
</packing>
</child>
<child>
- <object class="GtkLabel">
+ <object class="GtkBox">
<property name="visible">1</property>
- <property name="label" translatable="yes">Directions</property>
- <property name="xalign">0</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">4</property>
<style>
<class name="heading"/>
</style>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">1</property>
+ <property name="label" translatable="yes">Directions</property>
+ <property name="xalign">0</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="directions_help_button">
+ <property name="visible">1</property>
+ <property name="relief">none</property>
+ <property name="direction">up</property>
+ <property name="popover">directions_help_popover</property>
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">1</property>
+ <property name="icon-name">dialog-question-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
</object>
<packing>
<property name="left-attach">0</property>
@@ -671,47 +695,31 @@
<object class="GtkBox">
<property name="visible">1</property>
<property name="orientation">horizontal</property>
- <style>
- <class name="linked"/>
- </style>
+ <property name="margin-top">10</property>
+ <property name="spacing">10</property>
<child>
- <object class="GtkButton" id="add_recipe_button">
+ <object class="GtkButton" id="add_step_button">
<property name="visible">1</property>
<property name="halign">start</property>
- <property name="tooltip-text" translatable="yes">Add Recipe link</property>
- <property name="margin-top">10</property>
- <signal name="clicked" handler="add_recipe_link"/>
- <style>
- <class name="dim-label"/>
- <class name="image-button"/>
- </style>
- <child>
- <object class="GtkImage">
- <property name="visible">1</property>
- <property name="icon-name">insert-link-symbolic</property>
- <property name="icon-size">1</property>
- </object>
- </child>
+ <property name="focus-on-click">0</property>
+ <property name="label" translatable="yes">Add Step</property>
+ <signal name="clicked" handler="add_step"/>
</object>
</child>
<child>
<object class="GtkButton" id="link_image_button">
<property name="visible">1</property>
<property name="halign">start</property>
- <property name="tooltip-text" translatable="yes">Add Image link</property>
- <property name="margin-top">10</property>
+ <property name="label" translatable="yes">Add Image</property>
<signal name="clicked" handler="add_image_link"/>
- <style>
- <class name="dim-label"/>
- <class name="image-button"/>
- </style>
- <child>
- <object class="GtkImage">
- <property name="visible">1</property>
- <property name="icon-name">insert-image-symbolic</property>
- <property name="icon-size">1</property>
- </object>
- </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="timer_button">
+ <property name="visible">1</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes">Add Timer</property>
+ <signal name="clicked" handler="add_timer"/>
</object>
</child>
</object>
@@ -920,54 +928,133 @@
</object>
</child>
</object>
- <object class="GtkPopover" id="recipe_popover">
- <property name="relative-to">add_recipe_button</property>
+ <object class="GtkPopover" id="image_popover">
+ <property name="relative-to">link_image_button</property>
<property name="constrain-to">none</property>
<child>
- <object class="GtkBox">
+ <object class="GtkFlowBox" id="image_flowbox">
<property name="visible">1</property>
<property name="margin">12</property>
- <property name="spacing">12</property>
- <property name="orientation">vertical</property>
+ <property name="selection-mode">none</property>
+ <property name="min-children-per-line">5</property>
+ <property name="max-children-per-line">5</property>
+ <signal name="child-activated" handler="image_activated"/>
+ </object>
+ </child>
+ </object>
+ <object class="GtkAdjustment" id="time_adjustment">
+ <property name="upper">86400</property>
+ <property name="step-increment">60</property>
+ <property name="page-increment">900</property>
+ </object>
+ <object class="GtkPopover" id="timer_popover">
+ <property name="relative-to">timer_button</property>
+ <property name="constrain-to">none</property>
+ <child>
+ <object class="GtkSpinButton" id="timer_spin">
+ <property name="visible">1</property>
+ <property name="margin">12</property>
+ <property name="adjustment">time_adjustment</property>
+ <property name="width-chars">8</property>
+ <signal name="input" handler="time_spin_input"/>
+ <signal name="output" handler="time_spin_output"/>
+ <signal name="activate" handler="time_spin_activate"/>
+ </object>
+ </child>
+ </object>
+ <object class="GtkPopover" id="directions_help_popover">
+ <property name="relative-to">directions_help_button</property>
+ <property name="constrain-to">none</property>
+ <child>
+ <object class="GtkGrid">
+ <property name="visible">1</property>
+ <property name="margin">12</property>
+ <property name="margin-top">0</property>
+ <property name="column-homogeneous">1</property>
<child>
- <object class="GtkSearchEntry" id="recipe_filter_entry">
+ <object class="GtkLabel">
<property name="visible">1</property>
- <property name="placeholder-text" translatable="yes">Search…</property>
- <signal name="search-changed" handler="recipe_filter_changed" swapped="yes"/>
- <signal name="stop-search" handler="recipe_filter_stop" swapped="yes"/>
- <signal name="activate" handler="recipe_filter_activated" swapped="yes"/>
+ <property name="halign">center</property>
+ <property name="label" translatable="yes">Syntax</property>
+ <style>
+ <class name="heading"/>
+ </style>
</object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ <property name="width">2</property>
+ </packing>
</child>
<child>
- <object class="GtkScrolledWindow">
+ <object class="GtkLabel">
<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>
- <child>
- <object class="GtkListBox" id="recipe_list">
- <property name="visible">1</property>
- <property name="selection-mode">none</property>
- <property name="height-request">220</property>
- </object>
- </child>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Use paragraphs to break directions into steps (2
newlines).</property>
</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="xalign">0</property>
+ <property name="margin-bottom">10</property>
+ <property name="label" translatable="yes">You can provide an image or a time counter in each
step.</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">1</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Timer</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">1</property>
+ <property name="xalign">0</property>
+ <property name="label">[timer:00:30]</property>
+ </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="xalign">0</property>
+ <property name="label" translatable="yes">Image</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">1</property>
+ <property name="xalign">0</property>
+ <property name="label">[image:1]</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
</child>
- </object>
- </child>
- </object>
- <object class="GtkPopover" id="image_popover">
- <property name="relative-to">link_image_button</property>
- <property name="constrain-to">none</property>
- <child>
- <object class="GtkFlowBox" id="image_flowbox">
- <property name="visible">1</property>
- <property name="margin">12</property>
- <property name="selection-mode">none</property>
- <property name="min-children-per-line">5</property>
- <property name="max-children-per-line">5</property>
- <signal name="child-activated" handler="image_activated"/>
</object>
</child>
</object>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]