[gnome-software] Show a star rating on the application details page



commit e0737e659e1acb76a185b190291a3a0fcd290852
Author: Richard Hughes <richard hughsie com>
Date:   Thu Oct 10 14:19:34 2013 +0100

    Show a star rating on the application details page

 data/Makefile.am                 |    7 +-
 data/gs-star-dim.png             |  Bin 0 -> 491 bytes
 data/gs-star.png                 |  Bin 0 -> 421 bytes
 data/stars0.png                  |  Bin 811 -> 0 bytes
 data/stars1.png                  |  Bin 1003 -> 0 bytes
 data/stars2.png                  |  Bin 1015 -> 0 bytes
 data/stars3.png                  |  Bin 808 -> 0 bytes
 data/stars4.png                  |  Bin 629 -> 0 bytes
 src/Makefile.am                  |    4 +-
 src/gnome-software.gresource.xml |    1 +
 src/gnome-software.ui            |   12 --
 src/gs-shell-details.c           |   35 ++++++
 src/gs-star-widget.c             |  211 ++++++++++++++++++++++++++++++++++++++
 src/gs-star-widget.h             |   63 +++++++++++
 src/gs-star-widget.ui            |   96 +++++++++++++++++
 15 files changed, 411 insertions(+), 18 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index bbacca1..b9de349 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -13,11 +13,8 @@ dist_resources_DATA =                                        \
        featured-weather-bg.png   \
        featured-xchat.png                              \
        featured.ini                                    \
-       stars0.png                                      \
-       stars1.png                                      \
-       stars2.png                                      \
-       stars3.png                                      \
-       stars4.png          
+       gs-star-dim.png                                 \
+       gs-star.png
 
 install-sample-data:
        wget -O fedora-20.xml.gz http://people.freedesktop.org/~hughsient/temp/fedora-20.xml.gz; \
diff --git a/data/gs-star-dim.png b/data/gs-star-dim.png
new file mode 100644
index 0000000..376a292
Binary files /dev/null and b/data/gs-star-dim.png differ
diff --git a/data/gs-star.png b/data/gs-star.png
new file mode 100644
index 0000000..7123f2c
Binary files /dev/null and b/data/gs-star.png differ
diff --git a/src/Makefile.am b/src/Makefile.am
index 1dfafd3..da6d0c7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,7 +29,7 @@ UI_FILES =                                            \
        category-tile.ui                                \
        feature-tile.ui                                 \
        gnome-software.ui                               \
-       gnome-software.ui                               \
+       gs-star-widget.ui                               \
        screenshot-image.ui                             \
        popular-tile.ui
 
@@ -47,6 +47,8 @@ gnome_software_SOURCES =                              \
        gs-category.h                                   \
        gs-app-widget.c                                 \
        gs-app-widget.h                                 \
+       gs-star-widget.c                                \
+       gs-star-widget.h                                \
        gs-popular-tile.c                               \
        gs-popular-tile.h                               \
        gs-feature-tile.c                               \
diff --git a/src/gnome-software.gresource.xml b/src/gnome-software.gresource.xml
index 04349c8..1f0ece8 100644
--- a/src/gnome-software.gresource.xml
+++ b/src/gnome-software.gresource.xml
@@ -9,6 +9,7 @@
   <file preprocess="xml-stripblanks">app-tile.ui</file>
   <file preprocess="xml-stripblanks">app-widget.ui</file>
   <file preprocess="xml-stripblanks">screenshot-image.ui</file>
+  <file preprocess="xml-stripblanks">gs-star-widget.ui</file>
   <file>gtk-style.css</file>
   <file>gtk-style-hc.css</file>
   <file preprocess="to-pixdata">shadow.png</file>
diff --git a/src/gnome-software.ui b/src/gnome-software.ui
index 124cca5..e47b546 100644
--- a/src/gnome-software.ui
+++ b/src/gnome-software.ui
@@ -790,18 +790,6 @@
                         <property name="position">1</property>
                       </packing>
                     </child>
-                    <child>
-                      <object class="GtkImage" id="application_details_stars">
-                        <property name="can_focus">False</property>
-                        <property name="yalign">0</property>
-                        <property name="file">/usr/share/gnome-software/stars3.png</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">2</property>
-                      </packing>
-                    </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
diff --git a/src/gs-shell-details.c b/src/gs-shell-details.c
index 8f062e9..44712f7 100644
--- a/src/gs-shell-details.c
+++ b/src/gs-shell-details.c
@@ -29,6 +29,7 @@
 
 #include "gs-shell-details.h"
 #include "gs-screenshot-image.h"
+#include "gs-star-widget.h"
 
 static void    gs_shell_details_finalize       (GObject        *object);
 
@@ -45,6 +46,7 @@ struct GsShellDetailsPrivate
        GtkSizeGroup            *history_sizegroup_state;
        GtkSizeGroup            *history_sizegroup_timestamp;
        GtkSizeGroup            *history_sizegroup_version;
+       GtkWidget               *star;
        SoupSession             *session;
 };
 
@@ -473,6 +475,10 @@ gs_shell_details_refresh_all (GsShellDetails *shell_details)
                gtk_label_set_label (GTK_LABEL (widget), tmp);
        }
 
+       /* set the rating */
+       gs_star_widget_set_rating (GS_STAR_WIDGET (priv->star),
+                                  gs_app_get_rating (priv->app));
+
        /* make history button insensitive if there is none */
        history = gs_app_get_history (priv->app);
        widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_history"));
@@ -803,6 +809,25 @@ scrollbar_mapped_cb (GtkWidget *sb, GtkScrolledWindow *swin)
 }
 
 /**
+ * gs_shell_details_rating_changed_cb:
+ **/
+static void
+gs_shell_details_rating_changed_cb (GsStarWidget *star,
+                                   guint rating,
+                                   GsShellDetails *shell_details)
+{
+       GsShellDetailsPrivate *priv = shell_details->priv;
+
+       g_debug ("%s rating changed from %i%% to %i%%",
+                gs_app_get_id (priv->app),
+                gs_app_get_rating (priv->app),
+                rating);
+
+       /* FIXME: call into the plugins to set the new value */
+       gs_app_set_rating (priv->app, rating);
+}
+
+/**
  * gs_shell_details_setup:
  */
 void
@@ -826,6 +851,16 @@ gs_shell_details_setup (GsShellDetails *shell_details,
        priv->builder = g_object_ref (builder);
        priv->cancellable = g_object_ref (cancellable);
 
+       /* set up star ratings */
+       sw = GTK_WIDGET (gtk_builder_get_object (priv->builder,
+                                                "box_details_header"));
+       priv->star = gs_star_widget_new ();
+       g_signal_connect (priv->star, "rating-changed",
+                         G_CALLBACK (gs_shell_details_rating_changed_cb),
+                         shell_details);
+       gtk_widget_set_visible (priv->star, TRUE);
+       gtk_box_pack_start (GTK_BOX (sw), priv->star, FALSE, FALSE, 0);
+
        /* setup history */
        list_box = GTK_LIST_BOX (gtk_builder_get_object (priv->builder, "list_box_history"));
        gtk_list_box_set_header_func (list_box,
diff --git a/src/gs-star-widget.c b/src/gs-star-widget.c
new file mode 100644
index 0000000..4dbe271
--- /dev/null
+++ b/src/gs-star-widget.c
@@ -0,0 +1,211 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "gs-star-widget.h"
+
+struct _GsStarWidgetPrivate
+{
+       gint             rating;
+       GtkWidget       *button1;
+       GtkWidget       *button2;
+       GtkWidget       *button3;
+       GtkWidget       *button4;
+       GtkWidget       *image1;
+       GtkWidget       *image2;
+       GtkWidget       *image3;
+       GtkWidget       *image4;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GsStarWidget, gs_star_widget, GTK_TYPE_BIN)
+
+enum {
+       RATING_CHANGED,
+       SIGNAL_LAST
+};
+
+static guint signals [SIGNAL_LAST] = { 0 };
+
+static const gint rate_to_star[] = {1, 30, 70, 100, -1};
+
+/**
+ * gs_star_widget_get_rating:
+ **/
+gint
+gs_star_widget_get_rating (GsStarWidget *star)
+{
+       GsStarWidgetPrivate *priv;
+       g_return_val_if_fail (GS_IS_STAR_WIDGET (star), -1);
+       priv = gs_star_widget_get_instance_private (star);
+       return priv->rating;
+}
+
+/**
+ * gs_star_widget_refresh:
+ **/
+static void
+gs_star_widget_refresh (GsStarWidget *star)
+{
+       GsStarWidgetPrivate *priv;
+       const gchar *img = DATADIR "/gnome-software/gs-star.png";
+       const gchar *img_dim = DATADIR "/gnome-software/gs-star-dim.png";
+
+       priv = gs_star_widget_get_instance_private (star);
+
+       /* not set yet */
+       gtk_widget_set_sensitive (priv->button1, priv->rating != -1);
+       gtk_widget_set_sensitive (priv->button2, priv->rating != -1);
+       gtk_widget_set_sensitive (priv->button3, priv->rating != -1);
+       gtk_widget_set_sensitive (priv->button4, priv->rating != -1);
+
+       /* set the dim states correctly */
+       gtk_image_set_from_file (GTK_IMAGE (priv->image1),
+                                priv->rating >= rate_to_star[0] ? img : img_dim);
+       gtk_image_set_from_file (GTK_IMAGE (priv->image2),
+                                priv->rating >= rate_to_star[1] ? img : img_dim);
+       gtk_image_set_from_file (GTK_IMAGE (priv->image3),
+                                priv->rating >= rate_to_star[2] ? img : img_dim);
+       gtk_image_set_from_file (GTK_IMAGE (priv->image4),
+                                priv->rating >= rate_to_star[3] ? img : img_dim);
+}
+
+/**
+ * gs_star_widget_set_rating:
+ **/
+void
+gs_star_widget_set_rating (GsStarWidget *star, gint rating)
+{
+       GsStarWidgetPrivate *priv;
+       g_return_if_fail (GS_IS_STAR_WIDGET (star));
+       priv = gs_star_widget_get_instance_private (star);
+       priv->rating = rating;
+       gs_star_widget_refresh (star);
+}
+
+/**
+ * gs_star_widget_destroy:
+ **/
+static void
+gs_star_widget_destroy (GtkWidget *widget)
+{
+       GTK_WIDGET_CLASS (gs_star_widget_parent_class)->destroy (widget);
+}
+
+/**
+ * gs_star_widget_button_clicked_cb:
+ **/
+static void
+gs_star_widget_button_clicked_cb (GtkButton *button, GsStarWidget *star)
+{
+       GsStarWidgetPrivate *priv;
+       gint rating;
+
+       priv = gs_star_widget_get_instance_private (star);
+       rating = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button),
+                                                    "GsStarWidget::value"));
+       if (rating == priv->rating)
+               return;
+       priv->rating = rating;
+       g_signal_emit (star, signals[RATING_CHANGED], 0, priv->rating);
+       gs_star_widget_refresh (star);
+}
+
+/**
+ * gs_star_widget_init:
+ **/
+static void
+gs_star_widget_init (GsStarWidget *star)
+{
+       GsStarWidgetPrivate *priv;
+
+       gtk_widget_set_has_window (GTK_WIDGET (star), FALSE);
+       gtk_widget_init_template (GTK_WIDGET (star));
+       priv = gs_star_widget_get_instance_private (star);
+       g_signal_connect (priv->button1, "clicked",
+                         G_CALLBACK (gs_star_widget_button_clicked_cb), star);
+       g_signal_connect (priv->button2, "clicked",
+                         G_CALLBACK (gs_star_widget_button_clicked_cb), star);
+       g_signal_connect (priv->button3, "clicked",
+                         G_CALLBACK (gs_star_widget_button_clicked_cb), star);
+       g_signal_connect (priv->button4, "clicked",
+                         G_CALLBACK (gs_star_widget_button_clicked_cb), star);
+
+       /* assign the values */
+       g_object_set_data (G_OBJECT (priv->button1),
+                          "GsStarWidget::value",
+                          GINT_TO_POINTER (rate_to_star[0]));
+       g_object_set_data (G_OBJECT (priv->button2),
+                          "GsStarWidget::value",
+                          GINT_TO_POINTER (rate_to_star[1]));
+       g_object_set_data (G_OBJECT (priv->button3),
+                          "GsStarWidget::value",
+                          GINT_TO_POINTER (rate_to_star[2]));
+       g_object_set_data (G_OBJECT (priv->button4),
+                          "GsStarWidget::value",
+                          GINT_TO_POINTER (rate_to_star[3]));
+}
+
+/**
+ * gs_star_widget_class_init:
+ **/
+static void
+gs_star_widget_class_init (GsStarWidgetClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+       GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+       widget_class->destroy = gs_star_widget_destroy;
+
+       signals [RATING_CHANGED] =
+               g_signal_new ("rating-changed",
+                             G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+                             G_STRUCT_OFFSET (GsStarWidgetClass, rating_changed),
+                             NULL, NULL, g_cclosure_marshal_VOID__UINT,
+                             G_TYPE_NONE, 1, G_TYPE_UINT);
+
+       gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/software/gs-star-widget.ui");
+
+       gtk_widget_class_bind_template_child_private (widget_class, GsStarWidget, button1);
+       gtk_widget_class_bind_template_child_private (widget_class, GsStarWidget, button2);
+       gtk_widget_class_bind_template_child_private (widget_class, GsStarWidget, button3);
+       gtk_widget_class_bind_template_child_private (widget_class, GsStarWidget, button4);
+       gtk_widget_class_bind_template_child_private (widget_class, GsStarWidget, image1);
+       gtk_widget_class_bind_template_child_private (widget_class, GsStarWidget, image2);
+       gtk_widget_class_bind_template_child_private (widget_class, GsStarWidget, image3);
+       gtk_widget_class_bind_template_child_private (widget_class, GsStarWidget, image4);
+}
+
+/**
+ * gs_star_widget_new:
+ **/
+GtkWidget *
+gs_star_widget_new (void)
+{
+       GsStarWidget *star;
+       star = g_object_new (GS_TYPE_STAR_WIDGET, NULL);
+       return GTK_WIDGET (star);
+}
+
+/* vim: set noexpandtab: */
diff --git a/src/gs-star-widget.h b/src/gs-star-widget.h
new file mode 100644
index 0000000..24fe418
--- /dev/null
+++ b/src/gs-star-widget.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef GS_STAR_WIDGET_H
+#define GS_STAR_WIDGET_H
+
+#include <gtk/gtk.h>
+
+#define GS_TYPE_STAR_WIDGET            (gs_star_widget_get_type())
+#define GS_STAR_WIDGET(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), GS_TYPE_STAR_WIDGET, GsStarWidget))
+#define GS_STAR_WIDGET_CLASS(cls)      (G_TYPE_CHECK_CLASS_CAST((cls), GS_TYPE_STAR_WIDGET, 
GsStarWidgetClass))
+#define GS_IS_STAR_WIDGET(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), GS_TYPE_STAR_WIDGET))
+#define GS_IS_STAR_WIDGET_CLASS(cls)   (G_TYPE_CHECK_CLASS_TYPE((cls), GS_TYPE_STAR_WIDGET))
+#define GS_STAR_WIDGET_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), GS_TYPE_STAR_WIDGET, 
GsStarWidgetClass))
+
+G_BEGIN_DECLS
+
+typedef struct _GsStarWidget                   GsStarWidget;
+typedef struct _GsStarWidgetClass              GsStarWidgetClass;
+typedef struct _GsStarWidgetPrivate            GsStarWidgetPrivate;
+
+struct _GsStarWidget
+{
+       GtkBin             parent;
+       GsStarWidgetPrivate     *priv;
+};
+
+struct _GsStarWidgetClass
+{
+       GtkBinClass      parent_class;
+
+       void                    (*rating_changed)               (GsStarWidget   *star);
+};
+
+GType           gs_star_widget_get_type                (void);
+GtkWidget      *gs_star_widget_new                     (void);
+gint            gs_star_widget_get_rating              (GsStarWidget   *star);
+void            gs_star_widget_set_rating              (GsStarWidget   *star,
+                                                        gint            rating);
+
+G_END_DECLS
+
+#endif /* GS_STAR_WIDGET_H */
+
+/* vim: set noexpandtab: */
diff --git a/src/gs-star-widget.ui b/src/gs-star-widget.ui
new file mode 100644
index 0000000..04adcb9
--- /dev/null
+++ b/src/gs-star-widget.ui
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.10 -->
+  <template class="GsStarWidget" parent="GtkBin">
+    <property name="visible">True</property>
+    <child>
+      <object class="GtkBox" id="box1">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">center</property>
+        <property name="valign">center</property>
+        <property name="spacing">6</property>
+        <child>
+          <object class="GtkButton" id="button1">
+            <property name="visible">True</property>
+            <style>
+              <class name="child"/>
+              <class name="tile"/>
+            </style>
+            <child>
+              <object class="GtkImage" id="image1">
+                <property name="visible">True</property>
+                <property name="stock">gtk-about</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="button2">
+            <property name="visible">True</property>
+            <style>
+              <class name="child"/>
+              <class name="tile"/>
+            </style>
+            <child>
+              <object class="GtkImage" id="image2">
+                <property name="visible">True</property>
+                <property name="stock">gtk-about</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="button3">
+            <property name="visible">True</property>
+            <style>
+              <class name="child"/>
+              <class name="tile"/>
+            </style>
+            <child>
+              <object class="GtkImage" id="image3">
+                <property name="visible">True</property>
+                <property name="stock">gtk-about</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="button4">
+            <property name="visible">True</property>
+            <style>
+              <class name="child"/>
+              <class name="tile"/>
+            </style>
+            <child>
+              <object class="GtkImage" id="image4">
+                <property name="visible">True</property>
+                <property name="stock">gtk-about</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">3</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>


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