[recipes/welcome-dialog: 2/3] Add welcome and news dialogs



commit c4abdcda6fee00490e5495880e9f187ed13d2083
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Feb 25 20:25:11 2017 -0500

    Add welcome and news dialogs
    
    The first time recipes is launched, show a welcome dialog,
    similar to what we have for software. And when a new version
    is launched for the first time, show a dialog with news
    about the release.
    
    The news dialog is also available from the app menu.

 po/POTFILES.in                 |    2 +
 src/gr-app.c                   |   13 +++
 src/gr-window.c                |  160 ++++++++++++++++++++++++++++++++++++++++
 src/gr-window.h                |    2 +
 src/menus.ui                   |    4 +
 src/recipe-welcome-dialog.ui   |   60 +++++++++++++++
 src/recipe-whats-new-dialog.ui |   34 +++++++++
 src/recipes-ui.gresource.xml   |    2 +
 src/recipes.css                |    5 +
 9 files changed, 282 insertions(+), 0 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 75f0560..ef48845 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -27,6 +27,8 @@ src/gr-window.ui
 src/menus.ui
 src/recipe-conflict-dialog.ui
 src/recipe-export-dialog.ui
+src/recipe-welcome-dialog.ui
+src/recipe-whats-new-dialog.ui
 src/gr-about-dialog.c
 src/gr-account.c
 src/gr-app.c
diff --git a/src/gr-app.c b/src/gr-app.c
index 9711d5a..db7082f 100644
--- a/src/gr-app.c
+++ b/src/gr-app.c
@@ -63,6 +63,7 @@ gr_app_activate (GApplication *app)
         if (!win)
                 win = GTK_WINDOW (gr_window_new (GR_APP (app)));
         gtk_window_present (win);
+        gr_window_activate (GR_WINDOW (win));
 }
 
 static void
@@ -107,6 +108,17 @@ about_activated (GSimpleAction *action,
 }
 
 static void
+news_activated (GSimpleAction *action,
+                GVariant      *parameter,
+                gpointer       app)
+{
+        GtkWindow *win;
+
+        win = gtk_application_get_active_window (GTK_APPLICATION (app));
+        gr_window_show_news (GR_WINDOW (win));
+}
+
+static void
 quit_activated (GSimpleAction *action,
                 GVariant      *parameter,
                 gpointer       app)
@@ -165,6 +177,7 @@ static GActionEntry app_entries[] =
         { "timer-expired", timer_expired, "(si)", NULL, NULL },
         { "chef-information", chef_information_activated, NULL, NULL, NULL },
         { "about", about_activated, NULL, NULL, NULL },
+        { "news", news_activated, NULL, NULL, NULL },
         { "import", import_activated, NULL, NULL, NULL },
         { "details", details_activated, "(ss)", NULL, NULL },
         { "search", search_activated, "s", NULL, NULL },
diff --git a/src/gr-window.c b/src/gr-window.c
index 86d2272..18991bc 100644
--- a/src/gr-window.c
+++ b/src/gr-window.c
@@ -40,6 +40,8 @@
 #include "gr-recipe-importer.h"
 #include "gr-about-dialog.h"
 #include "gr-account.h"
+#include "gr-utils.h"
+#include "gr-appdata.h"
 
 
 struct _GrWindow
@@ -1145,3 +1147,161 @@ gr_window_show_about_dialog (GrWindow *window)
         g_signal_connect (window->about_dialog, "response", G_CALLBACK (about_response), window);
         gr_window_present_dialog (window, GTK_WINDOW (window->about_dialog));
 }
+
+static void
+load_versions (char **new,
+               char **old)
+{
+        g_autofree char *path = NULL;
+        g_autofree char *buffer = NULL;
+        g_auto(GStrv) strv = NULL;
+
+        path = g_build_filename (get_user_data_dir (), "version", NULL);
+        if (!g_file_get_contents (path, &buffer, NULL, NULL)) {
+                *new = NULL;
+                *old = NULL;
+                return;
+        }
+
+        strv = g_strsplit (buffer, "\n", 0);
+        *new = g_strdup (strv[0]);
+        *old = g_strdup (strv[1]);
+}
+
+static void
+save_versions (const char *new,
+               const char *old)
+{
+        g_autofree char *path = NULL;
+        g_autofree char *buffer = NULL;
+
+        if (old == NULL)
+                buffer = g_strdup (new);
+        else
+                buffer = g_strdup_printf ("%s\n%s", new, old);
+
+        path = g_build_filename (get_user_data_dir (), "version", NULL);
+        g_file_set_contents (path, buffer, -1, NULL);
+}
+
+static void
+gr_window_show_welcome (GrWindow *window)
+{
+        g_autoptr(GtkBuilder) builder = NULL;
+        GtkWindow *dialog;
+        GtkWidget *button;
+
+        builder = gtk_builder_new_from_resource ("/org/gnome/Recipes/recipe-welcome-dialog.ui");
+        dialog = GTK_WINDOW (gtk_builder_get_object (builder, "dialog"));
+        button = GTK_WIDGET (gtk_builder_get_object (builder, "close_button"));
+        g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), dialog);
+        gtk_window_set_transient_for (dialog, GTK_WINDOW (window));
+        gr_window_present_dialog (window, dialog);
+}
+
+void
+gr_window_show_news (GrWindow *window)
+{
+        g_autoptr(GtkBuilder) builder = NULL;
+        GtkWindow *dialog;
+        g_autofree char *old = NULL;
+        g_autofree char *new = NULL;
+        g_autoptr(GPtrArray) news = NULL;
+        GtkWidget *box;
+        int i;
+
+        load_versions (&new, &old);
+        if (new == NULL && old == NULL)
+                news = get_release_info (PACKAGE_VERSION, "0.0.0");
+        else if (old == NULL)
+                news = get_release_info (new, "0.0.0");
+        else
+                news = get_release_info (new, old);
+
+        if (news->len == 0)
+                return;
+
+        builder = gtk_builder_new_from_resource ("/org/gnome/Recipes/recipe-whats-new-dialog.ui");
+        dialog = GTK_WINDOW (gtk_builder_get_object (builder, "dialog"));
+        gtk_window_set_transient_for (dialog, GTK_WINDOW (window));
+        box = GTK_WIDGET (gtk_builder_get_object (builder, "box"));
+
+        for (i = 0; i < news->len; i++) {
+                ReleaseInfo *ri = g_ptr_array_index (news, i);
+                GtkWidget *heading;
+                GtkWidget *image;
+                GtkWidget *label;
+                GtkStyleContext *context;
+                g_autofree char *title = NULL;
+
+                heading = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
+                gtk_widget_set_halign (heading, GTK_ALIGN_CENTER);
+                image = gtk_image_new_from_icon_name ("org.gnome.Recipes-symbolic", 1);
+                gtk_image_set_pixel_size (GTK_IMAGE (image), 32);
+                gtk_container_add (GTK_CONTAINER (heading), image);
+                title = g_strdup_printf (_("Recipes %s"), ri->version);
+                label = gtk_label_new (title);
+                gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+                context = gtk_widget_get_style_context (label);
+                gtk_style_context_add_class (context, "heading");
+                gtk_style_context_add_class (context, "welcome");
+                gtk_container_add (GTK_CONTAINER (heading), label);
+                gtk_container_add (GTK_CONTAINER (box), heading);
+
+                if (ri->date) {
+                        g_autofree char *date = NULL;
+                        g_autofree char *release = NULL;
+
+                        date = g_date_time_format (ri->date, "%F");
+                        release = g_strdup_printf (_("Released: %s"), date);
+                        label = gtk_label_new (release);
+                        gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+                        gtk_container_add (GTK_CONTAINER (box), label);
+                }
+
+                if (ri->news) {
+                        label = gtk_label_new (ri->news);
+                        gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+                        gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+                        gtk_label_set_max_width_chars (GTK_LABEL (label), 55);
+                        gtk_label_set_width_chars (GTK_LABEL (label), 55);
+                        gtk_container_add (GTK_CONTAINER (box), label);
+                }
+        }
+
+        gtk_widget_show_all (box);
+        gr_window_present_dialog (GR_WINDOW (window), dialog);
+}
+
+static gboolean
+show_welcome_or_news (gpointer data)
+{
+        GrWindow *window = data;
+        g_autofree char *old = NULL;
+        g_autofree char *new = NULL;
+
+        load_versions (&new, &old);
+        if (new == NULL && old == NULL) {
+                save_versions (PACKAGE_VERSION, NULL);
+                gr_window_show_welcome (window);
+        }
+        else if (strcmp (new, PACKAGE_VERSION) != 0) {
+                save_versions (PACKAGE_VERSION, new);
+                gr_window_show_news (window);
+        }
+
+        return G_SOURCE_REMOVE;
+}
+
+static void
+window_mapped (GtkWidget *window)
+{
+        // we don't want the dialot to show up first
+        g_timeout_add (200, show_welcome_or_news, window);
+}
+
+void
+gr_window_activate (GrWindow *window)
+{
+        g_signal_connect_after (window, "map-event", G_CALLBACK (window_mapped), NULL);
+}
diff --git a/src/gr-window.h b/src/gr-window.h
index feaec31..2f70787 100644
--- a/src/gr-window.h
+++ b/src/gr-window.h
@@ -83,5 +83,7 @@ void            gr_window_offer_shopping             (GrWindow   *window);
 
 void            gr_window_show_my_chef_information   (GrWindow   *window);
 void            gr_window_show_about_dialog          (GrWindow   *window);
+void            gr_window_show_news                  (GrWindow   *window);
+void            gr_window_activate                   (GrWindow   *window);
 
 G_END_DECLS
diff --git a/src/menus.ui b/src/menus.ui
index f2ce0af..49a0a3f 100644
--- a/src/menus.ui
+++ b/src/menus.ui
@@ -15,6 +15,10 @@
     </section>
     <section>
       <item>
+        <attribute name="label" translatable="yes">_What's New</attribute>
+        <attribute name="action">app.news</attribute>
+      </item>
+      <item>
         <attribute name="label" translatable="yes">_About</attribute>
         <attribute name="action">app.about</attribute>
       </item>
diff --git a/src/recipe-welcome-dialog.ui b/src/recipe-welcome-dialog.ui
new file mode 100644
index 0000000..3638ae4
--- /dev/null
+++ b/src/recipe-welcome-dialog.ui
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface domain="gnome-recipes">
+  <object class="GtkWindow" id="dialog">
+    <property name="modal">1</property>
+    <property name="resizable">0</property>
+    <property name="title" translatable="yes">Welcome</property>
+    <property name="destroy-with-parent">1</property>
+    <child type="titlebar">
+      <object class="GtkHeaderBar">
+        <property name="visible">1</property>
+        <property name="title" translatable="yes">Welcome</property>
+        <property name="show-close-button">0</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkBox">
+        <property name="visible">1</property>
+        <property name="margin">20</property>
+        <property name="spacing">20</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkImage">
+            <property name="visible">1</property>
+            <property name="icon-name">org.gnome.Recipes</property>
+            <property name="pixel-size">256</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">1</property>
+            <property name="label" translatable="yes">Welcome to Recipes</property>
+            <style>
+              <class name="welcome"/>
+              <class name="heading"/>
+            </style>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">1</property>
+            <property name="wrap">1</property>
+            <property name="max-width-chars">55</property>
+            <property name="width-chars">55</property>
+            <property name="label" translatable="yes">Recipes helps you to discover what to cook today, 
tomorrow, and the rest of the week. Find recipes from all over the world that have been contributed by the 
GNOME community, and share your favorite recipes with your friends.</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkButton" id="close_button">
+            <property name="visible">1</property>
+            <property name="halign">center</property>
+            <property name="label" translatable="yes">Let's Cook Something</property>
+            <style>
+              <class name="suggested-action"/>
+            </style>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/src/recipe-whats-new-dialog.ui b/src/recipe-whats-new-dialog.ui
new file mode 100644
index 0000000..df80b70
--- /dev/null
+++ b/src/recipe-whats-new-dialog.ui
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface domain="gnome-recipes">
+  <object class="GtkWindow" id="dialog">
+    <property name="modal">1</property>
+    <property name="default-width">400</property>
+    <property name="default-height">600</property>
+    <property name="resizable">0</property>
+    <property name="title" translatable="yes">What's New in Recipes</property>
+    <property name="destroy-with-parent">1</property>
+    <child type="titlebar">
+      <object class="GtkHeaderBar">
+        <property name="visible">1</property>
+        <property name="title" translatable="yes">What's New in Recipes</property>
+        <property name="show-close-button">1</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkScrolledWindow">
+        <property name="visible">1</property>
+        <property name="hscrollbar-policy">never</property>
+        <property name="vscrollbar-policy">automatic</property>
+        <property name="min-content-height">600</property>
+        <child>
+          <object class="GtkBox" id="box">
+            <property name="visible">1</property>
+            <property name="margin">20</property>
+            <property name="spacing">20</property>
+            <property name="orientation">vertical</property>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/src/recipes-ui.gresource.xml b/src/recipes-ui.gresource.xml
index 0ca1173..ae503a5 100644
--- a/src/recipes-ui.gresource.xml
+++ b/src/recipes-ui.gresource.xml
@@ -29,6 +29,8 @@
     <file preprocess="xml-stripblanks">chef-conflict-dialog.ui</file>
     <file preprocess="xml-stripblanks">recipe-conflict-dialog.ui</file>
     <file preprocess="xml-stripblanks">recipe-export-dialog.ui</file>
+    <file preprocess="xml-stripblanks">recipe-welcome-dialog.ui</file>
+    <file preprocess="xml-stripblanks">recipe-whats-new-dialog.ui</file>
   </gresource>
   <gresource prefix="/org/gnome/Recipes/gtk">
     <file preprocess="xml-stripblanks">menus.ui</file>
diff --git a/src/recipes.css b/src/recipes.css
index 7eb7a6d..35650c0 100644
--- a/src/recipes.css
+++ b/src/recipes.css
@@ -8,6 +8,11 @@ label.heading {
   font-weight: bold;
 }
 
+label.welcome.heading {
+  font: 32px Cantarell;
+  font-weight: bold;
+}
+
 label.sidebar {
   background: none;
   border: none;


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