summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2014-06-28 15:51:33 -0400
committerMatthias Clasen <mclasen@redhat.com>2014-06-28 15:51:33 -0400
commitef0e164a4c9acf68dc12ea1493c7468dd5da7e0f (patch)
tree93c0fa1cf523834fb45783289957ebbe2f482b45
parent3c400823167799b167b621549e776688c8624953 (diff)
downloadgtk+-ef0e164a4c9acf68dc12ea1493c7468dd5da7e0f.tar.gz
GtkEntry: Make progress pulsing smooth
This changes the calculation of activity mode progress in the same way as was done in GtkProgressBar a while ago, and make it smooth, using a tick callback.
-rw-r--r--gtk/gtkentry.c155
1 files changed, 114 insertions, 41 deletions
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index f438887197..d77c50fddc 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -155,6 +155,11 @@ struct _GtkEntryPrivate
gdouble progress_pulse_fraction;
gdouble progress_pulse_current;
+ guint tick_id;
+ gint64 pulse1;
+ gint64 pulse2;
+ gint64 frame1;
+
gchar *placeholder_text;
GtkWidget *bubble_window;
@@ -2970,6 +2975,9 @@ gtk_entry_finalize (GObject *object)
EntryIconInfo *icon_info = NULL;
gint i;
+ if (priv->tick_id)
+ gtk_widget_remove_tick_callback (GTK_WIDGET (entry), priv->tick_id);
+
for (i = 0; i < MAX_ICONS; i++)
{
if ((icon_info = priv->icons[i]) != NULL)
@@ -10373,6 +10381,108 @@ gtk_entry_get_cursor_hadjustment (GtkEntry *entry)
return g_object_get_qdata (G_OBJECT (entry), quark_cursor_hadjustment);
}
+static gboolean
+tick_cb (GtkWidget *widget,
+ GdkFrameClock *frame_clock,
+ gpointer user_data)
+{
+ GtkEntry *entry = GTK_ENTRY (widget);
+ GtkEntryPrivate *priv = entry->priv;
+ gint64 frame2;
+ gdouble fraction;
+
+ frame2 = gdk_frame_clock_get_frame_time (frame_clock);
+ if (priv->frame1 == 0)
+ priv->frame1 = frame2 - 16667;
+ if (priv->pulse1 == 0)
+ priv->pulse1 = priv->pulse2 - 250 * 1000000;
+
+ g_assert (priv->pulse2 > priv->pulse1);
+ g_assert (frame2 > priv->frame1);
+
+ if (frame2 - priv->pulse2 > 3 * (priv->pulse2 - priv->pulse1))
+ {
+ priv->pulse1 = 0;
+ return G_SOURCE_CONTINUE;
+ }
+
+ /* Determine the fraction to move the block from one frame
+ * to the next when pulse_fraction is how far the block should
+ * move between two calls to gtk_entry_progress_pulse().
+ */
+ fraction = priv->progress_pulse_fraction * (frame2 - priv->frame1) / MAX (frame2 - priv->pulse2, priv->pulse2 - priv->pulse1);
+
+ priv->frame1 = frame2;
+
+ /* advance the block */
+ if (priv->progress_pulse_way_back)
+ {
+ priv->progress_pulse_current -= fraction;
+
+ if (priv->progress_pulse_current < 0.0)
+ {
+ priv->progress_pulse_current = 0.0;
+ priv->progress_pulse_way_back = FALSE;
+ }
+ }
+ else
+ {
+ priv->progress_pulse_current += fraction;
+
+ if (priv->progress_pulse_current > 1.0 - priv->progress_pulse_fraction)
+ {
+ priv->progress_pulse_current = 1.0 - priv->progress_pulse_fraction;
+ priv->progress_pulse_way_back = TRUE;
+ }
+ }
+
+ gtk_widget_queue_draw (widget);
+
+ return G_SOURCE_CONTINUE;
+}
+
+static void
+gtk_entry_start_pulse_mode (GtkEntry *entry)
+{
+ GtkEntryPrivate *priv = entry->priv;
+
+ if (!priv->progress_pulse_mode)
+ {
+ priv->progress_pulse_mode = TRUE;
+ priv->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (entry), tick_cb, NULL, NULL);
+
+ priv->progress_fraction = 0.0;
+ priv->progress_pulse_way_back = FALSE;
+ priv->progress_pulse_current = 0.0;
+
+ priv->pulse2 = 0;
+ priv->pulse1 = 0;
+ priv->frame1 = 0;
+ }
+}
+
+static void
+gtk_entry_stop_pulse_mode (GtkEntry *entry)
+{
+ GtkEntryPrivate *priv = entry->priv;
+
+ if (priv->progress_pulse_mode)
+ {
+ priv->progress_pulse_mode = FALSE;
+ gtk_widget_remove_tick_callback (GTK_WIDGET (entry), priv->tick_id);
+ priv->tick_id = 0;
+ }
+}
+
+static void
+gtk_entry_update_pulse (GtkEntry *entry)
+{
+ GtkEntryPrivate *priv = entry->priv;
+
+ priv->pulse1 = priv->pulse2;
+ priv->pulse2 = g_get_monotonic_time ();
+}
+
/**
* gtk_entry_set_progress_fraction:
* @entry: a #GtkEntry
@@ -10404,13 +10514,13 @@ gtk_entry_set_progress_fraction (GtkEntry *entry,
else
old_fraction = private->progress_fraction;
+ gtk_entry_stop_pulse_mode (entry);
+
if (gtk_widget_is_drawable (widget))
get_progress_area (widget, &old_x, &old_y, &old_width, &old_height);
fraction = CLAMP (fraction, 0.0, 1.0);
-
private->progress_fraction = fraction;
- private->progress_pulse_mode = FALSE;
private->progress_pulse_current = 0.0;
if (gtk_widget_is_drawable (widget))
@@ -10469,9 +10579,6 @@ gtk_entry_set_progress_pulse_step (GtkEntry *entry,
if (fraction != private->progress_pulse_fraction)
{
private->progress_pulse_fraction = fraction;
-
- gtk_widget_queue_draw (GTK_WIDGET (entry));
-
g_object_notify (G_OBJECT (entry), "progress-pulse-step");
}
}
@@ -10510,44 +10617,10 @@ gtk_entry_get_progress_pulse_step (GtkEntry *entry)
void
gtk_entry_progress_pulse (GtkEntry *entry)
{
- GtkEntryPrivate *private;
-
g_return_if_fail (GTK_IS_ENTRY (entry));
- private = entry->priv;
-
- if (private->progress_pulse_mode)
- {
- if (private->progress_pulse_way_back)
- {
- private->progress_pulse_current -= private->progress_pulse_fraction;
-
- if (private->progress_pulse_current < 0.0)
- {
- private->progress_pulse_current = 0.0;
- private->progress_pulse_way_back = FALSE;
- }
- }
- else
- {
- private->progress_pulse_current += private->progress_pulse_fraction;
-
- if (private->progress_pulse_current > 1.0 - private->progress_pulse_fraction)
- {
- private->progress_pulse_current = 1.0 - private->progress_pulse_fraction;
- private->progress_pulse_way_back = TRUE;
- }
- }
- }
- else
- {
- private->progress_fraction = 0.0;
- private->progress_pulse_mode = TRUE;
- private->progress_pulse_way_back = FALSE;
- private->progress_pulse_current = 0.0;
- }
-
- gtk_widget_queue_draw (GTK_WIDGET (entry));
+ gtk_entry_start_pulse_mode (entry);
+ gtk_entry_update_pulse (entry);
}
/**