[gnome-software] Break out the feature tile as a separate widget
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Break out the feature tile as a separate widget
- Date: Sat, 7 Sep 2013 04:49:37 +0000 (UTC)
commit ffaab0aeedb68b537cf6223474e113b14d245cc3
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Sep 7 00:48:54 2013 -0400
Break out the feature tile as a separate widget
At the same time, move to a separate template.
src/Makefile.am | 2 +
src/feature-tile.ui | 62 +++++++++++++
src/gnome-software.gresource.xml | 1 +
src/gnome-software.ui | 52 +-----------
src/gs-feature-tile.c | 184 ++++++++++++++++++++++++++++++++++++++
src/gs-feature-tile.h | 64 +++++++++++++
src/gs-shell-overview.c | 104 ++++++----------------
7 files changed, 340 insertions(+), 129 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index d6c089f..0158216 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -41,6 +41,8 @@ gnome_software_SOURCES = \
gs-app-widget.h \
gs-popular-tile.c \
gs-popular-tile.h \
+ gs-feature-tile.c \
+ gs-feature-tile.h \
gs-box.h \
gs-box.c \
gs-plugin.c \
diff --git a/src/feature-tile.ui b/src/feature-tile.ui
new file mode 100644
index 0000000..2d8673b
--- /dev/null
+++ b/src/feature-tile.ui
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.10 -->
+ <template class="GsFeatureTile" parent="GtkBin">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkButton" id="button">
+ <property name="visible">True</property>
+ <property name="halign">fill</property>
+ <style>
+ <class name="featured-tile"/>
+ </style>
+ <child>
+ <object class="GtkBox" id="box">
+ <property name="visible">True</property>
+ <property name="orientation">horizontal</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkImage" id="image">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <style>
+ <class name="featured-image"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="margin">40</property>
+ <child>
+ <object class="GtkLabel" id="title">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="halign">start</property>
+ <property name="valign">end</property>
+ <attributes>
+ <attribute name="scale" value="2.5"/>
+ <attribute name="weight" value="700"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="subtitle">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/src/gnome-software.gresource.xml b/src/gnome-software.gresource.xml
index c7964ad..c792bd7 100644
--- a/src/gnome-software.gresource.xml
+++ b/src/gnome-software.gresource.xml
@@ -4,6 +4,7 @@
<file preprocess="xml-stripblanks">gnome-software.ui</file>
<file preprocess="xml-stripblanks">app-menu.ui</file>
<file preprocess="xml-stripblanks">popular-tile.ui</file>
+ <file preprocess="xml-stripblanks">feature-tile.ui</file>
<file>gtk-style.css</file>
<file>shadow.png</file>
<file>shadow-active.png</file>
diff --git a/src/gnome-software.ui b/src/gnome-software.ui
index c2c4fc4..d2ad943 100644
--- a/src/gnome-software.ui
+++ b/src/gnome-software.ui
@@ -314,61 +314,11 @@
</packing>
</child>
<child>
- <object class="GtkButton" id="featured_button">
+ <object class="GtkAlignment" id="feature">
<property name="visible">True</property>
- <property name="receives_default">False</property>
<property name="halign">fill</property>
<property name="margin_left">12</property>
<property name="margin_right">12</property>
- <style>
- <class name="featured-tile"/>
- </style>
- <child>
- <object class="GtkBox" id="featured_box">
- <property name="visible">True</property>
- <property name="orientation">horizontal</property>
- <property name="hexpand">True</property>
- <child>
- <object class="GtkImage" id="featured_image">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <style>
- <class name="featured-image"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkBox" id="featured_title_box">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="margin">40</property>
- <child>
- <object class="GtkLabel" id="featured_title">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="halign">start</property>
- <property name="valign">end</property>
- <attributes>
- <attribute name="scale" value="2.5"/>
- <attribute name="weight" value="700"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">True</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="featured_subtitle">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="halign">start</property>
- <property name="valign">start</property>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
</object>
<packing>
<property name="expand">False</property>
diff --git a/src/gs-feature-tile.c b/src/gs-feature-tile.c
new file mode 100644
index 0000000..e5ec014
--- /dev/null
+++ b/src/gs-feature-tile.c
@@ -0,0 +1,184 @@
+/* -*- 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-feature-tile.h"
+
+struct _GsFeatureTilePrivate
+{
+ GsApp *app;
+ GtkWidget *button;
+ GtkWidget *image;
+ GtkWidget *title;
+ GtkWidget *subtitle;
+ GtkCssProvider *provider;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GsFeatureTile, gs_feature_tile, GTK_TYPE_BIN)
+
+enum {
+ SIGNAL_CLICKED,
+ SIGNAL_LAST
+};
+
+static guint signals [SIGNAL_LAST] = { 0 };
+
+GsApp *
+gs_feature_tile_get_app (GsFeatureTile *tile)
+{
+ GsFeatureTilePrivate *priv;
+
+ g_return_val_if_fail (GS_IS_FEATURE_TILE (tile), NULL);
+
+ priv = gs_feature_tile_get_instance_private (tile);
+ return priv->app;
+}
+
+void
+gs_feature_tile_set_app (GsFeatureTile *tile, GsApp *app)
+{
+ GsFeatureTilePrivate *priv;
+ gchar *data;
+
+ g_return_if_fail (GS_IS_FEATURE_TILE (tile));
+ g_return_if_fail (GS_IS_APP (app));
+
+ priv = gs_feature_tile_get_instance_private (tile);
+
+ g_clear_object (&priv->app);
+ priv->app = g_object_ref (app);
+
+ gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image),
+ gs_app_get_featured_pixbuf (priv->app));
+ gtk_label_set_label (GTK_LABEL (priv->title),
+ gs_app_get_metadata_item (app, "featured-title"));
+ gtk_label_set_label (GTK_LABEL (priv->subtitle),
+ gs_app_get_metadata_item (app, "featured-subtitle"));
+ data = g_strdup_printf (
+ ".button.featured-tile {\n"
+ " padding: 0;\n"
+ " border-radius: 0;\n"
+ " border-width: 1px;\n"
+ " border-image: none;\n"
+ " border-color: %s;\n"
+ " color: %s;\n"
+ " -GtkWidget-focus-padding: 0;\n"
+ " outline-color: alpha(%s, 0.75);\n"
+ " outline-style: dashed;\n"
+ " outline-offset: 2px;\n"
+ " background-image: -gtk-gradient(linear,\n"
+ " 0 0, 0 1,\n"
+ " color-stop(0,%s),\n"
+ " color-stop(1,%s));\n"
+ "}\n"
+ ".button.featured-tile:hover {\n"
+ " background-image: -gtk-gradient(linear,\n"
+ " 0 0, 0 1,\n"
+ " color-stop(0,alpha(%s,0.80)),\n"
+ " color-stop(1,alpha(%s,0.80)));\n"
+ "}\n",
+ gs_app_get_metadata_item (app, "featured-stroke-color"),
+ gs_app_get_metadata_item (app, "featured-text-color"),
+ gs_app_get_metadata_item (app, "featured-text-color"),
+ gs_app_get_metadata_item (app, "featured-gradient1-color"),
+ gs_app_get_metadata_item (app, "featured-gradient2-color"),
+ gs_app_get_metadata_item (app, "featured-gradient1-color"),
+ gs_app_get_metadata_item (app, "featured-gradient2-color"));
+
+ gtk_css_provider_load_from_data (priv->provider, data, -1, NULL);
+ g_free (data);
+}
+
+static void
+gs_feature_tile_destroy (GtkWidget *widget)
+{
+ GsFeatureTile *tile = GS_FEATURE_TILE (widget);
+ GsFeatureTilePrivate *priv;
+
+ priv = gs_feature_tile_get_instance_private (tile);
+
+ g_clear_object (&priv->app);
+ g_clear_object (&priv->provider);
+
+ GTK_WIDGET_CLASS (gs_feature_tile_parent_class)->destroy (widget);
+}
+
+static void
+button_clicked (GsFeatureTile *tile)
+{
+ g_signal_emit (tile, signals[SIGNAL_CLICKED], 0);
+}
+
+static void
+gs_feature_tile_init (GsFeatureTile *tile)
+{
+ GsFeatureTilePrivate *priv;
+
+ gtk_widget_set_has_window (GTK_WIDGET (tile), FALSE);
+ gtk_widget_init_template (GTK_WIDGET (tile));
+ priv = gs_feature_tile_get_instance_private (tile);
+ g_signal_connect_swapped (priv->button, "clicked",
+ G_CALLBACK (button_clicked), tile);
+
+ priv->provider = gtk_css_provider_new ();
+ gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
+ GTK_STYLE_PROVIDER (priv->provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+}
+
+static void
+gs_feature_tile_class_init (GsFeatureTileClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ widget_class->destroy = gs_feature_tile_destroy;
+
+ signals [SIGNAL_CLICKED] =
+ g_signal_new ("clicked",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsFeatureTileClass, clicked),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/software/feature-tile.ui");
+
+ gtk_widget_class_bind_template_child_private (widget_class, GsFeatureTile, button);
+ gtk_widget_class_bind_template_child_private (widget_class, GsFeatureTile, image);
+ gtk_widget_class_bind_template_child_private (widget_class, GsFeatureTile, title);
+ gtk_widget_class_bind_template_child_private (widget_class, GsFeatureTile, subtitle);
+}
+
+GtkWidget *
+gs_feature_tile_new (GsApp *app)
+{
+ GsFeatureTile *tile;
+
+ tile = g_object_new (GS_TYPE_FEATURE_TILE, NULL);
+ gs_feature_tile_set_app (tile, app);
+
+ return GTK_WIDGET (tile);
+}
+
diff --git a/src/gs-feature-tile.h b/src/gs-feature-tile.h
new file mode 100644
index 0000000..e52a0b5
--- /dev/null
+++ b/src/gs-feature-tile.h
@@ -0,0 +1,64 @@
+/* -*- 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_FEATURE_TILE_H
+#define GS_FEATURE_TILE_H
+
+#include <gtk/gtk.h>
+
+#include "gs-app.h"
+
+#define GS_TYPE_FEATURE_TILE (gs_feature_tile_get_type())
+#define GS_FEATURE_TILE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GS_TYPE_FEATURE_TILE,
GsFeatureTile))
+#define GS_FEATURE_TILE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls), GS_TYPE_FEATURE_TILE,
GsFeatureTileClass))
+#define GS_IS_FEATURE_TILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GS_TYPE_FEATURE_TILE))
+#define GS_IS_FEATURE_TILE_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls), GS_TYPE_FEATURE_TILE))
+#define GS_FEATURE_TILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GS_TYPE_FEATURE_TILE,
GsFeatureTileClass))
+
+G_BEGIN_DECLS
+
+typedef struct _GsFeatureTile GsFeatureTile;
+typedef struct _GsFeatureTileClass GsFeatureTileClass;
+typedef struct _GsFeatureTilePrivate GsFeatureTilePrivate;
+
+struct _GsFeatureTile
+{
+ GtkBin parent;
+ GsFeatureTilePrivate *priv;
+};
+
+struct _GsFeatureTileClass
+{
+ GtkBinClass parent_class;
+
+ void (*clicked) (GsFeatureTile *feature_tile);
+};
+
+GType gs_feature_tile_get_type (void);
+GtkWidget *gs_feature_tile_new (GsApp *app);
+GsApp *gs_feature_tile_get_app (GsFeatureTile *feature_tile);
+void gs_feature_tile_set_app (GsFeatureTile *feature_tile,
+ GsApp *app);
+
+G_END_DECLS
+
+#endif /* GS_FEATURE_TILE_H */
+
diff --git a/src/gs-shell-overview.c b/src/gs-shell-overview.c
index ea5deff..9f33986 100644
--- a/src/gs-shell-overview.c
+++ b/src/gs-shell-overview.c
@@ -28,6 +28,7 @@
#include "gs-app.h"
#include "gs-category.h"
#include "gs-popular-tile.h"
+#include "gs-feature-tile.h"
#include "gs-utils.h"
static void gs_shell_overview_finalize (GObject *object);
@@ -64,16 +65,6 @@ gs_shell_overview_invalidate (GsShellOverview *shell_overview)
}
static void
-app_tile_clicked (GtkButton *button, gpointer data)
-{
- GsShellOverview *shell_overview = GS_SHELL_OVERVIEW (data);
- GsApp *app;
-
- app = g_object_get_data (G_OBJECT (button), "app");
- gs_shell_show_app (shell_overview->priv->shell, app);
-}
-
-static void
popular_tile_clicked (GsPopularTile *tile, gpointer data)
{
GsShellOverview *shell = GS_SHELL_OVERVIEW (data);
@@ -155,30 +146,31 @@ create_category_tile (GsShellOverview *shell_overview, GsCategory *category)
return button;
}
-/**
- * gs_shell_overview_get_featured_cb:
- **/
+static void
+feature_tile_clicked (GsFeatureTile *tile, gpointer data)
+{
+ GsShellOverview *shell = GS_SHELL_OVERVIEW (data);
+ GsApp *app;
+
+ app = gs_feature_tile_get_app (tile);
+ gs_shell_show_app (shell->priv->shell, app);
+}
+
static void
gs_shell_overview_get_featured_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
- GdkPixbuf *pixbuf;
- GError *error = NULL;
- GList *list;
- GsApp *app;
- GsShellOverview *shell_overview = GS_SHELL_OVERVIEW (user_data);
- GsShellOverviewPrivate *priv = shell_overview->priv;
+ GsShellOverview *shell = GS_SHELL_OVERVIEW (user_data);
+ GsShellOverviewPrivate *priv = shell->priv;
GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source_object);
- GtkImage *image;
- GtkWidget *button;
- GtkWidget *widget;
- const gchar *text;
- gchar *css;
+ GtkWidget *tile;
+ GtkWidget *box;
+ GList *list;
+ GError *error = NULL;
+ GsApp *app;
- list = gs_plugin_loader_get_featured_finish (plugin_loader,
- res,
- &error);
+ list = gs_plugin_loader_get_featured_finish (plugin_loader, res, &error);
if (list == NULL) {
g_warning ("failed to get featured apps: %s", error->message);
g_error_free (error);
@@ -187,64 +179,20 @@ gs_shell_overview_get_featured_cb (GObject *source_object,
/* at the moment, we only care about the first app */
app = GS_APP (list->data);
- image = GTK_IMAGE (gtk_builder_get_object (priv->builder, "featured_image"));
- pixbuf = gs_app_get_featured_pixbuf (app);
- gtk_image_set_from_pixbuf (image, pixbuf);
-
- widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "featured_title"));
- text = gs_app_get_metadata_item (app, "featured-title");
- gtk_label_set_label (GTK_LABEL (widget), text);
+ box = GTK_WIDGET (gtk_builder_get_object (priv->builder, "feature"));
+ tile = gs_feature_tile_new (app);
+ g_signal_connect (tile, "clicked",
+ G_CALLBACK (feature_tile_clicked), shell);
- widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "featured_subtitle"));
- text = gs_app_get_metadata_item (app, "featured-subtitle");
- gtk_label_set_label (GTK_LABEL (widget), text);
-
- button = GTK_WIDGET (gtk_builder_get_object (priv->builder, "featured_button"));
- g_object_set_data_full (G_OBJECT (button), "app", app, g_object_unref);
- g_signal_connect (button, "clicked",
- G_CALLBACK (app_tile_clicked), shell_overview);
-
- css = g_strdup_printf (
- ".button.featured-tile {\n"
- " padding: 0;\n"
- " border-radius: 0;\n"
- " border-width: 1px;\n"
- " border-image: none;\n"
- " border-color: %s;\n"
- " color: %s;\n"
- " -GtkWidget-focus-padding: 0;\n"
- " outline-color: alpha(%s, 0.75);\n"
- " outline-style: dashed;\n"
- " outline-offset: 2px;\n"
- " background-image: -gtk-gradient(linear,\n"
- " 0 0, 0 1,\n"
- " color-stop(0,%s),\n"
- " color-stop(1,%s));\n"
- "}\n"
- ".button.featured-tile:hover {\n"
- " background-image: -gtk-gradient(linear,\n"
- " 0 0, 0 1,\n"
- " color-stop(0,alpha(%s,0.80)),\n"
- " color-stop(1,alpha(%s,0.80)));\n"
- "}\n",
- gs_app_get_metadata_item (app, "featured-stroke-color"),
- gs_app_get_metadata_item (app, "featured-text-color"),
- gs_app_get_metadata_item (app, "featured-text-color"),
- gs_app_get_metadata_item (app, "featured-gradient1-color"),
- gs_app_get_metadata_item (app, "featured-gradient2-color"),
- gs_app_get_metadata_item (app, "featured-gradient1-color"),
- gs_app_get_metadata_item (app, "featured-gradient2-color"));
-
- gtk_css_provider_load_from_data (priv->feature_style, css, -1, NULL);
-
- g_free (css);
+ gs_container_remove_all (GTK_CONTAINER (box));
+ gtk_container_add (GTK_CONTAINER (box), tile);
out:
g_list_free (list);
priv->refresh_count--;
if (priv->refresh_count == 0)
- g_signal_emit (shell_overview, signals[SIGNAL_REFRESHED], 0);
+ g_signal_emit (shell, signals[SIGNAL_REFRESHED], 0);
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]