[libhandy] carousel-indicator: Resize on carousel or page number change



commit 5395f1be3bb6d91e8c1fa77b1b4f77da8c120c81
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Mon Feb 21 10:15:23 2022 +0100

    carousel-indicator: Resize on carousel or page number change
    
    We need to resize the indicator when the carousel or its number of pages
    changes, not just redraw it or animate it. This also ensures size
    changes are animated correctly.

 src/hdy-carousel-indicator-dots.c  | 30 +++++++++++++++++++++++-------
 src/hdy-carousel-indicator-lines.c | 30 +++++++++++++++++++++++-------
 2 files changed, 46 insertions(+), 14 deletions(-)
---
diff --git a/src/hdy-carousel-indicator-dots.c b/src/hdy-carousel-indicator-dots.c
index b83714d2..a74f977b 100644
--- a/src/hdy-carousel-indicator-dots.c
+++ b/src/hdy-carousel-indicator-dots.c
@@ -76,7 +76,7 @@ animation_cb (GtkWidget     *widget,
 
   g_assert (self->tick_cb_id > 0);
 
-  gtk_widget_queue_draw (GTK_WIDGET (self));
+  gtk_widget_queue_resize (GTK_WIDGET (self));
 
   frame_time = gdk_frame_clock_get_frame_time (frame_clock) / 1000;
 
@@ -107,13 +107,13 @@ animate (HdyCarouselIndicatorDots *self,
   gint64 frame_time;
 
   if (duration <= 0 || !hdy_get_enable_animations (GTK_WIDGET (self))) {
-    gtk_widget_queue_draw (GTK_WIDGET (self));
+    gtk_widget_queue_resize (GTK_WIDGET (self));
     return;
   }
 
   frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
   if (!frame_clock) {
-    gtk_widget_queue_draw (GTK_WIDGET (self));
+    gtk_widget_queue_resize (GTK_WIDGET (self));
     return;
   }
 
@@ -231,11 +231,27 @@ hdy_carousel_indicator_dots_measure (GtkWidget      *widget,
   gint size = 0;
 
   if (orientation == self->orientation) {
-    gint n_pages = 0;
+    gint i, n_points = 0;
+    gdouble indicator_length, dot_size;
+    g_autofree gdouble *points = NULL;
+    g_autofree gdouble *sizes = NULL;
+
     if (self->carousel)
-      n_pages = hdy_carousel_get_n_pages (self->carousel);
+      points = hdy_swipeable_get_snap_points (HDY_SWIPEABLE (self->carousel), &n_points);
+
+    sizes = g_new0 (gdouble, n_points);
+
+    if (n_points > 0)
+      sizes[0] = points[0] + 1;
+    for (i = 1; i < n_points; i++)
+      sizes[i] = points[i] - points[i - 1];
+
+    dot_size = 2 * DOTS_RADIUS_SELECTED + DOTS_SPACING;
+    indicator_length = 0;
+    for (i = 0; i < n_points; i++)
+      indicator_length += dot_size * sizes[i];
 
-    size = MAX (0, (2 * DOTS_RADIUS_SELECTED + DOTS_SPACING) * n_pages - DOTS_SPACING);
+    size = ceil (indicator_length);
   } else {
     size = 2 * DOTS_RADIUS_SELECTED;
   }
@@ -480,7 +496,7 @@ hdy_carousel_indicator_dots_set_carousel (HdyCarouselIndicatorDots *self,
                              G_CONNECT_SWAPPED);
   }
 
-  gtk_widget_queue_draw (GTK_WIDGET (self));
+  gtk_widget_queue_resize (GTK_WIDGET (self));
 
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_CAROUSEL]);
 }
diff --git a/src/hdy-carousel-indicator-lines.c b/src/hdy-carousel-indicator-lines.c
index aebf76af..c44bd3e9 100644
--- a/src/hdy-carousel-indicator-lines.c
+++ b/src/hdy-carousel-indicator-lines.c
@@ -75,7 +75,7 @@ animation_cb (GtkWidget     *widget,
 
   g_assert (self->tick_cb_id > 0);
 
-  gtk_widget_queue_draw (GTK_WIDGET (self));
+  gtk_widget_queue_resize (GTK_WIDGET (self));
 
   frame_time = gdk_frame_clock_get_frame_time (frame_clock) / 1000;
 
@@ -106,13 +106,13 @@ animate (HdyCarouselIndicatorLines *self,
   gint64 frame_time;
 
   if (duration <= 0 || !hdy_get_enable_animations (GTK_WIDGET (self))) {
-    gtk_widget_queue_draw (GTK_WIDGET (self));
+    gtk_widget_queue_resize (GTK_WIDGET (self));
     return;
   }
 
   frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
   if (!frame_clock) {
-    gtk_widget_queue_draw (GTK_WIDGET (self));
+    gtk_widget_queue_resize (GTK_WIDGET (self));
     return;
   }
 
@@ -229,11 +229,27 @@ hdy_carousel_indicator_lines_measure (GtkWidget      *widget,
   gint size = 0;
 
   if (orientation == self->orientation) {
-    gint n_pages = 0;
+    gint i, n_points = 0;
+    gdouble indicator_length, line_size;
+    g_autofree gdouble *points = NULL;
+    g_autofree gdouble *sizes = NULL;
+
     if (self->carousel)
-      n_pages = hdy_carousel_get_n_pages (self->carousel);
+      points = hdy_swipeable_get_snap_points (HDY_SWIPEABLE (self->carousel), &n_points);
+
+    sizes = g_new0 (gdouble, n_points);
+
+    if (n_points > 0)
+      sizes[0] = points[0] + 1;
+    for (i = 1; i < n_points; i++)
+      sizes[i] = points[i] - points[i - 1];
+
+    line_size = LINE_LENGTH + LINE_SPACING;
+    indicator_length = 0;
+    for (i = 0; i < n_points; i++)
+      indicator_length += line_size * sizes[i];
 
-    size = MAX (0, (LINE_LENGTH + LINE_SPACING) * n_pages - LINE_SPACING);
+    size = ceil (indicator_length);
   } else {
     size = LINE_WIDTH;
   }
@@ -478,7 +494,7 @@ hdy_carousel_indicator_lines_set_carousel (HdyCarouselIndicatorLines *self,
                              G_CONNECT_SWAPPED);
   }
 
-  gtk_widget_queue_draw (GTK_WIDGET (self));
+  gtk_widget_queue_resize (GTK_WIDGET (self));
 
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_CAROUSEL]);
 }


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