[calls] history-box: Dynamically adjust slice list model size



commit a6faac2940ae4f8deaf70053b4e6e75a5a9a7a84
Author: Evangelos Ribeiro Tzaras <devrtz fortysixandtwo eu>
Date:   Sat Jul 9 13:20:34 2022 +0200

    history-box: Dynamically adjust slice list model size
    
    The slice get's increased by 50 items if scrolled to the bottom
    and reset to the initial 75 items if scrolled back to the top.
    
    The defined threshholds make sure that the UX still feels smooth.

 src/calls-history-box.c | 67 ++++++++++++++++++++++++++++++++++++++++++++-----
 src/ui/history-box.ui   |  2 +-
 2 files changed, 62 insertions(+), 7 deletions(-)
---
diff --git a/src/calls-history-box.c b/src/calls-history-box.c
index 6c481164..a626ca62 100644
--- a/src/calls-history-box.c
+++ b/src/calls-history-box.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, 2019 Purism SPC
+ * Copyright (C) 2018, 2019, 2022 Purism SPC
  *
  * This file is part of Calls.
  *
@@ -17,10 +17,12 @@
  * along with Calls.  If not, see <http://www.gnu.org/licenses/>.
  *
  * Author: Adrien Plazas <adrien plazas puri sm>
+ *         Evangelos Ribeiro Tzaras <devrtz fortysixandtwo eu>
  *
  * SPDX-License-Identifier: GPL-3.0-or-later
  *
  */
+#define G_LOG_DOMAIN "CallsHistoryBox"
 
 #include "calls-history-box.h"
 #include "calls-call-record.h"
@@ -31,16 +33,22 @@
 #include <glib/gi18n.h>
 #include <glib-object.h>
 
+#define CALLS_HISTORY_SIZE_INITIAL 75
+#define CALLS_HISTORY_SIZE_INCREMENTS 50
+#define CALLS_HISTORY_RESET_SIZE_POSITION_THRESHOLD 500
+#define CALLS_HISTORY_INCREASE_N_PAGES_THRESHOLD 2
 
 struct _CallsHistoryBox {
-  GtkStack    parent_instance;
+  GtkStack           parent_instance;
 
-  GtkListBox *history;
+  GtkListBox        *history;
+  GtkScrolledWindow *scrolled_window;
+  GtkAdjustment     *scroll_adjustment;
 
-  GListModel *model;
+  GListModel        *model;
   GtkSliceListModel *slice_model;
 
-  gulong      model_changed_handler_id;
+  gulong             model_changed_handler_id;
 
 };
 
@@ -122,6 +130,43 @@ create_row_cb (CallsCallRecord *record,
 }
 
 
+static void
+on_adjustment_position_changed (GtkAdjustment   *adjustment,
+                                CallsHistoryBox *self)
+{
+  double position;
+  double upper_limit;
+  double page_size;
+  guint old_size;
+
+  g_assert (CALLS_IS_HISTORY_BOX (self));
+
+  position = gtk_adjustment_get_value (adjustment);
+  page_size = gtk_adjustment_get_page_size (adjustment);
+  old_size = gtk_slice_list_model_get_size (self->slice_model);
+
+  if (position < CALLS_HISTORY_RESET_SIZE_POSITION_THRESHOLD) {
+    if (old_size == CALLS_HISTORY_SIZE_INITIAL)
+      return;
+
+    g_debug ("Resetting to initial size: %u",
+             CALLS_HISTORY_SIZE_INITIAL);
+    gtk_slice_list_model_set_size (self->slice_model, CALLS_HISTORY_SIZE_INITIAL);
+    return;
+  }
+
+  upper_limit = gtk_adjustment_get_upper (adjustment);
+
+  if (position > upper_limit - CALLS_HISTORY_INCREASE_N_PAGES_THRESHOLD * page_size) {
+    guint new_size = old_size + CALLS_HISTORY_SIZE_INCREMENTS;
+
+    g_debug ("Increasing history slice from %u to %u",
+             old_size, new_size);
+    gtk_slice_list_model_set_size (self->slice_model, new_size);
+  }
+}
+
+
 static void
 set_property (GObject      *object,
               guint         property_id,
@@ -152,7 +197,9 @@ constructed (GObject *object)
 
   G_OBJECT_CLASS (calls_history_box_parent_class)->constructed (object);
 
-  self->slice_model = gtk_slice_list_model_new (self->model, 0, 75);
+  self->slice_model = gtk_slice_list_model_new (self->model,
+                                                0,
+                                                CALLS_HISTORY_SIZE_INITIAL);
 
   self->model_changed_handler_id =
     g_signal_connect_swapped
@@ -203,6 +250,7 @@ calls_history_box_class_init (CallsHistoryBoxClass *klass)
 
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Calls/ui/history-box.ui");
   gtk_widget_class_bind_template_child (widget_class, CallsHistoryBox, history);
+  gtk_widget_class_bind_template_child (widget_class, CallsHistoryBox, scrolled_window);
 }
 
 
@@ -210,6 +258,13 @@ static void
 calls_history_box_init (CallsHistoryBox *self)
 {
   gtk_widget_init_template (GTK_WIDGET (self));
+
+  self->scroll_adjustment = gtk_scrolled_window_get_vadjustment (self->scrolled_window);
+
+  g_signal_connect (self->scroll_adjustment,
+                    "value-changed",
+                    G_CALLBACK (on_adjustment_position_changed),
+                    self);
 }
 
 
diff --git a/src/ui/history-box.ui b/src/ui/history-box.ui
index ff221642..48671ff6 100644
--- a/src/ui/history-box.ui
+++ b/src/ui/history-box.ui
@@ -15,7 +15,7 @@
     </child>
 
     <child>
-      <object class="GtkScrolledWindow">
+      <object class="GtkScrolledWindow" id="scrolled_window">
         <property name="visible">True</property>
         <property name="hscrollbar-policy">never</property>
         <child>


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