[gtk/wip/otte/inscription: 12/12] inscription: Implement marquee overflow




commit 98a93b265de12b6fdfda7d9d03fb913553fc4b83
Author: Benjamin Otte <otte redhat com>
Date:   Thu Jun 9 05:56:18 2022 +0200

    inscription: Implement marquee overflow

 gtk/gtkinscription.c | 35 ++++++++++++++++++++++++++++++++++-
 gtk/gtkinscription.h |  3 ++-
 2 files changed, 36 insertions(+), 2 deletions(-)
---
diff --git a/gtk/gtkinscription.c b/gtk/gtkinscription.c
index 3ad3319077..4305896ce3 100644
--- a/gtk/gtkinscription.c
+++ b/gtk/gtkinscription.c
@@ -73,6 +73,7 @@ struct _GtkInscription
   GtkInscriptionOverflow overflow;
 
   PangoLayout *layout;
+  guint marquee_tick;
 };
 
 enum
@@ -386,7 +387,18 @@ gtk_inscription_get_layout_location (GtkInscription *self,
     xalign = 1.0 - xalign;
 
   pango_layout_get_pixel_extents (self->layout, NULL, &logical);
-  x = floor ((xalign * (widget_width - logical.width)) - logical.x);
+  if (self->overflow == GTK_INSCRIPTION_OVERFLOW_MARQUEE && widget_width < logical.width)
+    {
+      gint64 frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
+      gint64 repeat_time = (logical.width - widget_width) * 20000;
+      frame_time = frame_time % (2 * repeat_time);
+      frame_time = ABS (frame_time);
+      if (frame_time > repeat_time)
+        frame_time = 2 * repeat_time - frame_time;
+      x = (widget_width - logical.width) * frame_time / repeat_time;
+    }
+  else
+    x = floor ((xalign * (widget_width - logical.width)) - logical.x);
 
   baseline = gtk_widget_get_allocated_baseline (widget);
   if (baseline != -1)
@@ -417,6 +429,7 @@ gtk_inscription_allocate (GtkWidget *widget,
   switch (self->overflow)
     {
     case GTK_INSCRIPTION_OVERFLOW_CLIP:
+    case GTK_INSCRIPTION_OVERFLOW_MARQUEE:
       pango_layout_set_height (self->layout, 0);
       /* figure out if we're single line (clip horizontally)
        * or multiline (clip vertically):
@@ -1068,6 +1081,16 @@ gtk_inscription_get_attributes (GtkInscription *self)
   return self->attrs;
 }
 
+static gboolean
+marquee_de_sade (GtkWidget     *widget,
+                 GdkFrameClock *frameclock,
+                 gpointer       unused)
+{
+  gtk_widget_queue_draw (widget);
+
+  return G_SOURCE_CONTINUE;
+}
+
 /**
  * gtk_inscription_set_overflow: (attributes org.gtk.Method.set_property=overflow)
  * @self: a `GtkInscription`
@@ -1089,6 +1112,7 @@ gtk_inscription_set_overflow (GtkInscription         *self,
   switch (self->overflow)
     {
     case GTK_INSCRIPTION_OVERFLOW_CLIP:
+    case GTK_INSCRIPTION_OVERFLOW_MARQUEE:
       pango_layout_set_ellipsize (self->layout, PANGO_ELLIPSIZE_NONE);
       break;
     case GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_START:
@@ -1104,6 +1128,15 @@ gtk_inscription_set_overflow (GtkInscription         *self,
       g_assert_not_reached();
       break;
     }
+
+  if (self->overflow == GTK_INSCRIPTION_OVERFLOW_MARQUEE)
+    self->marquee_tick = gtk_widget_add_tick_callback (GTK_WIDGET (self), marquee_de_sade, NULL, NULL);
+  else if (self->marquee_tick)
+    {
+      gtk_widget_remove_tick_callback (GTK_WIDGET (self), self->marquee_tick);
+      self->marquee_tick = 0;
+    }
+
   g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_OVERFLOW]);
 
   gtk_widget_queue_draw (GTK_WIDGET (self));
diff --git a/gtk/gtkinscription.h b/gtk/gtkinscription.h
index 10171e599e..036e543b96 100644
--- a/gtk/gtkinscription.h
+++ b/gtk/gtkinscription.h
@@ -34,7 +34,8 @@ typedef enum {
   GTK_INSCRIPTION_OVERFLOW_CLIP,
   GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_START,
   GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_MIDDLE,
-  GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_END
+  GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_END,
+  GTK_INSCRIPTION_OVERFLOW_MARQUEE,
 } GtkInscriptionOverflow;
 
 GDK_AVAILABLE_IN_4_8


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