[gnome-software] Use a template for GsAppWidget



commit 441cfae291363fccf32140c6dfa8402ca3ee3d76
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Sep 7 12:27:16 2013 -0400

    Use a template for GsAppWidget

 src/app-widget.ui                |  118 ++++++++++++++++++++
 src/gnome-software.gresource.xml |    1 +
 src/gs-app-widget.c              |  228 ++++++++++++--------------------------
 src/gs-app-widget.h              |    4 +-
 4 files changed, 192 insertions(+), 159 deletions(-)
---
diff --git a/src/app-widget.ui b/src/app-widget.ui
new file mode 100644
index 0000000..e22a433
--- /dev/null
+++ b/src/app-widget.ui
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.10 -->
+  <template class="GsAppWidget" parent="GtkBin">
+    <property name="visible">True</property>
+    <property name="margin">9</property>
+    <child>
+      <object class="GtkBox" id="box">
+        <property name="visible">True</property>
+        <property name="orientation">horizontal</property>
+        <property name="spacing">3</property>
+        <child>
+          <object class="GtkImage" id="image">
+            <property name="visible">True</property>
+            <property name="pixel_size">64</property>
+            <property name="margin-right">9</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="name_box">
+            <property name="visible">True</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkLabel" id="name_label">
+                <property name="visible">True</property>
+                <property name="wrap">True</property>
+                <property name="max_width_chars">20</property>
+                <property name="xalign">0.0</property>
+                <property name="yalign">0.5</property>
+                <property name="width_request">200</property>
+                <attributes>
+                  <attribute name="weight" value="bold"/>
+                </attributes>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="version_label">
+                <property name="visible">True</property>
+                <property name="xalign">0.0</property>
+                <property name="yalign">0.5</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="description_label">
+            <property name="visible">True</property>
+            <property name="halign">fill</property>
+            <property name="xalign">0</property>
+            <property name="yalign">0.5</property>
+            <property name="wrap">True</property>
+            <property name="ellipsize">end</property>
+            <property name="lines">3</property>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="button_box">
+            <property name="visible">True</property>
+            <property name="orientation">horizontal</property>
+            <property name="width_request">200</property>
+            <property name="halign">end</property>
+            <property name="valign">center</property>
+            <child>
+              <object class="GtkButton" id="button">
+                <property name="margin_right">9</property>
+                <property name="width_request">100</property>
+                <property name="halign">end</property>
+              </object>
+              <packing>
+                <property name="pack_type">end</property>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkSpinner" id="spinner">
+                <property name="margin_left">6</property>
+                <property name="margin_right">6</property>
+                <property name="halign">end</property>
+              </object>
+              <packing>
+                <property name="pack_type">end</property>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="pack_type">end</property>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/src/gnome-software.gresource.xml b/src/gnome-software.gresource.xml
index e5166ac..97ffd37 100644
--- a/src/gnome-software.gresource.xml
+++ b/src/gnome-software.gresource.xml
@@ -6,6 +6,7 @@
   <file preprocess="xml-stripblanks">popular-tile.ui</file>
   <file preprocess="xml-stripblanks">feature-tile.ui</file>
   <file preprocess="xml-stripblanks">category-tile.ui</file>
+  <file preprocess="xml-stripblanks">app-widget.ui</file>
   <file>gtk-style.css</file>
   <file>shadow.png</file>
   <file>shadow-active.png</file>
diff --git a/src/gs-app-widget.c b/src/gs-app-widget.c
index ea592a9..4008e2f 100644
--- a/src/gs-app-widget.c
+++ b/src/gs-app-widget.c
@@ -31,19 +31,18 @@ struct _GsAppWidgetPrivate
 {
        ChMarkdown      *markdown;
        GsApp           *app;
-       GtkWidget       *widget_button;
-       GtkWidget       *widget_description;
-       GtkWidget       *widget_image;
-       GtkWidget       *widget_name;
-       GtkWidget       *widget_spinner;
-       GtkWidget       *widget_version;
+       GtkWidget       *image;
+       GtkWidget       *name_box;
+       GtkWidget       *name_label;
+       GtkWidget       *version_label;
+       GtkWidget       *description_label;
+       GtkWidget       *button_box;
+       GtkWidget       *button;
+       GtkWidget       *spinner;
         gboolean         colorful;
 };
 
-
-#define        GS_APP_WIDGET_MAX_LINES_NO_EXPANDER     3
-
-G_DEFINE_TYPE (GsAppWidget, gs_app_widget, GTK_TYPE_BOX)
+G_DEFINE_TYPE_WITH_PRIVATE (GsAppWidget, gs_app_widget, GTK_TYPE_BIN)
 
 enum {
        SIGNAL_BUTTON_CLICKED,
@@ -97,7 +96,6 @@ gs_app_widget_refresh (GsAppWidget *app_widget)
 {
        GsAppWidgetPrivate *priv = app_widget->priv;
        GtkStyleContext *context;
-       GtkWidget *box;
        const gchar *tmp = NULL;
        GString *str = NULL;
 
@@ -105,77 +103,73 @@ gs_app_widget_refresh (GsAppWidget *app_widget)
                return;
 
        /* get the main body text */
-       if (gs_app_get_state (app_widget->priv->app) == GS_APP_STATE_UPDATABLE)
-               tmp = gs_app_get_metadata_item (app_widget->priv->app, "update-details");
+       if (gs_app_get_state (priv->app) == GS_APP_STATE_UPDATABLE)
+               tmp = gs_app_get_metadata_item (priv->app, "update-details");
        if (tmp == NULL)
-               tmp = gs_app_get_description (app_widget->priv->app);
+               tmp = gs_app_get_description (priv->app);
        if (tmp == NULL)
-               tmp = gs_app_get_summary (app_widget->priv->app);
+               tmp = gs_app_get_summary (priv->app);
        if (tmp == NULL)
-               tmp = gs_app_get_name (app_widget->priv->app);
+               tmp = gs_app_get_name (priv->app);
 
        /* join the lines*/
        str = g_string_new (tmp);
        _g_string_replace (str, "\n", " ");
 
-       gtk_label_set_label (GTK_LABEL (priv->widget_description), str->str);
-       gtk_label_set_label (GTK_LABEL (priv->widget_name),
-                            gs_app_get_name (priv->app));
-       gtk_label_set_label (GTK_LABEL (priv->widget_version),
+       gtk_label_set_label (GTK_LABEL (priv->description_label), str->str);
+       g_string_free (str, TRUE);
+
+       gtk_label_set_label (GTK_LABEL (priv->name_label),
+                             gs_app_get_name (priv->app));
+       gtk_label_set_label (GTK_LABEL (priv->version_label),
                             gs_app_get_version (priv->app));
        if (gs_app_get_pixbuf (priv->app))
-               gtk_image_set_from_pixbuf (GTK_IMAGE (priv->widget_image),
+               gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image),
                                           gs_app_get_pixbuf (priv->app));
-       gtk_widget_set_visible (priv->widget_name, TRUE);
-       gtk_widget_set_visible (priv->widget_version, TRUE);
-       gtk_widget_set_visible (priv->widget_image, TRUE);
-       gtk_widget_set_visible (priv->widget_button, TRUE);
-       gtk_widget_set_sensitive (priv->widget_button, TRUE);
-
-       /* show / hide widgets depending on kind */
-       context = gtk_widget_get_style_context (priv->widget_button);
+       gtk_widget_set_visible (priv->button, TRUE);
+       gtk_widget_set_sensitive (priv->button, TRUE);
+
+       context = gtk_widget_get_style_context (priv->button);
        gtk_style_context_remove_class (context, "destructive-action");
 
        switch (gs_app_get_state (app_widget->priv->app)) {
        case GS_APP_STATE_AVAILABLE:
-               gtk_widget_set_visible (priv->widget_spinner, FALSE);
-               gtk_widget_set_visible (priv->widget_button, TRUE);
-               gtk_button_set_label (GTK_BUTTON (priv->widget_button), _("Install"));
+               gtk_widget_set_visible (priv->spinner, FALSE);
+               gtk_widget_set_visible (priv->button, TRUE);
+               gtk_button_set_label (GTK_BUTTON (priv->button), _("Install"));
                break;
        case GS_APP_STATE_INSTALLED:
-               gtk_widget_set_visible (priv->widget_spinner, FALSE);
-               gtk_widget_set_visible (priv->widget_button, TRUE);
-               gtk_button_set_label (GTK_BUTTON (priv->widget_button), _("Remove"));
+               gtk_widget_set_visible (priv->spinner, FALSE);
+               gtk_widget_set_visible (priv->button, TRUE);
+               gtk_button_set_label (GTK_BUTTON (priv->button), _("Remove"));
                 if (priv->colorful)
                        gtk_style_context_add_class (context, "destructive-action");
                break;
        case GS_APP_STATE_UPDATABLE:
-               gtk_widget_set_visible (priv->widget_spinner, FALSE);
-               gtk_widget_set_visible (priv->widget_button, FALSE);
-               gtk_button_set_label (GTK_BUTTON (priv->widget_button), _("Update"));
+               gtk_widget_set_visible (priv->spinner, FALSE);
+               gtk_widget_set_visible (priv->button, FALSE);
+               gtk_button_set_label (GTK_BUTTON (priv->button), _("Update"));
                break;
        case GS_APP_STATE_INSTALLING:
-               gtk_spinner_start (GTK_SPINNER (priv->widget_spinner));
-               gtk_widget_set_visible (priv->widget_spinner, TRUE);
-               gtk_widget_set_visible (priv->widget_button, TRUE);
-               gtk_widget_set_sensitive (priv->widget_button, FALSE);
-               gtk_button_set_label (GTK_BUTTON (priv->widget_button), _("Installing"));
+               gtk_spinner_start (GTK_SPINNER (priv->spinner));
+               gtk_widget_set_visible (priv->spinner, TRUE);
+               gtk_widget_set_visible (priv->button, TRUE);
+               gtk_widget_set_sensitive (priv->button, FALSE);
+               gtk_button_set_label (GTK_BUTTON (priv->button), _("Installing"));
                break;
        case GS_APP_STATE_REMOVING:
-               gtk_spinner_start (GTK_SPINNER (priv->widget_spinner));
-               gtk_widget_set_visible (priv->widget_spinner, TRUE);
-               gtk_widget_set_visible (priv->widget_button, TRUE);
-               gtk_widget_set_sensitive (priv->widget_button, FALSE);
-               gtk_button_set_label (GTK_BUTTON (priv->widget_button), _("Removing"));
+               gtk_spinner_start (GTK_SPINNER (priv->spinner));
+               gtk_widget_set_visible (priv->spinner, TRUE);
+               gtk_widget_set_visible (priv->button, TRUE);
+               gtk_widget_set_sensitive (priv->button, FALSE);
+               gtk_button_set_label (GTK_BUTTON (priv->button), _("Removing"));
                break;
        default:
-               gtk_widget_set_visible (priv->widget_button, FALSE);
+               gtk_widget_set_visible (priv->button, FALSE);
                break;
        }
-       box = gtk_widget_get_parent (priv->widget_button);
-       gtk_widget_set_visible (box, gtk_widget_get_visible (priv->widget_spinner) ||
-                                    gtk_widget_get_visible (priv->widget_button));
-       g_string_free (str, TRUE);
+       gtk_widget_set_visible (priv->button_box, gtk_widget_get_visible (priv->spinner) ||
+                                                 gtk_widget_get_visible (priv->button));
 }
 
 /**
@@ -213,10 +207,8 @@ gs_app_widget_destroy (GtkWidget *object)
        GsAppWidget *app_widget = GS_APP_WIDGET (object);
        GsAppWidgetPrivate *priv = app_widget->priv;
 
-       if (priv->markdown != NULL)
-               g_clear_object (&priv->markdown);
-       if (priv->app != NULL)
-               g_clear_object (&priv->app);
+       g_clear_object (&priv->markdown);
+       g_clear_object (&priv->app);
 
        GTK_WIDGET_CLASS (gs_app_widget_parent_class)->destroy (object);
 }
@@ -226,6 +218,7 @@ gs_app_widget_class_init (GsAppWidgetClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
        widget_class->destroy = gs_app_widget_destroy;
 
        signals [SIGNAL_BUTTON_CLICKED] =
@@ -235,112 +228,40 @@ gs_app_widget_class_init (GsAppWidgetClass *klass)
                              NULL, NULL, g_cclosure_marshal_VOID__VOID,
                              G_TYPE_NONE, 0);
 
-       g_type_class_add_private (klass, sizeof (GsAppWidgetPrivate));
+        gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/software/app-widget.ui");
+
+        gtk_widget_class_bind_template_child_private (widget_class, GsAppWidget, image);
+        gtk_widget_class_bind_template_child_private (widget_class, GsAppWidget, name_box);
+        gtk_widget_class_bind_template_child_private (widget_class, GsAppWidget, name_label);
+        gtk_widget_class_bind_template_child_private (widget_class, GsAppWidget, version_label);
+        gtk_widget_class_bind_template_child_private (widget_class, GsAppWidget, description_label);
+        gtk_widget_class_bind_template_child_private (widget_class, GsAppWidget, button_box);
+        gtk_widget_class_bind_template_child_private (widget_class, GsAppWidget, button);
+        gtk_widget_class_bind_template_child_private (widget_class, GsAppWidget, spinner);
 }
 
-/**
- * gs_app_widget_button_clicked_cb:
- **/
 static void
-gs_app_widget_button_clicked_cb (GtkWidget *widget, GsAppWidget *app_widget)
+button_clicked (GtkWidget *widget, GsAppWidget *app_widget)
 {
        g_signal_emit (app_widget, signals[SIGNAL_BUTTON_CLICKED], 0);
 }
 
-/**
- * gs_app_widget_init:
- **/
 static void
 gs_app_widget_init (GsAppWidget *app_widget)
 {
        GsAppWidgetPrivate *priv;
-       GtkWidget *box;
-       PangoAttrList *attr_list;
 
-       g_return_if_fail (GS_IS_APP_WIDGET (app_widget));
-       app_widget->priv = G_TYPE_INSTANCE_GET_PRIVATE (app_widget,
-                                                       GS_TYPE_APP_WIDGET,
-                                                       GsAppWidgetPrivate);
-       priv = app_widget->priv;
-       priv->markdown = ch_markdown_new ();
+       priv = gs_app_widget_get_instance_private (app_widget);
+       app_widget->priv = priv;
 
+        gtk_widget_set_has_window (GTK_WIDGET (app_widget), FALSE);
+        gtk_widget_init_template (GTK_WIDGET (app_widget));
+
+       priv->markdown = ch_markdown_new ();
         priv->colorful = TRUE;
 
-       /* set defaults */
-       gtk_box_set_spacing (GTK_BOX (app_widget), 3);
-       g_object_set (app_widget, "margin", 9, NULL);
-
-       /* pixbuf */
-       priv->widget_image = gtk_image_new ();
-       gtk_image_set_pixel_size (GTK_IMAGE (priv->widget_image), 64);
-
-       gtk_widget_set_margin_right (priv->widget_image, 9);
-       gtk_widget_set_valign (priv->widget_image, GTK_ALIGN_START);
-       gtk_box_pack_start (GTK_BOX (app_widget), priv->widget_image, FALSE, FALSE, 0);
-
-       /* name > version */
-       box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-       gtk_widget_set_visible (box, TRUE);
-       priv->widget_name = gtk_label_new ("name");
-       gtk_label_set_ellipsize (GTK_LABEL (priv->widget_name),
-                                PANGO_ELLIPSIZE_NONE);
-       gtk_label_set_line_wrap (GTK_LABEL (priv->widget_name), TRUE);
-       gtk_label_set_max_width_chars (GTK_LABEL (priv->widget_name), 20);
-       gtk_misc_set_alignment (GTK_MISC (priv->widget_name), 0.0, 0.5);
-       gtk_widget_set_size_request (priv->widget_name, 200, -1);
-       attr_list = pango_attr_list_new ();
-       pango_attr_list_insert (attr_list,
-                               pango_attr_weight_new (PANGO_WEIGHT_BOLD));
-       gtk_label_set_attributes (GTK_LABEL (priv->widget_name), attr_list);
-       pango_attr_list_unref (attr_list);
-       priv->widget_version = gtk_label_new ("version");
-       gtk_misc_set_alignment (GTK_MISC (priv->widget_version), 0.0, 0.5);
-       gtk_box_pack_start (GTK_BOX (box), priv->widget_name, FALSE, FALSE, 0);
-       gtk_box_pack_start (GTK_BOX (box), priv->widget_version, FALSE, FALSE, 6);
-       gtk_box_pack_start (GTK_BOX (app_widget), box, FALSE, TRUE, 0);
-
-       /* description */
-       priv->widget_description = gtk_label_new (NULL);
-        gtk_widget_show (priv->widget_description);
-        gtk_label_set_line_wrap (GTK_LABEL (priv->widget_description), TRUE);
-#if GTK_CHECK_VERSION (3, 9, 13)
-        gtk_label_set_lines (GTK_LABEL (priv->widget_description), 3);
-#endif
-       gtk_widget_set_hexpand (priv->widget_description, TRUE);
-       gtk_widget_set_halign (priv->widget_description, GTK_ALIGN_FILL);
-       gtk_misc_set_alignment (GTK_MISC (priv->widget_description), 0.0, 0.5);
-       gtk_label_set_ellipsize (GTK_LABEL (priv->widget_description), PANGO_ELLIPSIZE_END);
-
-       gtk_box_pack_start (GTK_BOX (app_widget), priv->widget_description, TRUE, TRUE, 0);
-
-       /* button */
-       priv->widget_button = gtk_button_new_with_label ("button");
-       gtk_widget_set_margin_right (priv->widget_button, 9);
-       gtk_widget_set_size_request (priv->widget_button, 100, -1);
-       gtk_widget_set_vexpand (priv->widget_button, FALSE);
-       gtk_widget_set_hexpand (priv->widget_button, FALSE);
-       gtk_widget_set_halign (priv->widget_button, GTK_ALIGN_END);
-       g_signal_connect (priv->widget_button, "clicked",
-                         G_CALLBACK (gs_app_widget_button_clicked_cb), app_widget);
-
-       /* spinner */
-       priv->widget_spinner = gtk_spinner_new ();
-       gtk_widget_set_halign (priv->widget_spinner, GTK_ALIGN_END);
-       gtk_widget_set_valign (priv->widget_spinner, GTK_ALIGN_CENTER);
-       gtk_widget_set_margin_left (priv->widget_spinner, 6);
-       gtk_widget_set_margin_right (priv->widget_spinner, 6);
-
-       box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
-       gtk_widget_set_size_request (box, 200, -1);
-       gtk_widget_set_halign (box, GTK_ALIGN_END);
-       gtk_widget_set_valign (box, GTK_ALIGN_CENTER);
-       gtk_widget_set_visible (box, TRUE);
-       gtk_box_pack_end (GTK_BOX (box), priv->widget_button, FALSE, FALSE, 0);
-       gtk_box_pack_end (GTK_BOX (box), priv->widget_spinner, FALSE, FALSE, 0);
-       gtk_box_pack_end (GTK_BOX (app_widget), box, FALSE, FALSE, 0);
-
-       /* refresh */
-       gs_app_widget_refresh (app_widget);
+       g_signal_connect (priv->button, "clicked",
+                         G_CALLBACK (button_clicked), app_widget);
 }
 
 void
@@ -348,12 +269,8 @@ gs_app_widget_set_size_groups (GsAppWidget  *app_widget,
                               GtkSizeGroup *image,
                               GtkSizeGroup *name)
 {
-       GtkWidget *box;
-
-       gtk_size_group_add_widget (image, app_widget->priv->widget_image);
-
-       box = gtk_widget_get_parent (app_widget->priv->widget_name);
-       gtk_size_group_add_widget (name, box);
+       gtk_size_group_add_widget (image, app_widget->priv->image);
+       gtk_size_group_add_widget (name, app_widget->priv->name_box);
 }
 
 void
@@ -363,9 +280,6 @@ gs_app_widget_set_colorful (GsAppWidget *app_widget,
         app_widget->priv->colorful = colorful;
 }
 
-/**
- * gs_app_widget_new:
- **/
 GtkWidget *
 gs_app_widget_new (void)
 {
diff --git a/src/gs-app-widget.h b/src/gs-app-widget.h
index 9bb7bfa..ed6526b 100644
--- a/src/gs-app-widget.h
+++ b/src/gs-app-widget.h
@@ -41,7 +41,7 @@ typedef struct _GsAppWidgetPrivate            GsAppWidgetPrivate;
 
 struct _GsAppWidget
 {
-       GtkBox                   parent;
+       GtkBin                   parent;
 
        /*< private >*/
        GsAppWidgetPrivate      *priv;
@@ -49,7 +49,7 @@ struct _GsAppWidget
 
 struct _GsAppWidgetClass
 {
-       GtkBoxClass              parent_class;
+       GtkBinClass              parent_class;
        void                    (*button_clicked)       (GsAppWidget    *app_widget);
        void                    (*read_more_clicked)    (GsAppWidget    *app_widget);
 };


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