[recipes] Add a confirmation dialog for leaving cooking mode



commit 21d4534802706edcaf5938d099938bd498a7a5de
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Mar 10 18:36:38 2017 -0500

    Add a confirmation dialog for leaving cooking mode
    
    When there's timers running, we offer the user a choice
    whether to stay in cooking mode, keeping the timers running
    or stopping the timers.

 src/gr-cooking-page.c  |   92 ++++++++++++++++++++++++++++++++++++++++++------
 src/gr-cooking-page.ui |   74 ++++++++++++++++++++++++++++++++++++++
 src/gr-cooking-view.c  |   21 +++++++----
 src/gr-cooking-view.h  |    3 +-
 src/gr-edit-page.c     |    8 +---
 src/recipes.css        |   26 +++++++++++++
 6 files changed, 199 insertions(+), 25 deletions(-)
---
diff --git a/src/gr-cooking-page.c b/src/gr-cooking-page.c
index 8c0aabf..a7df7bd 100644
--- a/src/gr-cooking-page.c
+++ b/src/gr-cooking-page.c
@@ -48,6 +48,7 @@ struct _GrCookingPage
         GtkWidget *notification_revealer;
         GtkWidget *notification_label;
         GtkWidget *mini_timer_box;
+        GtkWidget *confirm_revealer;
         int notification_step;
 
         GrRecipe *recipe;
@@ -130,11 +131,9 @@ on_child_revealed (GrCookingPage *page)
 }
 
 static void
-hide_overlay (gpointer data,
-              gboolean fade)
+hide_overlay (GrCookingPage *page,
+              gboolean       fade)
 {
-        GrCookingPage *page = data;
-
         if (!fade)
                 gtk_revealer_set_transition_type (GTK_REVEALER (page->overlay_revealer), 
GTK_REVEALER_TRANSITION_TYPE_NONE);
         gtk_revealer_set_reveal_child (GTK_REVEALER (page->overlay_revealer), FALSE);
@@ -154,6 +153,70 @@ show_overlay (gpointer data)
 }
 
 static void
+on_confirm_revealed (GrCookingPage *page)
+{
+        if (!gtk_revealer_get_reveal_child (GTK_REVEALER (page->confirm_revealer)))
+                    gtk_widget_hide (page->confirm_revealer);
+}
+
+static void
+hide_confirm (GrCookingPage *page)
+{
+        gtk_revealer_set_reveal_child (GTK_REVEALER (page->confirm_revealer), FALSE);
+}
+
+static void
+show_confirm (GrCookingPage *page)
+{
+        gtk_widget_show (page->confirm_revealer);
+        gtk_revealer_set_reveal_child (GTK_REVEALER (page->confirm_revealer), TRUE);
+}
+
+static void
+leave_cooking_mode (GrCookingPage *page,
+                    gboolean       stop_timers)
+{
+        GtkWidget *window;
+        GtkApplication *app;
+
+        window = gtk_widget_get_ancestor (GTK_WIDGET (page), GTK_TYPE_APPLICATION_WINDOW);
+        app = gtk_window_get_application (GTK_WINDOW (window));
+
+        if (page->inhibit_cookie != 0) {
+                gtk_application_uninhibit (app, page->inhibit_cookie);
+                page->inhibit_cookie = 0;
+        }
+
+        gr_window_show_recipe (GR_WINDOW (window), page->recipe);
+        gr_cooking_view_stop (GR_COOKING_VIEW (page->cooking_view), FALSE);
+        gr_window_set_fullscreen (GR_WINDOW (window), FALSE);
+}
+
+static void
+confirm_close (GrCookingPage *page)
+{
+        show_confirm (page);
+}
+
+static void
+keep_cooking (GrCookingPage *page)
+{
+        hide_confirm (page);
+}
+
+static void
+stop_timers (GrCookingPage *page)
+{
+        leave_cooking_mode (page, TRUE);
+}
+
+static void
+continue_timers (GrCookingPage *page)
+{
+        leave_cooking_mode (page, FALSE);
+}
+
+static void
 set_cooking (GrCookingPage *page,
              gboolean       cooking)
 {
@@ -185,15 +248,17 @@ set_cooking (GrCookingPage *page,
                 gr_window_set_fullscreen (GR_WINDOW (window), TRUE);
         }
         else {
-                if (page->inhibit_cookie != 0) {
-                        gtk_application_uninhibit (app, page->inhibit_cookie);
-                        page->inhibit_cookie = 0;
-                }
+                GList *children;
+                gboolean has_timers;
 
-                gr_window_show_recipe (GR_WINDOW (window), page->recipe);
-                gr_cooking_view_stop (GR_COOKING_VIEW (page->cooking_view));
+                children = gtk_container_get_children (GTK_CONTAINER (page->mini_timer_box));
+                has_timers = children != NULL;
+                g_list_free (children);
 
-                gr_window_set_fullscreen (GR_WINDOW (window), FALSE);
+                if (has_timers)
+                        confirm_close (page);
+                else
+                        leave_cooking_mode (page, TRUE);
         }
 }
 
@@ -442,6 +507,7 @@ gr_cooking_page_class_init (GrCookingPageClass *klass)
         gtk_widget_class_bind_template_child (widget_class, GrCookingPage, notification_revealer);
         gtk_widget_class_bind_template_child (widget_class, GrCookingPage, notification_label);
         gtk_widget_class_bind_template_child (widget_class, GrCookingPage, mini_timer_box);
+        gtk_widget_class_bind_template_child (widget_class, GrCookingPage, confirm_revealer);
 
         gtk_widget_class_bind_template_callback (widget_class, prev_step);
         gtk_widget_class_bind_template_callback (widget_class, next_step);
@@ -450,6 +516,10 @@ gr_cooking_page_class_init (GrCookingPageClass *klass)
         gtk_widget_class_bind_template_callback (widget_class, close_notification);
         gtk_widget_class_bind_template_callback (widget_class, on_child_revealed);
         gtk_widget_class_bind_template_callback (widget_class, goto_timer);
+        gtk_widget_class_bind_template_callback (widget_class, on_confirm_revealed);
+        gtk_widget_class_bind_template_callback (widget_class, keep_cooking);
+        gtk_widget_class_bind_template_callback (widget_class, stop_timers);
+        gtk_widget_class_bind_template_callback (widget_class, continue_timers);
 }
 
 void
diff --git a/src/gr-cooking-page.ui b/src/gr-cooking-page.ui
index 45ac00f..666d468 100644
--- a/src/gr-cooking-page.ui
+++ b/src/gr-cooking-page.ui
@@ -165,6 +165,80 @@
           </object>
         </child>
         <child type="overlay">
+          <object class="GtkRevealer" id="confirm_revealer">
+            <property name="halign">center</property>
+            <property name="valign">center</property>
+            <property name="transition-type">crossfade</property>
+            <property name="transition-duration">1000</property>
+            <signal name="notify::child-revealed" handler="on_confirm_revealed" swapped="yes"/>
+            <child>
+              <object class="GtkBox" id="confirm_overlay">
+                <property name="visible">1</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">0</property>
+                <style>
+                  <class name="cooking"/>
+                  <class name="overlay"/>
+                  <class name="confirm"/>
+                </style>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">1</property>
+                    <property name="label" translatable="yes">Stop Cooking?</property>
+                    <style>
+                      <class name="heading"/>
+                    </style>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">1</property>
+                    <property name="xalign">0.5</property>
+                    <property name="label" translatable="yes">Some timers are still running.</property>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">1</property>
+                    <property name="xalign">0.5</property>
+                    <property name="label" translatable="yes">Recipes can keep the timers running
+even if you leave cooking mode now.</property>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkButtonBox">
+                    <property name="visible">1</property>
+                    <property name="halign">fill</property>
+                    <property name="valign">end</property>
+                    <property name="layout-style">expand</property>
+                    <child>
+                      <object class="GtkButton">
+                        <property name="visible">1</property>
+                        <property name="label" translatable="yes">Keep Cooking</property>
+                        <signal name="clicked" handler="keep_cooking" swapped="yes"/>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkButton">
+                        <property name="visible">1</property>
+                        <property name="label" translatable="yes">Stop Timers</property>
+                        <signal name="clicked" handler="stop_timers" swapped="yes"/>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkButton">
+                        <property name="visible">1</property>
+                        <property name="label" translatable="yes">Continue Timers</property>
+                        <signal name="clicked" handler="continue_timers" swapped="yes"/>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child type="overlay">
           <object class="GtkRevealer" id="overlay_revealer">
             <property name="halign">center</property>
             <property name="valign">center</property>
diff --git a/src/gr-cooking-view.c b/src/gr-cooking-view.c
index 9397076..a45e715 100644
--- a/src/gr-cooking-view.c
+++ b/src/gr-cooking-view.c
@@ -630,10 +630,9 @@ gr_cooking_view_start (GrCookingView *view)
 }
 
 void
-gr_cooking_view_stop (GrCookingView *view)
+gr_cooking_view_stop (GrCookingView *view,
+                      gboolean       stop_timers)
 {
-        GList *l;
-
         g_object_set (view->cooking_timer, "timer", NULL, NULL);
         if (view->timer_box)
                 container_remove_all (GTK_CONTAINER (view->timer_box));
@@ -642,10 +641,18 @@ gr_cooking_view_stop (GrCookingView *view)
         g_clear_pointer (&view->images, g_array_unref);
         g_ptr_array_set_size (view->steps, 0);
 
-        for (l = view->timers; l; l = l->next) {
-                GrTimer *timer = l->data;
-                TimerData *td = g_object_get_data (G_OBJECT (timer), "timer-data");
-                td->use_system = TRUE;
+        if (stop_timers) {
+                g_list_foreach (view->timers, (GFunc)gr_timer_reset, NULL);
+                g_list_free_full (view->timers, g_object_unref);
+                view->timers = NULL;
+        }
+        else {
+                GList *l;
+
+                for (l = view->timers; l; l = l->next) {
+                        TimerData *td = g_object_get_data (G_OBJECT (l->data), "timer-data");
+                        td->use_system = TRUE;
+                }
         }
 }
 
diff --git a/src/gr-cooking-view.h b/src/gr-cooking-view.h
index cd3eb8d..c714d6e 100644
--- a/src/gr-cooking-view.h
+++ b/src/gr-cooking-view.h
@@ -40,7 +40,8 @@ int            gr_cooking_view_get_step      (GrCookingView *view);
 void           gr_cooking_view_set_step      (GrCookingView *view,
                                               int            step);
 void           gr_cooking_view_start         (GrCookingView *view);
-void           gr_cooking_view_stop          (GrCookingView *view);
+void           gr_cooking_view_stop          (GrCookingView *view,
+                                              gboolean       stop_timers);
 void           gr_cooking_view_forward       (GrCookingView *view);
 void           gr_cooking_view_next_step     (GrCookingView *view);
 void           gr_cooking_view_prev_step     (GrCookingView *view);
diff --git a/src/gr-edit-page.c b/src/gr-edit-page.c
index ae574f5..80baf2e 100644
--- a/src/gr-edit-page.c
+++ b/src/gr-edit-page.c
@@ -1388,7 +1388,7 @@ preview_visible_changed (GrEditPage *page)
                 gtk_widget_set_sensitive (page->temperature_button, TRUE);
                 gtk_widget_set_visible (page->prev_step_button, FALSE);
                 gtk_widget_set_visible (page->next_step_button, FALSE);
-                gr_cooking_view_stop (GR_COOKING_VIEW (page->cooking_view));
+                gr_cooking_view_stop (GR_COOKING_VIEW (page->cooking_view), TRUE);
         }
         else {
                 g_autoptr(GArray) images = NULL;
@@ -1470,7 +1470,6 @@ gr_edit_page_class_init (GrEditPageClass *klass)
 {
         GObjectClass *object_class = G_OBJECT_CLASS (klass);
         GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-        
 
         object_class->finalize = edit_page_finalize;
         object_class->set_property = gr_edit_page_set_property;
@@ -1481,7 +1480,6 @@ gr_edit_page_class_init (GrEditPageClass *klass)
                                                       NULL, NULL,
                                                       TRUE, G_PARAM_READWRITE);
         g_object_class_install_properties (object_class, N_PROPS, props);
-        
 
         gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Recipes/gr-edit-page.ui");
 
@@ -1581,7 +1579,6 @@ gr_edit_page_class_init (GrEditPageClass *klass)
         gtk_widget_class_bind_template_callback (widget_class, prev_step);
         gtk_widget_class_bind_template_callback (widget_class, next_step);
         gtk_widget_class_bind_template_callback (widget_class, set_unsaved);
-
 }
 
 GtkWidget *
@@ -1720,6 +1717,7 @@ add_ingredients_segment (GrEditPage *page,
         gtk_widget_show (entry);
         gtk_entry_set_placeholder_text (GTK_ENTRY (entry), _("Name of the List"));
         gtk_entry_set_text (GTK_ENTRY (entry), segment_label[0] ? segment_label : "");
+        g_signal_connect_swapped (entry, "changed", G_CALLBACK (set_unsaved), page);
 
 #if defined(ENABLE_GSPELL) && defined(GSPELL_TYPE_ENTRY)
         {
@@ -1727,8 +1725,6 @@ add_ingredients_segment (GrEditPage *page,
 
                 gspell_entry = gspell_entry_get_from_gtk_entry (GTK_ENTRY (entry));
                 gspell_entry_basic_setup (gspell_entry);
-                g_signal_connect_swapped (GTK_WIDGET (entry), "changed", G_CALLBACK (set_unsaved),page);
-
         }
 #endif
 
diff --git a/src/recipes.css b/src/recipes.css
index 2c1c88e..7ebba00 100644
--- a/src/recipes.css
+++ b/src/recipes.css
@@ -337,6 +337,32 @@ button.osd {
         border: 1px solid black;
 }
 
+.cooking.confirm > label:not(.heading) {
+        margin-bottom: 20px;
+}
+
+box.cooking.overlay.confirm {
+        padding: 0;
+}
+
+box.cooking.overlay.confirm button {
+        background: transparent;
+        padding: 10px;
+        text-shadow: none;
+}
+
+box.cooking.overlay.confirm button {
+        background: gray;
+}
+
+box.cooking.overlay.confirm button:first-child {
+        border-radius: 0 0 0 16px;
+}
+
+box.cooking.overlay.confirm button:last-child {
+        border-radius: 0 0 16px 0;
+}
+
 .timer-label,
 .cooking-label {
         font-size: 30px;


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