[gnome-software] gs-star-widget: Add GObject properties



commit 144a915c49bfb8d650223b3374bb2f86c4fd7b71
Author: Philip Withnall <withnall endlessm com>
Date:   Tue Jun 2 13:01:58 2020 +0100

    gs-star-widget: Add GObject properties
    
    These allow things like the icon size to be set in GtkBuilder files,
    which saves a call to `gs_star_widget_set_icon_size()` and hence,
    particularly, a call to `gs_star_widget_refresh()`, which destroys and
    recreates most of the widget.
    
    Signed-off-by: Philip Withnall <withnall endlessm com>

 src/gs-app-row.c        |   1 -
 src/gs-app-row.ui       |   1 +
 src/gs-popular-tile.c   |   1 -
 src/gs-popular-tile.ui  |   1 +
 src/gs-review-dialog.c  |   2 -
 src/gs-review-dialog.ui |   2 +
 src/gs-star-widget.c    | 119 ++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 123 insertions(+), 4 deletions(-)
---
diff --git a/src/gs-app-row.c b/src/gs-app-row.c
index 592e6837..3496b492 100644
--- a/src/gs-app-row.c
+++ b/src/gs-app-row.c
@@ -625,7 +625,6 @@ gs_app_row_init (GsAppRow *app_row)
 
        gtk_widget_set_has_window (GTK_WIDGET (app_row), FALSE);
        gtk_widget_init_template (GTK_WIDGET (app_row));
-       gs_star_widget_set_icon_size (GS_STAR_WIDGET (priv->star), 12);
 
        priv->settings = g_settings_new ("org.gnome.software");
 
diff --git a/src/gs-app-row.ui b/src/gs-app-row.ui
index 410d1981..109881c3 100644
--- a/src/gs-app-row.ui
+++ b/src/gs-app-row.ui
@@ -81,6 +81,7 @@
               <object class="GsStarWidget" id="star">
                 <property name="visible">False</property>
                 <property name="halign">start</property>
+                <property name="icon-size">12</property>
               </object>
             </child>
           </object>
diff --git a/src/gs-popular-tile.c b/src/gs-popular-tile.c
index 7a093cf2..897f09cf 100644
--- a/src/gs-popular-tile.c
+++ b/src/gs-popular-tile.c
@@ -103,7 +103,6 @@ gs_popular_tile_init (GsPopularTile *tile)
 {
        gtk_widget_set_has_window (GTK_WIDGET (tile), FALSE);
        gtk_widget_init_template (GTK_WIDGET (tile));
-       gs_star_widget_set_icon_size (GS_STAR_WIDGET (tile->stars), 12);
 }
 
 static void
diff --git a/src/gs-popular-tile.ui b/src/gs-popular-tile.ui
index 2b1cea33..17e4eecd 100644
--- a/src/gs-popular-tile.ui
+++ b/src/gs-popular-tile.ui
@@ -92,6 +92,7 @@
                       <object class="GsStarWidget" id="stars">
                         <property name="visible">True</property>
                         <property name="halign">center</property>
+                        <property name="icon-size">12</property>
                         <style>
                           <class name="onlyjustvisible"/>
                         </style>
diff --git a/src/gs-review-dialog.c b/src/gs-review-dialog.c
index 0c607e54..6153b571 100644
--- a/src/gs-review-dialog.c
+++ b/src/gs-review-dialog.c
@@ -161,7 +161,6 @@ gs_review_dialog_init (GsReviewDialog *dialog)
 {
        GtkTextBuffer *buffer;
        gtk_widget_init_template (GTK_WIDGET (dialog));
-       gs_star_widget_set_icon_size (GS_STAR_WIDGET (dialog->star), 32);
 
 #ifdef HAVE_GSPELL
        /* allow checking spelling */
@@ -183,7 +182,6 @@ gs_review_dialog_init (GsReviewDialog *dialog)
                                                  dialog);
 
        /* update UI */
-       gs_star_widget_set_interactive (GS_STAR_WIDGET (dialog->star), TRUE);
        g_signal_connect_swapped (dialog->star, "rating-changed",
                                  G_CALLBACK (gs_review_dialog_changed_cb), dialog);
        g_signal_connect_swapped (dialog->summary_entry, "notify::text",
diff --git a/src/gs-review-dialog.ui b/src/gs-review-dialog.ui
index b6db5c12..c79ee53b 100644
--- a/src/gs-review-dialog.ui
+++ b/src/gs-review-dialog.ui
@@ -82,6 +82,8 @@
                   <object class="GsStarWidget" id="star">
                     <property name="visible">True</property>
                     <property name="halign">center</property>
+                    <property name="icon-size">32</property>
+                    <property name="interactive">True</property>
                   </object>
                 </child>
                 <child>
diff --git a/src/gs-star-widget.c b/src/gs-star-widget.c
index 091f1433..32255b4e 100644
--- a/src/gs-star-widget.c
+++ b/src/gs-star-widget.c
@@ -23,11 +23,18 @@ typedef struct
 
 G_DEFINE_TYPE_WITH_PRIVATE (GsStarWidget, gs_star_widget, GTK_TYPE_BIN)
 
+typedef enum {
+       PROP_ICON_SIZE = 1,
+       PROP_INTERACTIVE,
+       PROP_RATING,
+} GsStarWidgetProperty;
+
 enum {
        RATING_CHANGED,
        SIGNAL_LAST
 };
 
+static GParamSpec *properties[PROP_RATING + 1] = { 0, };
 static guint signals [SIGNAL_LAST] = { 0 };
 
 static void gs_star_widget_refresh (GsStarWidget *star);
@@ -47,7 +54,12 @@ gs_star_widget_set_icon_size (GsStarWidget *star, guint pixel_size)
        GsStarWidgetPrivate *priv;
        g_return_if_fail (GS_IS_STAR_WIDGET (star));
        priv = gs_star_widget_get_instance_private (star);
+
+       if (priv->icon_size == pixel_size)
+               return;
+
        priv->icon_size = pixel_size;
+       g_object_notify_by_pspec (G_OBJECT (star), properties[PROP_ICON_SIZE]);
        gs_star_widget_refresh (star);
 }
 
@@ -64,6 +76,7 @@ gs_star_widget_button_clicked_cb (GtkButton *button, GsStarWidget *star)
        rating = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button),
                                                     "GsStarWidget::value"));
        priv->rating = rating;
+       g_object_notify_by_pspec (G_OBJECT (star), properties[PROP_RATING]);
        g_signal_emit (star, signals[RATING_CHANGED], 0, priv->rating);
        gs_star_widget_refresh (star);
 }
@@ -116,7 +129,12 @@ gs_star_widget_set_interactive (GsStarWidget *star, gboolean interactive)
        GsStarWidgetPrivate *priv;
        g_return_if_fail (GS_IS_STAR_WIDGET (star));
        priv = gs_star_widget_get_instance_private (star);
+
+       if (priv->interactive == interactive)
+               return;
+
        priv->interactive = interactive;
+       g_object_notify_by_pspec (G_OBJECT (star), properties[PROP_INTERACTIVE]);
        gs_star_widget_refresh (star);
 }
 
@@ -127,10 +145,64 @@ gs_star_widget_set_rating (GsStarWidget *star,
        GsStarWidgetPrivate *priv;
        g_return_if_fail (GS_IS_STAR_WIDGET (star));
        priv = gs_star_widget_get_instance_private (star);
+
+       if (priv->rating == rating)
+               return;
+
        priv->rating = rating;
+       g_object_notify_by_pspec (G_OBJECT (star), properties[PROP_RATING]);
        gs_star_widget_refresh (star);
 }
 
+static void
+gs_star_widget_get_property (GObject *object,
+                            guint prop_id,
+                            GValue *value,
+                            GParamSpec *pspec)
+{
+       GsStarWidget *self = GS_STAR_WIDGET (object);
+       GsStarWidgetPrivate *priv = gs_star_widget_get_instance_private (self);
+
+       switch ((GsStarWidgetProperty) prop_id) {
+       case PROP_ICON_SIZE:
+               g_value_set_uint (value, priv->icon_size);
+               break;
+       case PROP_INTERACTIVE:
+               g_value_set_boolean (value, priv->interactive);
+               break;
+       case PROP_RATING:
+               g_value_set_int (value, priv->rating);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+static void
+gs_star_widget_set_property (GObject *object,
+                            guint prop_id,
+                            const GValue *value,
+                            GParamSpec *pspec)
+{
+       GsStarWidget *self = GS_STAR_WIDGET (object);
+
+       switch ((GsStarWidgetProperty) prop_id) {
+       case PROP_ICON_SIZE:
+               gs_star_widget_set_icon_size (self, g_value_get_uint (value));
+               break;
+       case PROP_INTERACTIVE:
+               gs_star_widget_set_interactive (self, g_value_get_boolean (value));
+               break;
+       case PROP_RATING:
+               gs_star_widget_set_rating (self, g_value_get_int (value));
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
 static void
 gs_star_widget_destroy (GtkWidget *widget)
 {
@@ -151,6 +223,51 @@ gs_star_widget_class_init (GsStarWidgetClass *klass)
        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
        widget_class->destroy = gs_star_widget_destroy;
+       object_class->get_property = gs_star_widget_get_property;
+       object_class->set_property = gs_star_widget_set_property;
+
+       /**
+        * GsStarWidget:icon-size:
+        *
+        * Size of the star icons to use in the widget, in pixels.
+        *
+        * Since: 3.38
+        */
+       properties[PROP_ICON_SIZE] =
+                g_param_spec_uint ("icon-size",
+                                   "Icon Size",
+                                   "Size of icons to use, in pixels",
+                                   0, G_MAXUINT, 12,
+                                   G_PARAM_READWRITE);
+
+       /**
+        * GsStarWidget:interactive:
+        *
+        * Whether the widget accepts user input to change #GsStarWidget:rating.
+        *
+        * Since: 3.38
+        */
+       properties[PROP_INTERACTIVE] =
+                g_param_spec_boolean ("interactive",
+                                      "Interactive",
+                                      "Whether the rating is interactive",
+                                      FALSE,
+                                      G_PARAM_READWRITE);
+
+       /**
+        * GsStarWidget:rating:
+        *
+        * The rating to display on the widget, as a percentage. `-1` indicates
+        * that the rating is unknown.
+        *
+        * Since: 3.38
+        */
+       properties[PROP_RATING] =
+                g_param_spec_int ("rating",
+                                  "Rating",
+                                  "Rating, out of 100%, or -1 for unknown",
+                                  -1, 100, -1,
+                                  G_PARAM_READWRITE);
 
        signals [RATING_CHANGED] =
                g_signal_new ("rating-changed",
@@ -159,6 +276,8 @@ gs_star_widget_class_init (GsStarWidgetClass *klass)
                              NULL, NULL, g_cclosure_marshal_VOID__UINT,
                              G_TYPE_NONE, 1, G_TYPE_UINT);
 
+       g_object_class_install_properties (object_class, G_N_ELEMENTS (properties), properties);
+
        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, box1);
 }


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