[gnome-software/1131-featured-carousel: 3/21] gs-overview-page: Use the new GsFeaturedCarousel widget




commit 660b8e7a2c350aabc48948255fc6f6b754f12b00
Author: Philip Withnall <pwithnall endlessos org>
Date:   Thu Feb 11 23:31:30 2021 +0000

    gs-overview-page: Use the new GsFeaturedCarousel widget
    
    Rather than rolling a custom carousel widget.
    
    Signed-off-by: Philip Withnall <pwithnall endlessos org>
    
    Fixes: #1131

 src/gs-overview-page.c  | 157 +++++++-----------------------------------------
 src/gs-overview-page.ui |  62 +------------------
 2 files changed, 23 insertions(+), 196 deletions(-)
---
diff --git a/src/gs-overview-page.c b/src/gs-overview-page.c
index 561559104..cfefdd6d4 100644
--- a/src/gs-overview-page.c
+++ b/src/gs-overview-page.c
@@ -17,7 +17,7 @@
 #include "gs-overview-page.h"
 #include "gs-app-list-private.h"
 #include "gs-popular-tile.h"
-#include "gs-feature-tile.h"
+#include "gs-featured-carousel.h"
 #include "gs-category-tile.h"
 #include "gs-hiding-box.h"
 #include "gs-common.h"
@@ -43,14 +43,10 @@ typedef struct
        GHashTable              *category_hash;         /* id : GsCategory */
        GSettings               *settings;
        GsApp                   *third_party_repo;
-       guint                    featured_rotate_timer_id;
 
        GtkWidget               *infobar_third_party;
        GtkWidget               *label_third_party;
-       GtkWidget               *overlay;
-       GtkWidget               *stack_featured;
-       GtkWidget               *button_featured_back;
-       GtkWidget               *button_featured_forwards;
+       GtkWidget               *featured_carousel;
        GtkWidget               *box_overview;
        GtkWidget               *box_popular;
        GtkWidget               *box_popular_rotating;
@@ -107,6 +103,17 @@ app_tile_clicked (GsAppTile *tile, gpointer data)
        gs_shell_show_app (priv->shell, app);
 }
 
+static void
+featured_carousel_app_clicked_cb (GsFeaturedCarousel *carousel,
+                                  GsApp              *app,
+                                  gpointer            user_data)
+{
+       GsOverviewPage *self = GS_OVERVIEW_PAGE (user_data);
+       GsOverviewPagePrivate *priv = gs_overview_page_get_instance_private (self);
+
+       gs_shell_show_app (priv->shell, app);
+}
+
 static gboolean
 filter_category (GsApp *app, gpointer user_data)
 {
@@ -348,95 +355,6 @@ out:
        gs_overview_page_decrement_action_cnt (self);
 }
 
-static void
-_feature_banner_forward (GsOverviewPage *self)
-{
-       GsOverviewPagePrivate *priv = gs_overview_page_get_instance_private (self);
-       GtkWidget *visible_child;
-       GtkWidget *next_child = NULL;
-       GList *banner_link;
-       g_autoptr(GList) banners = NULL;
-
-       visible_child = gtk_stack_get_visible_child (GTK_STACK (priv->stack_featured));
-       banners = gtk_container_get_children (GTK_CONTAINER (priv->stack_featured));
-       if (banners == NULL)
-               return;
-
-       /* find banner after the currently visible one */
-       for (banner_link = banners; banner_link != NULL; banner_link = banner_link->next) {
-               GtkWidget *child = banner_link->data;
-               if (child == visible_child) {
-                       if (banner_link->next != NULL)
-                               next_child = banner_link->next->data;
-                       break;
-               }
-       }
-       if (next_child == NULL)
-               next_child = g_list_first(banners)->data;
-       gtk_stack_set_visible_child (GTK_STACK (priv->stack_featured), next_child);
-}
-
-static void
-_feature_banner_back (GsOverviewPage *self)
-{
-       GsOverviewPagePrivate *priv = gs_overview_page_get_instance_private (self);
-       GtkWidget *visible_child;
-       GtkWidget *next_child = NULL;
-       GList *banner_link;
-       g_autoptr(GList) banners = NULL;
-
-       visible_child = gtk_stack_get_visible_child (GTK_STACK (priv->stack_featured));
-       banners = gtk_container_get_children (GTK_CONTAINER (priv->stack_featured));
-       if (banners == NULL)
-               return;
-
-       /* find banner before the currently visible one */
-       for (banner_link = banners; banner_link != NULL; banner_link = banner_link->next) {
-               GtkWidget *child = banner_link->data;
-               if (child == visible_child) {
-                       if (banner_link->prev != NULL)
-                               next_child = banner_link->prev->data;
-                       break;
-               }
-       }
-       if (next_child == NULL)
-               next_child = g_list_last(banners)->data;
-       gtk_stack_set_visible_child (GTK_STACK (priv->stack_featured), next_child);
-}
-
-static gboolean
-gs_overview_page_featured_rotate_cb (gpointer user_data)
-{
-       GsOverviewPage *self = GS_OVERVIEW_PAGE (user_data);
-       _feature_banner_forward (self);
-       return G_SOURCE_CONTINUE;
-}
-
-static void
-featured_reset_rotate_timer (GsOverviewPage *self)
-{
-       GsOverviewPagePrivate *priv = gs_overview_page_get_instance_private (self);
-       if (priv->featured_rotate_timer_id != 0)
-               g_source_remove (priv->featured_rotate_timer_id);
-       priv->featured_rotate_timer_id = g_timeout_add_seconds (FEATURED_ROTATE_TIME,
-                                                               gs_overview_page_featured_rotate_cb,
-                                                               self);
-}
-
-static void
-_featured_back_clicked_cb (GsCategoryTile *tile, gpointer data)
-{
-       GsOverviewPage *self = GS_OVERVIEW_PAGE (data);
-       _feature_banner_back (self);
-}
-
-static void
-_featured_forward_clicked_cb (GsCategoryTile *tile, gpointer data)
-{
-       GsOverviewPage *self = GS_OVERVIEW_PAGE (data);
-       _feature_banner_forward (self);
-}
-
 static void
 gs_overview_page_get_featured_cb (GObject *source_object,
                                   GAsyncResult *res,
@@ -452,23 +370,10 @@ gs_overview_page_get_featured_cb (GObject *source_object,
        if (g_error_matches (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_CANCELLED))
                goto out;
 
-       if (priv->featured_rotate_timer_id != 0) {
-               g_source_remove (priv->featured_rotate_timer_id);
-               priv->featured_rotate_timer_id = 0;
-       }
-
-       gs_container_remove_all (GTK_CONTAINER (priv->stack_featured));
-       gtk_widget_set_visible (priv->overlay, gs_app_list_length (list) > 0);
-       gtk_widget_set_visible (priv->button_featured_back, gs_app_list_length (list) > 1);
-       gtk_widget_set_visible (priv->button_featured_forwards, gs_app_list_length (list) > 1);
-       if (list == NULL) {
+       if (list == NULL || gs_app_list_length (list) == 0) {
                g_warning ("failed to get featured apps: %s",
-                          error->message);
-               goto out;
-       }
-       if (gs_app_list_length (list) == 0) {
-               g_warning ("failed to get featured apps: "
-                          "no apps to show");
+                          (error != NULL) ? error->message : "no apps to show");
+               gtk_widget_set_visible (priv->featured_carousel, FALSE);
                goto out;
        }
 
@@ -478,16 +383,11 @@ gs_overview_page_get_featured_cb (GObject *source_object,
                gs_app_list_filter_duplicates (list, GS_APP_LIST_FILTER_FLAG_KEY_ID);
                gs_app_list_randomize (list);
        }
-       for (guint i = 0; i < gs_app_list_length (list); i++) {
-               GsApp *app = gs_app_list_index (list, i);
-               GtkWidget *tile = gs_feature_tile_new (app);
-               g_signal_connect (tile, "clicked",
-                                 G_CALLBACK (app_tile_clicked), self);
-               gtk_container_add (GTK_CONTAINER (priv->stack_featured), tile);
-       }
+
+       gtk_widget_set_visible (priv->featured_carousel, gs_app_list_length (list) > 0);
+       gs_featured_carousel_set_apps (GS_FEATURED_CAROUSEL (priv->featured_carousel), list);
 
        priv->empty = FALSE;
-       featured_reset_rotate_timer (self);
 
 out:
        gs_overview_page_decrement_action_cnt (self);
@@ -950,9 +850,6 @@ gs_overview_page_setup (GsPage *page,
        adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scrolledwindow_overview));
        gtk_container_set_focus_vadjustment (GTK_CONTAINER (priv->box_overview), adj);
 
-       tile = gs_feature_tile_new (NULL);
-       gtk_container_add (GTK_CONTAINER (priv->stack_featured), tile);
-
        for (i = 0; i < N_TILES; i++) {
                tile = gs_popular_tile_new (NULL);
                gtk_container_add (GTK_CONTAINER (priv->box_popular), tile);
@@ -972,11 +869,6 @@ gs_overview_page_init (GsOverviewPage *self)
        GsOverviewPagePrivate *priv = gs_overview_page_get_instance_private (self);
        gtk_widget_init_template (GTK_WIDGET (self));
 
-       g_signal_connect (priv->button_featured_back, "clicked",
-                         G_CALLBACK (_featured_back_clicked_cb), self);
-       g_signal_connect (priv->button_featured_forwards, "clicked",
-                         G_CALLBACK (_featured_forward_clicked_cb), self);
-
        priv->settings = g_settings_new ("org.gnome.software");
 }
 
@@ -994,11 +886,6 @@ gs_overview_page_dispose (GObject *object)
        g_clear_pointer (&priv->category_of_day, g_free);
        g_clear_pointer (&priv->category_hash, g_hash_table_unref);
 
-       if (priv->featured_rotate_timer_id != 0) {
-               g_source_remove (priv->featured_rotate_timer_id);
-               priv->featured_rotate_timer_id = 0;
-       }
-
        G_OBJECT_CLASS (gs_overview_page_parent_class)->dispose (object);
 }
 
@@ -1038,10 +925,7 @@ gs_overview_page_class_init (GsOverviewPageClass *klass)
 
        gtk_widget_class_bind_template_child_private (widget_class, GsOverviewPage, infobar_third_party);
        gtk_widget_class_bind_template_child_private (widget_class, GsOverviewPage, label_third_party);
-       gtk_widget_class_bind_template_child_private (widget_class, GsOverviewPage, overlay);
-       gtk_widget_class_bind_template_child_private (widget_class, GsOverviewPage, stack_featured);
-       gtk_widget_class_bind_template_child_private (widget_class, GsOverviewPage, button_featured_back);
-       gtk_widget_class_bind_template_child_private (widget_class, GsOverviewPage, button_featured_forwards);
+       gtk_widget_class_bind_template_child_private (widget_class, GsOverviewPage, featured_carousel);
        gtk_widget_class_bind_template_child_private (widget_class, GsOverviewPage, box_overview);
        gtk_widget_class_bind_template_child_private (widget_class, GsOverviewPage, box_popular);
        gtk_widget_class_bind_template_child_private (widget_class, GsOverviewPage, box_popular_rotating);
@@ -1052,6 +936,7 @@ gs_overview_page_class_init (GsOverviewPageClass *klass)
        gtk_widget_class_bind_template_child_private (widget_class, GsOverviewPage, recent_heading);
        gtk_widget_class_bind_template_child_private (widget_class, GsOverviewPage, scrolledwindow_overview);
        gtk_widget_class_bind_template_child_private (widget_class, GsOverviewPage, stack_overview);
+       gtk_widget_class_bind_template_callback (widget_class, featured_carousel_app_clicked_cb);
 }
 
 GsOverviewPage *
diff --git a/src/gs-overview-page.ui b/src/gs-overview-page.ui
index 21abb37f3..09868c6f8 100644
--- a/src/gs-overview-page.ui
+++ b/src/gs-overview-page.ui
@@ -81,68 +81,10 @@
                             <property name="border_width">12</property>
                             <property name="orientation">vertical</property>
                             <child>
-                              <object class="GtkOverlay" id="overlay">
+                              <object class="GsFeaturedCarousel" id="featured_carousel">
                                 <property name="visible">True</property>
-                                <property name="halign">fill</property>
-                                <property name="valign">fill</property>
                                 <property name="height-request">150</property>
-                                <child type="overlay">
-                                  <object class="GtkStack" id="stack_featured">
-                                    <property name="visible">True</property>
-                                    <property name="halign">fill</property>
-                                    <property name="transition-type">crossfade</property>
-                                  </object>
-                                </child>
-                                <child type="overlay">
-                                  <object class="GtkButton" id="button_featured_back">
-                                    <property name="visible">True</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="halign">start</property>
-                                    <property name="valign">center</property>
-                                    <child internal-child="accessible">
-                                      <object class="AtkObject" id="button_featured_back_accessible">
-                                        <property name="accessible-name" 
translatable="yes">Previous</property>
-                                      </object>
-                                    </child>
-                                    <style>
-                                      <class name="osd"/>
-                                      <class name="featured-button-left"/>
-                                    </style>
-                                    <child>
-                                      <object class="GtkImage" id="back_image">
-                                        <property name="visible">True</property>
-                                        <property name="icon_name">go-previous-symbolic</property>
-                                        <property name="icon_size">1</property>
-                                      </object>
-                                    </child>
-                                  </object>
-                                </child>
-                                <child type="overlay">
-                                  <object class="GtkButton" id="button_featured_forwards">
-                                    <property name="visible">True</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="halign">end</property>
-                                    <property name="valign">center</property>
-                                    <child internal-child="accessible">
-                                      <object class="AtkObject" id="button_featured_forwards_accessible">
-                                        <property name="accessible-name" translatable="yes">Next</property>
-                                      </object>
-                                    </child>
-                                    <style>
-                                      <class name="osd"/>
-                                      <class name="featured-button-right"/>
-                                    </style>
-                                    <child>
-                                      <object class="GtkImage" id="forwards_image">
-                                        <property name="visible">True</property>
-                                        <property name="icon_name">go-next-symbolic</property>
-                                        <property name="icon_size">1</property>
-                                      </object>
-                                    </child>
-                                  </object>
-                                </child>
+                                <signal name="app-clicked" handler="featured_carousel_app_clicked_cb"/>
                               </object>
                             </child>
 


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