[gnome-software/1364-implement-other-apps-by-author-section-in-app-details-page: 214/215] gs-details-page: Remember selected app when changing through "Other Apps by $author"




commit 3137c75bd1a7d7ca66c3e5c5756966ea746b3f65
Author: Milan Crha <mcrha redhat com>
Date:   Fri May 6 10:48:39 2022 +0200

    gs-details-page: Remember selected app when changing through "Other Apps by $author"
    
    Remember the selected app, to be able to go back to the previous app,
    not directly to the Overview page.

 src/gs-details-page.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/gs-details-page.h |  1 +
 2 files changed, 66 insertions(+)
---
diff --git a/src/gs-details-page.c b/src/gs-details-page.c
index 6e2370a73..a962cf55d 100644
--- a/src/gs-details-page.c
+++ b/src/gs-details-page.c
@@ -70,6 +70,11 @@ static void gs_details_page_refresh_addons (GsDetailsPage *self);
 static void gs_details_page_refresh_all (GsDetailsPage *self);
 static void gs_details_page_app_refine_cb (GObject *source, GAsyncResult *res, gpointer user_data);
 
+typedef struct {
+       GsApp *app; /* owned */
+       gdouble vscroll_value;
+} BackEntry;
+
 typedef enum {
        GS_DETAILS_PAGE_STATE_LOADING,
        GS_DETAILS_PAGE_STATE_READY,
@@ -155,6 +160,7 @@ struct _GsDetailsPage
        GtkWidget               *developer_apps_heading;
        GtkWidget               *box_developer_apps;
        gchar                   *last_developer_name;
+       GQueue                  *back_entry_stack;
 };
 
 G_DEFINE_TYPE (GsDetailsPage, gs_details_page, GS_TYPE_PAGE)
@@ -174,6 +180,13 @@ typedef enum {
 static GParamSpec *obj_props[PROP_IS_NARROW + 1] = { NULL, };
 static guint signals[SIGNAL_LAST] = { 0 };
 
+static void
+free_back_entry (BackEntry *entry)
+{
+       g_clear_object (&entry->app);
+       g_free (entry);
+}
+
 static void
 gs_details_page_cancel_cb (GCancellable *cancellable,
                           GsDetailsPage *self)
@@ -966,10 +979,22 @@ gs_details_page_app_tile_clicked (GsAppTile *tile,
                                  gpointer user_data)
 {
        GsDetailsPage *self = GS_DETAILS_PAGE (user_data);
+       GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW 
(self->scrolledwindow_details));
+       BackEntry *entry;
        GsApp *app;
 
+       /* Remember the selected app */
+       entry = g_new0 (BackEntry, 1);
+       entry->app = g_object_ref (self->app);
+       entry->vscroll_value = gtk_adjustment_get_value (adj);
+       g_queue_push_head (self->back_entry_stack, entry);
+
+       /* Set the new app */
        app = gs_app_tile_get_app (tile);
        gs_details_page_set_app (self, app);
+
+       /* Scroll to the top */
+       gtk_adjustment_set_value (adj, gtk_adjustment_get_lower (adj));
 }
 
 /* Consider app IDs with and without the ".desktop" suffix being the same app */
@@ -2276,6 +2301,10 @@ gs_details_page_dispose (GObject *object)
                g_hash_table_unref (self->packaging_format_preference);
                self->packaging_format_preference = NULL;
        }
+       if (self->back_entry_stack) {
+               g_queue_free_full (self->back_entry_stack, (GDestroyNotify) free_back_entry);
+               self->back_entry_stack = NULL;
+       }
        g_clear_object (&self->app_local_file);
        g_clear_object (&self->app_reviews_dialog);
        g_clear_object (&self->plugin_loader);
@@ -2458,6 +2487,7 @@ gs_details_page_init (GsDetailsPage *self)
        gtk_widget_init_template (GTK_WIDGET (self));
 
        self->packaging_format_preference = g_hash_table_new_full (gs_details_page_strcase_hash, 
gs_details_page_strcase_equal, g_free, NULL);
+       self->back_entry_stack = g_queue_new ();
        self->settings = g_settings_new ("org.gnome.software");
        g_signal_connect_swapped (self->settings, "changed",
                                  G_CALLBACK (settings_changed_cb),
@@ -2740,3 +2770,38 @@ gs_details_page_set_metainfo (GsDetailsPage *self,
        g_task_set_task_data (task, g_object_ref (file), g_object_unref);
        g_task_run_in_thread (task, gs_details_page_metainfo_thread);
 }
+
+/**
+ * gs_details_page_go_back:
+ * @self: a #GsDetailsPage
+ *
+ * Changes the selected application to the previous, if any such exists.
+ *
+ * Returns: %TRUE, when moved to the previously selected app, %FALSE when not.
+ *
+ * Since: 43
+ **/
+gboolean
+gs_details_page_go_back (GsDetailsPage *self)
+{
+       GtkAdjustment *adj;
+       BackEntry *entry;
+
+       g_return_val_if_fail (GS_IS_DETAILS_PAGE (self), FALSE);
+
+       if (g_queue_is_empty (self->back_entry_stack))
+               return FALSE;
+
+       entry = g_queue_pop_head (self->back_entry_stack);
+
+       /* Set the previous app */
+       gs_details_page_set_app (self, entry->app);
+
+       /* Scroll to where the page was */
+       adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (self->scrolledwindow_details));
+       gtk_adjustment_set_value (adj, entry->vscroll_value);
+
+       free_back_entry (entry);
+
+       return TRUE;
+}
diff --git a/src/gs-details-page.h b/src/gs-details-page.h
index 566e79b95..250b88c0e 100644
--- a/src/gs-details-page.h
+++ b/src/gs-details-page.h
@@ -35,5 +35,6 @@ void           gs_details_page_set_is_narrow  (GsDetailsPage  *self,
                                                 gboolean        is_narrow);
 void            gs_details_page_set_metainfo   (GsDetailsPage *self,
                                                 GFile *file);
+gboolean        gs_details_page_go_back        (GsDetailsPage *self);
 
 G_END_DECLS


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