[gnome-software] Add an overview mode for applications
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Add an overview mode for applications
- Date: Tue, 9 Apr 2013 15:56:29 +0000 (UTC)
commit 37b9ed59aae82415fa6520439177a1d21058eabf
Author: Richard Hughes <richard hughsie com>
Date: Tue Apr 9 15:57:04 2013 +0100
Add an overview mode for applications
Very much WIP.
src/gnome-software.ui | 294 +++++++++++++++++++++++++++++++++++++++++++++++-
src/gs-main.c | 144 +++++++++++++++++++++++-
2 files changed, 425 insertions(+), 13 deletions(-)
---
diff --git a/src/gnome-software.ui b/src/gnome-software.ui
index 9ca795e..f4be923 100644
--- a/src/gnome-software.ui
+++ b/src/gnome-software.ui
@@ -3,8 +3,8 @@
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkListStore" id="liststore_popular">
<columns>
- <!-- column-name package_id -->
- <column type="gchararray"/>
+ <!-- column-name app -->
+ <column type="GObject"/>
<!-- column-name markup -->
<column type="gchararray"/>
<!-- column-name pixbuf -->
@@ -36,6 +36,20 @@
<property name="can_focus">False</property>
<property name="spacing">21</property>
<child>
+ <object class="GtkButton" id="button_back">
+ <property name="label">gtk-go-back</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkLabel" id="label_update_all">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -43,11 +57,11 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">0</property>
+ <property name="position">1</property>
</packing>
</child>
<child>
- <object class="GtkButtonBox" id="buttonbox1">
+ <object class="GtkButtonBox" id="buttonbox_main">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">center</property>
@@ -124,7 +138,107 @@
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">1</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox_detail">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="layout_style">center</property>
+ <style>
+ <class name="linked"/>
+ </style>
+ <child>
+ <object class="GtkToggleButton" id="button_overview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="active">True</property>
+ <style>
+ <class name="toolbar-primary-buttons-software"/>
+ </style>
+ <child>
+ <object class="GtkLabel" id="label_button_overview">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Overview</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="GtkToggleButton" id="button_reviews">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <style>
+ <class name="toolbar-primary-buttons-software"/>
+ </style>
+ <child>
+ <object class="GtkLabel" id="label_button_reviews">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Reviews</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="GtkToggleButton" id="button_related">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <style>
+ <class name="toolbar-primary-buttons-software"/>
+ </style>
+ <child>
+ <object class="GtkLabel" id="label_button_related">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Related</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_install">
+ <property name="label" translatable="yes">Install</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <style>
+ <class name="suggested-action"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
</packing>
</child>
<child>
@@ -140,7 +254,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">2</property>
+ <property name="position">5</property>
</packing>
</child>
</object>
@@ -316,7 +430,6 @@
<property name="can_focus">True</property>
<property name="hscroll_policy">natural</property>
<property name="vscroll_policy">natural</property>
- <property name="selection_mode">none</property>
<property name="model">liststore_popular</property>
</object>
<packing>
@@ -492,6 +605,173 @@
<property name="tab_fill">False</property>
</packing>
</child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport" id="viewport3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="margin_left">120</property>
+ <property name="margin_right">120</property>
+ <property name="border_width">15</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">18</property>
+ <child>
+ <object class="GtkImage" id="image_detail_icon">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="stock">gtk-justify-center</property>
+ <property name="icon-size">6</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="image_detail_screenshot">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_top">12</property>
+ <property name="margin_bottom">30</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.50999999046325684</property>
+ <property name="stock">gtk-justify-center</property>
+ <property name="icon-size">6</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">3</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_detail_stars">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="xalign">1</property>
+ <property name="label">[***_]</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_detail_header">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Description</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="1.2"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ <property name="width">3</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_detail_description">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Shotwell is a digital photo organiser
that runs on Linux. It is the default photo manager in Ubuntu and Fedora.</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ <property name="width">3</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_detail_summary">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label">Open Source photo management for GNOME</property>
+ <attributes>
+ <attribute name="scale" value="1.2"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_detail_name">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label">Shotwell</property>
+ <attributes>
+ <attribute name="font-desc" value="<Enter Value> 10"/>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="1.3999999999999999"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label">Detail Overview</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="expand">True</property>
diff --git a/src/gs-main.c b/src/gs-main.c
index 797d69a..6bb37c2 100644
--- a/src/gs-main.c
+++ b/src/gs-main.c
@@ -37,11 +37,12 @@ typedef enum {
GS_MAIN_MODE_NEW,
GS_MAIN_MODE_INSTALLED,
GS_MAIN_MODE_UPDATES,
- GS_MAIN_MODE_WAITING
+ GS_MAIN_MODE_WAITING,
+ GS_MAIN_MODE_DETAILS
} GsMainMode;
enum {
- COLUMN_POPULAR_PACKAGE_ID,
+ COLUMN_POPULAR_APP,
COLUMN_POPULAR_MARKUP,
COLUMN_POPULAR_PIXBUF,
COLUMN_POPULAR_LAST
@@ -60,6 +61,7 @@ typedef struct {
GtkCssProvider *provider;
gboolean ignore_primary_buttons;
GsPluginLoader *plugin_loader;
+ guint tab_back_id;
} GsMainPrivate;
static void gs_main_set_overview_mode_ui (GsMainPrivate *priv, GsMainMode mode);
@@ -607,7 +609,7 @@ gs_main_get_popular_cb (GObject *source_object,
gtk_list_store_append (liststore, &iter);
gtk_list_store_set (liststore,
&iter,
- COLUMN_POPULAR_PACKAGE_ID, gs_app_get_metadata_item (app, "package-name"),
+ COLUMN_POPULAR_APP, app,
COLUMN_POPULAR_MARKUP, gs_app_get_name (app),
COLUMN_POPULAR_PIXBUF, gs_app_get_pixbuf (app),
-1);
@@ -644,6 +646,37 @@ gs_main_set_overview_mode_ui (GsMainPrivate *priv, GsMainMode mode)
GtkWidget *widget;
priv->ignore_primary_buttons = TRUE;
+
+ switch (mode) {
+ case GS_MAIN_MODE_DETAILS:
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "buttonbox_main"));
+ gtk_widget_set_visible (widget, FALSE);
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "buttonbox_detail"));
+ gtk_widget_set_visible (widget, TRUE);
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_back"));
+ gtk_widget_set_visible (widget, TRUE);
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_install"));
+ gtk_widget_set_visible (widget, FALSE);
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_update_all"));
+ gtk_widget_set_visible (widget, FALSE);
+ break;
+ case GS_MAIN_MODE_NEW:
+ case GS_MAIN_MODE_INSTALLED:
+ case GS_MAIN_MODE_UPDATES:
+ case GS_MAIN_MODE_WAITING:
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "buttonbox_main"));
+ gtk_widget_set_visible (widget, TRUE);
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "buttonbox_detail"));
+ gtk_widget_set_visible (widget, FALSE);
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_back"));
+ gtk_widget_set_visible (widget, FALSE);
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_install"));
+ gtk_widget_set_visible (widget, FALSE);
+ break;
+ default:
+ break;
+ }
+
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_new"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), mode == GS_MAIN_MODE_NEW);
@@ -699,6 +732,16 @@ gs_main_set_overview_mode_ui (GsMainPrivate *priv, GsMainMode mode)
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "spinner_waiting"));
gtk_spinner_start (GTK_SPINNER (widget));
break;
+ case GS_MAIN_MODE_DETAILS:
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_detail_name"));
+ gtk_widget_hide (widget);
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_detail_summary"));
+ gtk_widget_hide (widget);
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_detail_description"));
+ gtk_widget_hide (widget);
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "image_detail_screenshot"));
+ gtk_widget_hide (widget);
+ break;
default:
g_assert_not_reached ();
}
@@ -713,8 +756,12 @@ gs_main_set_overview_mode_ui (GsMainPrivate *priv, GsMainMode mode)
* gs_main_set_overview_mode:
**/
static void
-gs_main_set_overview_mode (GsMainPrivate *priv, GsMainMode mode)
+gs_main_set_overview_mode (GsMainPrivate *priv, GsMainMode mode, GsApp *app)
{
+ GtkWidget *widget;
+ const gchar *tmp;
+ GdkPixbuf *pixbuf;
+
if (priv->ignore_primary_buttons)
return;
@@ -736,6 +783,47 @@ gs_main_set_overview_mode (GsMainPrivate *priv, GsMainMode mode)
case GS_MAIN_MODE_WAITING:
gs_main_get_updates (priv);
break;
+ case GS_MAIN_MODE_DETAILS:
+
+ tmp = gs_app_get_name (app);
+ if (tmp != NULL && tmp[0] != '\0') {
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_detail_name"));
+ gtk_label_set_label (GTK_LABEL (widget), tmp);
+ gtk_widget_set_visible (widget, TRUE);
+ }
+ tmp = gs_app_get_summary (app);
+ if (tmp != NULL && tmp[0] != '\0') {
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_detail_summary"));
+ gtk_label_set_label (GTK_LABEL (widget), tmp);
+ gtk_widget_set_visible (widget, TRUE);
+ }
+ tmp = NULL; // gs_app_get_description (app);
+ if (tmp == NULL)
+ tmp = _("The author of this software has not included a 'Description' in the desktop
file...");
+ if (tmp != NULL && tmp[0] != '\0') {
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
"label_detail_description"));
+ gtk_label_set_label (GTK_LABEL (widget), tmp);
+ gtk_widget_set_visible (widget, TRUE);
+ }
+ pixbuf = gs_app_get_pixbuf (app);
+ if (pixbuf != NULL) {
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "image_detail_icon"));
+ gtk_image_set_from_pixbuf (GTK_IMAGE (widget), pixbuf);
+ gtk_widget_set_visible (widget, TRUE);
+ }
+ tmp = gs_app_get_screenshot (app);
+ if (tmp != NULL && tmp[0] != '\0') {
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
"image_detail_screenshot"));
+ pixbuf = gdk_pixbuf_new_from_file_at_size (tmp, 1000, 500, NULL);
+ gtk_image_set_from_pixbuf (GTK_IMAGE (widget), pixbuf);
+ g_object_unref (pixbuf);
+ gtk_widget_set_visible (widget, TRUE);
+ }
+
+ /* add install button if available */
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_install"));
+ gtk_widget_set_visible (widget, gs_app_get_state (app) == GS_APP_STATE_AVAILABLE);
+ break;
default:
g_assert_not_reached ();
}
@@ -750,7 +838,16 @@ gs_main_overview_button_cb (GtkWidget *widget, GsMainPrivate *priv)
GsMainMode mode;
mode = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
"gnome-software::overview-mode"));
- gs_main_set_overview_mode (priv, mode);
+ gs_main_set_overview_mode (priv, mode, NULL);
+}
+
+/**
+ * gs_main_back_button_cb:
+ **/
+static void
+gs_main_back_button_cb (GtkWidget *widget, GsMainPrivate *priv)
+{
+ gs_main_set_overview_mode (priv, priv->tab_back_id, NULL);
}
/**
@@ -905,6 +1002,35 @@ gs_main_installed_sort_func (gconstpointer a,
}
/**
+ * gs_main_popular_activated_cb:
+ **/
+static void
+gs_main_popular_activated_cb (GtkIconView *iconview, GtkTreePath *path, GsMainPrivate *priv)
+{
+ gboolean ret;
+ GsApp *app;
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+
+ model = gtk_icon_view_get_model (iconview);
+ ret = gtk_tree_model_get_iter_from_string (model, &iter, gtk_tree_path_to_string (path));
+ if (!ret)
+ return;
+
+ gtk_tree_model_get (model, &iter,
+ COLUMN_POPULAR_APP, &app,
+ -1);
+ g_debug ("show details with %s", gs_app_get_name (app));
+
+ /* save current mode */
+ priv->tab_back_id = priv->mode;
+
+ /* switch to overview mode */
+ gs_main_set_overview_mode (priv, GS_MAIN_MODE_DETAILS, app);
+ g_object_unref (app);
+}
+
+/**
* gs_main_startup_cb:
**/
static void
@@ -976,6 +1102,9 @@ gs_main_startup_cb (GApplication *application, GsMainPrivate *priv)
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "iconview_popular"));
gtk_icon_view_set_markup_column (GTK_ICON_VIEW (widget), COLUMN_POPULAR_MARKUP);
gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (widget), COLUMN_POPULAR_PIXBUF);
+ gtk_icon_view_set_activate_on_single_click (GTK_ICON_VIEW (widget), TRUE);
+ g_signal_connect (widget, "item-activated",
+ G_CALLBACK (gs_main_popular_activated_cb), priv);
/* setup featured tiles */
gs_main_setup_featured (priv);
@@ -1014,6 +1143,9 @@ gs_main_startup_cb (GApplication *application, GsMainPrivate *priv)
gtk_widget_show (GTK_WIDGET (priv->list_box_updates));
/* setup buttons */
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_back"));
+ g_signal_connect (widget, "clicked",
+ G_CALLBACK (gs_main_back_button_cb), priv);
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_new"));
g_object_set_data (G_OBJECT (widget),
"gnome-software::overview-mode",
@@ -1044,7 +1176,7 @@ gs_main_startup_cb (GApplication *application, GsMainPrivate *priv)
/* show main UI */
gtk_widget_show (main_window);
- gs_main_set_overview_mode (priv, GS_MAIN_MODE_INSTALLED);
+ gs_main_set_overview_mode (priv, GS_MAIN_MODE_INSTALLED, NULL);
out:
if (data != NULL)
g_bytes_unref (data);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]