[gnome-software] Screenshot widget improvements



commit 37e073c1133d10ecdf2a8a0497fe9f24405a2168
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Oct 7 23:54:17 2013 -0400

    Screenshot widget improvements
    
    Turn the thumbnail list into an actual listbox, and make the
    screenshot widget no longer a button. This improves keynav,
    provides visual feedback on the currently selected thumbnail,
    and is simpler.

 src/gs-screenshot-image.c |   56 ++++++++++----------
 src/gs-screenshot-image.h |    1 -
 src/gs-shell-details.c    |   40 +++++++++------
 src/gtk-style.css         |   13 ++---
 src/screenshot-image.ui   |  121 +++++++++++++++++++++-----------------------
 5 files changed, 116 insertions(+), 115 deletions(-)
---
diff --git a/src/gs-screenshot-image.c b/src/gs-screenshot-image.c
index 1d58f9a..685f96e 100644
--- a/src/gs-screenshot-image.c
+++ b/src/gs-screenshot-image.c
@@ -33,7 +33,6 @@ struct _GsScreenshotImagePrivate
        GsScreenshot    *screenshot;
        GtkWidget       *stack;
        GtkWidget       *box_error;
-       GtkWidget       *button;
        GtkWidget       *image1;
        GtkWidget       *image2;
        GtkWidget       *label_error;
@@ -47,13 +46,6 @@ struct _GsScreenshotImagePrivate
 
 G_DEFINE_TYPE_WITH_PRIVATE (GsScreenshotImage, gs_screenshot_image, GTK_TYPE_BIN)
 
-enum {
-       SIGNAL_CLICKED,
-       SIGNAL_LAST
-};
-
-static guint signals [SIGNAL_LAST] = { 0 };
-
 /**
  * gs_screenshot_image_get_screenshot:
  **/
@@ -314,27 +306,17 @@ gs_screenshot_image_destroy (GtkWidget *widget)
 }
 
 /**
- * button_clicked:
- **/
-static void
-button_clicked (GsScreenshotImage *ssimg)
-{
-       g_signal_emit (ssimg, signals[SIGNAL_CLICKED], 0);
-}
-
-/**
  * gs_screenshot_image_init:
  **/
 static void
 gs_screenshot_image_init (GsScreenshotImage *ssimg)
 {
        GsScreenshotImagePrivate *priv;
+       AtkObject *accessible;
 
        gtk_widget_set_has_window (GTK_WIDGET (ssimg), FALSE);
        gtk_widget_init_template (GTK_WIDGET (ssimg));
        priv = gs_screenshot_image_get_instance_private (ssimg);
-       g_signal_connect_swapped (priv->button, "clicked",
-                                 G_CALLBACK (button_clicked), ssimg);
 
        /* setup networking */
        priv->session = soup_session_sync_new_with_options (SOUP_SESSION_USER_AGENT,
@@ -347,6 +329,32 @@ gs_screenshot_image_init (GsScreenshotImage *ssimg)
        }
        soup_session_add_feature_by_type (priv->session,
                                          SOUP_TYPE_PROXY_RESOLVER_DEFAULT);
+
+       accessible = gtk_widget_get_accessible (GTK_WIDGET (ssimg));
+       if (accessible != 0) {
+               atk_object_set_role (accessible, ATK_ROLE_IMAGE);
+               atk_object_set_name (accessible, _("Screenshot"));
+       }
+}
+
+static gboolean
+gs_screenshot_image_draw (GtkWidget *widget,
+                         cairo_t   *cr)
+{
+  GtkStyleContext *context;
+
+  context = gtk_widget_get_style_context (widget);
+
+  gtk_render_background (context, cr,
+                         0, 0,
+                         gtk_widget_get_allocated_width (widget),
+                         gtk_widget_get_allocated_height (widget));
+  gtk_render_frame (context, cr,
+                    0, 0,
+                    gtk_widget_get_allocated_width (widget),
+                    gtk_widget_get_allocated_height (widget));
+
+  return GTK_WIDGET_CLASS (gs_screenshot_image_parent_class)->draw (widget, cr);
 }
 
 /**
@@ -355,23 +363,15 @@ gs_screenshot_image_init (GsScreenshotImage *ssimg)
 static void
 gs_screenshot_image_class_init (GsScreenshotImageClass *klass)
 {
-       GObjectClass *object_class = G_OBJECT_CLASS (klass);
        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
        widget_class->destroy = gs_screenshot_image_destroy;
-
-       signals [SIGNAL_CLICKED] =
-               g_signal_new ("clicked",
-                             G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
-                             G_STRUCT_OFFSET (GsScreenshotImageClass, clicked),
-                             NULL, NULL, g_cclosure_marshal_VOID__VOID,
-                             G_TYPE_NONE, 0);
+       widget_class->draw = gs_screenshot_image_draw;
 
        gtk_widget_class_set_template_from_resource (widget_class,
                                                     "/org/gnome/software/screenshot-image.ui");
 
        gtk_widget_class_bind_template_child_private (widget_class, GsScreenshotImage, stack);
-       gtk_widget_class_bind_template_child_private (widget_class, GsScreenshotImage, button);
        gtk_widget_class_bind_template_child_private (widget_class, GsScreenshotImage, spinner);
        gtk_widget_class_bind_template_child_private (widget_class, GsScreenshotImage, image1);
        gtk_widget_class_bind_template_child_private (widget_class, GsScreenshotImage, image2);
diff --git a/src/gs-screenshot-image.h b/src/gs-screenshot-image.h
index 3a4b1bb..221a180 100644
--- a/src/gs-screenshot-image.h
+++ b/src/gs-screenshot-image.h
@@ -49,7 +49,6 @@ struct _GsScreenshotImage
 struct _GsScreenshotImageClass
 {
        GtkBinClass      parent_class;
-       void            (*clicked)                      (GsScreenshotImage      *ssimg);
 };
 
 GType           gs_screenshot_image_get_type           (void);
diff --git a/src/gs-shell-details.c b/src/gs-shell-details.c
index f4a04d0..1fa84ab 100644
--- a/src/gs-shell-details.c
+++ b/src/gs-shell-details.c
@@ -180,31 +180,33 @@ gs_shell_details_app_state_changed_cb (GsApp *app, GsShellDetails *shell_details
        gs_shell_details_refresh (shell_details);
 }
 
-/**
- * gs_shell_details_screenshot_clicked_cb:
- **/
 static void
-gs_shell_details_screenshot_clicked_cb (GsScreenshotImage *ssthumb,
-                                       GsShellDetails *shell_details)
+gs_shell_details_screenshot_selected_cb (GtkListBox *list,
+                                        GtkListBoxRow *row,
+                                        GsShellDetails *shell_details)
 {
-       GList *children;
-       GsScreenshot *ss;
-       GsScreenshotImage *ssmain;
        GsShellDetailsPrivate *priv = shell_details->priv;
        GtkWidget *widget;
+       GsScreenshotImage *ssmain;
+       GsScreenshotImage *ssthumb;
+       GsScreenshot *ss;
+       GList *children;
+
+       if (row == NULL)
+               return;
 
        widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
                                                     "box_details_screenshot_main"));
        children = gtk_container_get_children (GTK_CONTAINER (widget));
        ssmain = GS_SCREENSHOT_IMAGE (children->data);
+       g_list_free (children);
+
+       ssthumb = GS_SCREENSHOT_IMAGE (gtk_bin_get_child (GTK_BIN (row)));
        ss = gs_screenshot_image_get_screenshot (ssthumb);
-       g_debug ("Button pressed, show %s",
-                gs_screenshot_get_url (ss, G_MAXUINT, G_MAXUINT));
        gs_screenshot_image_set_screenshot (ssmain,
                                            ss,
                                            GS_SCREENSHOT_SIZE_LARGE_WIDTH,
                                            GS_SCREENSHOT_SIZE_LARGE_HEIGHT);
-       g_list_free (children);
 }
 
 /**
@@ -306,20 +308,28 @@ gs_shell_details_set_app (GsShellDetails *shell_details, GsApp *app)
        widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "box_details_screenshot_thumbnails"));
        gs_container_remove_all (GTK_CONTAINER (widget));
        if (screenshots->len > 1) {
+               GtkWidget *list;
+               list = gtk_list_box_new ();
+               gtk_style_context_add_class (gtk_widget_get_style_context (list), "image-list");
+               gtk_widget_show (list);
+               gtk_box_pack_start (GTK_BOX (widget), list, FALSE, FALSE, 0);
                for (i = 0; i < screenshots->len; i++) {
                        ss = g_ptr_array_index (screenshots, i);
                        ssimg = gs_screenshot_image_new ();
-                       g_signal_connect (ssimg, "clicked",
-                                         G_CALLBACK (gs_shell_details_screenshot_clicked_cb),
-                                         shell_details);
                        gs_screenshot_image_set_cachedir (GS_SCREENSHOT_IMAGE (ssimg), g_get_user_cache_dir 
());
                        gs_screenshot_image_set_screenshot (GS_SCREENSHOT_IMAGE (ssimg),
                                                            ss,
                                                            GS_SCREENSHOT_SIZE_SMALL_WIDTH,
                                                            GS_SCREENSHOT_SIZE_SMALL_HEIGHT);
-                       gtk_box_pack_start (GTK_BOX (widget), ssimg, FALSE, FALSE, 0);
+                       gtk_list_box_insert (GTK_LIST_BOX (list), ssimg, -1);
                        gtk_widget_set_visible (ssimg, TRUE);
                }
+
+               gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_BROWSE);
+               gtk_list_box_select_row (GTK_LIST_BOX (list),
+                                        gtk_list_box_get_row_at_index (GTK_LIST_BOX (list), 0));
+               g_signal_connect (list, "row-selected", 
+                                 G_CALLBACK (gs_shell_details_screenshot_selected_cb), shell_details);
        }
 
        /* set the project group */
diff --git a/src/gtk-style.css b/src/gtk-style.css
index 0937c43..0c0c4db 100644
--- a/src/gtk-style.css
+++ b/src/gtk-style.css
@@ -30,14 +30,7 @@ GtkNotebook.main-notebook-software > GtkScrolledWindow {
         animation: throbbing linear 1s infinite alternate;
 }
 
-.button.screenshot-image {
-        padding: 0;
-        border-radius: 0;
-        border-width: 0px;
-        border-image: none;
-        -GtkWidget-focus-padding: 0;
-        outline-style: dashed;
-        outline-offset: 2px;
+.screenshot-image {
         background-image: none;
         background-color: rgba(0,0,0,0.5);
 }
@@ -68,3 +61,7 @@ GtkNotebook.main-notebook-software > GtkScrolledWindow {
 .error-label {
        text-shadow: none;
 }
+
+.image-list {
+       background-color: transparent;
+}
diff --git a/src/screenshot-image.ui b/src/screenshot-image.ui
index 1f38c06..c6839aa 100644
--- a/src/screenshot-image.ui
+++ b/src/screenshot-image.ui
@@ -3,86 +3,81 @@
   <!-- interface-requires gtk+ 3.10 -->
   <template class="GsScreenshotImage" parent="GtkBin">
     <property name="visible">True</property>
+    <style>
+      <class name="screenshot-image"/>
+    </style>
     <child>
-      <object class="GtkButton" id="button">
+      <object class="GtkStack" id="stack">
         <property name="visible">True</property>
-        <style>
-          <class name="screenshot-image"/>
-        </style>
+        <property name="can_focus">False</property>
+        <property name="transition-type">crossfade</property>
         <child>
-          <object class="GtkStack" id="stack">
+          <object class="GtkImage" id="image1">
             <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="transition-type">crossfade</property>
-            <child>
-              <object class="GtkImage" id="image1">
-                <property name="visible">True</property>
-                <property name="halign">center</property>
-                <property name="valign">center</property>
-              </object>
-              <packing>
-                <property name="name">image1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkImage" id="image2">
-                <property name="visible">True</property>
-                <property name="halign">center</property>
-                <property name="valign">center</property>
-              </object>
-              <packing>
-                <property name="name">image2</property>
-              </packing>
-            </child>
+            <property name="halign">center</property>
+            <property name="valign">center</property>
+          </object>
+          <packing>
+            <property name="name">image1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkImage" id="image2">
+            <property name="visible">True</property>
+            <property name="halign">center</property>
+            <property name="valign">center</property>
+          </object>
+          <packing>
+            <property name="name">image2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkSpinner" id="spinner">
+            <property name="visible">True</property>
+            <property name="width_request">16</property>
+            <property name="height_request">16</property>
+            <property name="halign">center</property>
+            <property name="valign">center</property>
+          </object>
+          <packing>
+            <property name="name">spinner</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box_error">
+            <property name="visible">True</property>
+            <property name="halign">center</property>
+            <property name="valign">center</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">4</property>
             <child>
-              <object class="GtkSpinner" id="spinner">
+              <object class="GtkImage" id="image_error">
                 <property name="visible">True</property>
-                <property name="width_request">16</property>
-                <property name="height_request">16</property>
-                <property name="halign">center</property>
-                <property name="valign">center</property>
+                <property name="icon-name">dialog-error-symbolic</property>
               </object>
               <packing>
-                <property name="name">spinner</property>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
               </packing>
             </child>
             <child>
-              <object class="GtkBox" id="box_error">
+              <object class="GtkLabel" id="label_error">
                 <property name="visible">True</property>
-                <property name="halign">center</property>
-                <property name="valign">center</property>
-                <property name="orientation">vertical</property>
-                <property name="spacing">4</property>
-                <child>
-                  <object class="GtkImage" id="image_error">
-                    <property name="visible">True</property>
-                    <property name="icon-name">dialog-error-symbolic</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_error">
-                    <property name="visible">True</property>
-                    <style>
-                      <class name="error-label"/>
-                    </style>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
+                <style>
+                  <class name="error-label"/>
+                </style>
               </object>
               <packing>
-                <property name="name">error</property>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
               </packing>
             </child>
           </object>
+          <packing>
+            <property name="name">error</property>
+          </packing>
         </child>
       </object>
     </child>


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