[gnome-software/1364-implement-other-apps-by-author-section-in-app-details-page: 14/15] gs-details-page: Remember selected app when changing through "Other apps for developer"




commit 62083bce4213c8ce33bea08e640106800f6a5869
Author: Milan Crha <mcrha redhat com>
Date:   Tue Mar 15 18:23:12 2022 +0100

    gs-details-page: Remember selected app when changing through "Other apps for developer"
    
    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 97a827b50..10e8d5e19 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               *other_apps_heading;
        GtkWidget               *box_other_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)
@@ -960,10 +973,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 */
@@ -2272,6 +2297,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);
@@ -2454,6 +2483,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),
@@ -2736,3 +2766,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]