[Xfce4-commits] <xfce4-weather-plugin:master> Merge branch 'scrollbox-improvements'

Harald Judt noreply at xfce.org
Sat Dec 15 21:22:13 CET 2012


Updating branch refs/heads/master
         to 055ce41675a84f3efb8c896ae17cd3b2dd60a653 (commit)
       from dabd074d00ae5ffc654db4138fb7912c4868e392 (commit)

commit 055ce41675a84f3efb8c896ae17cd3b2dd60a653
Merge: dabd074 fdabe8f
Author: Harald Judt <h.judt at gmx.at>
Date:   Sat Dec 15 21:20:54 2012 +0100

    Merge branch 'scrollbox-improvements'

commit fdabe8fa3595ec9bd3ef5a97dcba74c355f6ee00
Author: Harald Judt <h.judt at gmx.at>
Date:   Sat Dec 15 20:42:14 2012 +0100

    Scrollbox: Use g_timeout_add_seconds where applicable.
    
    From the GLib Reference Manual:
    "If you want to have a timer in the "seconds" range and do not care about the
     exact time of the first call of the timer, use the g_timeout_add_seconds()
     function; this function allows for more optimizations and more efficient
     system power usage."
    
    This leaves g_timeout_add only for the sleep periods that control the
    label fade in / out speed.

commit e7cd852e19c59c57f39b01d6b4a5de17b2e8a2e7
Author: Harald Judt <h.judt at gmx.at>
Date:   Sat Dec 15 19:34:42 2012 +0100

    Scrollbox: Clear temporary queue before adding new labels.

commit f6d00862cf58fb35abfce892e734c339369e9cab
Author: Harald Judt <h.judt at gmx.at>
Date:   Sat Dec 15 19:26:59 2012 +0100

    Scrollbox: Reset on manual update.
    
    It's a good idea to give the user feedback when a manual update has been
    performed.

commit 960304f93aee86f1123b693ff1895acf053ef0fc
Author: Harald Judt <h.judt at gmx.at>
Date:   Sat Dec 15 10:50:53 2012 +0100

    Scrollbox: Do not abort or reset transition animation when not desired.
    
    When the scrollbox should change due to a weather data update, the
    current animation will be aborted or reset. We do not want this on
    regular updates or configuration changes regarding the labels, so
    let the current animation end and apply the changes after that.

commit 0f00bd2ab0980a2d907f1bd755ad063c7b8db680
Author: Harald Judt <h.judt at gmx.at>
Date:   Fri Dec 14 23:10:03 2012 +0100

    Scrollbox: Pause processing when invisible.
    
    Stop processing when the scrollbox becomes hidden and save CPU power.

commit 2a25b43b5ef1c50209f33e99a4e0f52be96373bf
Author: Harald Judt <h.judt at gmx.at>
Date:   Fri Dec 14 22:23:02 2012 +0100

    Scrollbox: Make adding and removing labels dynamic.
    
    These changes allow to alter the scrollbox labels seemingly on the fly,
    without disturbing the animation. Labels will be changed when fade-out
    is finished.

commit 2c24621109f5bb576d7b16d0c44157fcb062420b
Author: Harald Judt <h.judt at gmx.at>
Date:   Fri Dec 14 20:50:01 2012 +0100

    Scrollbox: Remove obsolete code.
    
    Maybe it was needed before, but it's no longer required.

commit 8c80d9279e87ebfd3729347aeb459f535dace813
Author: Harald Judt <h.judt at gmx.at>
Date:   Fri Dec 14 20:41:06 2012 +0100

    Scrollbox: Refactor code to free labels.

commit e0ba60ed9879eefd117f106c7c408c107da185df
Author: Harald Judt <h.judt at gmx.at>
Date:   Fri Dec 14 19:47:10 2012 +0100

    Scrollbox: Hook up scrolldown/scrollup events to prev/next labels.

commit 1cfa828ac72a587a3f4c0cb178f21438d6328c9f
Author: Harald Judt <h.judt at gmx.at>
Date:   Fri Dec 14 19:46:16 2012 +0100

    Scrollbox: Add function to switch to previous label.
    
    This is the counterpart to gtk_scrollbox_next_label().

commit 3803464536b63852b28dd581424e1c0c3167c108
Author: Harald Judt <h.judt at gmx.at>
Date:   Fri Dec 14 19:45:44 2012 +0100

    Scrollbox: Use doubly-linked lists instead of singly-linked lists.

commit 93285e8002ec9f1becf7415b39728d835c9f271c
Author: Harald Judt <h.judt at gmx.at>
Date:   Fri Dec 14 19:45:09 2012 +0100

    Scrollbox: Wrap around in gtk_scrollbox_next_label().

 panel-plugin/weather-scrollbox.c |  247 +++++++++++++++++++++++++++++++-------
 panel-plugin/weather-scrollbox.h |   26 ++++-
 panel-plugin/weather.c           |   27 ++---
 3 files changed, 233 insertions(+), 67 deletions(-)

diff --git a/panel-plugin/weather-scrollbox.c b/panel-plugin/weather-scrollbox.c
index 6f4dd79..ddd78b2 100644
--- a/panel-plugin/weather-scrollbox.c
+++ b/panel-plugin/weather-scrollbox.c
@@ -27,8 +27,11 @@
 #include <libxfce4panel/libxfce4panel.h>
 
 #include "weather-scrollbox.h"
-#define LABEL_REFRESH 3000
-#define LABEL_SPEED   25
+
+#define LABEL_REFRESH (3)
+#define LABEL_REFRESH_NO_ANIMATION (6)
+#define LABEL_REFRESH_NO_ANIM_INIT (1)
+#define LABEL_SPEED (25)
 
 
 static void gtk_scrollbox_finalize(GObject *object);
@@ -65,9 +68,13 @@ gtk_scrollbox_init(GtkScrollbox *self)
     GTK_WIDGET_SET_FLAGS(self, GTK_NO_WINDOW);
 
     self->labels = NULL;
+    self->labels_new = NULL;
     self->timeout_id = 0;
     self->offset = 0;
+    self->fade = FADE_NONE;
     self->active = NULL;
+    self->animate = FALSE;
+    self->visible = FALSE;
     self->orientation = GTK_ORIENTATION_HORIZONTAL;
     self->fontname = NULL;
     self->pattr_list = pango_attr_list_new();
@@ -75,6 +82,16 @@ gtk_scrollbox_init(GtkScrollbox *self)
 
 
 static void
+gtk_scrollbox_labels_free(GtkScrollbox *self)
+{
+    /* free all the labels */
+    g_list_foreach(self->labels, (GFunc) g_object_unref, NULL);
+    g_list_free(self->labels);
+    self->labels = NULL;
+}
+
+
+static void
 gtk_scrollbox_finalize(GObject *object)
 {
     GtkScrollbox *self = GTK_SCROLLBOX(object);
@@ -84,8 +101,10 @@ gtk_scrollbox_finalize(GObject *object)
         g_source_remove(self->timeout_id);
 
     /* free all the labels */
-    g_slist_foreach(self->labels, (GFunc) g_object_unref, NULL);
-    g_slist_free(self->labels);
+    gtk_scrollbox_labels_free(self);
+
+    /* free all the new labels */
+    gtk_scrollbox_clear_new(self);
 
     /* free everything else */
     g_free(self->fontname);
@@ -99,7 +118,7 @@ static void
 gtk_scrollbox_set_font(GtkScrollbox *self,
                        PangoLayout *layout)
 {
-    GSList *li;
+    GList *li;
     PangoFontDescription *desc = NULL;
 
     if (self->fontname)
@@ -125,7 +144,7 @@ gtk_scrollbox_size_request(GtkWidget *widget,
                            GtkRequisition *requisition)
 {
     GtkScrollbox *self = GTK_SCROLLBOX(widget);
-    GSList *li;
+    GList *li;
     PangoLayout *layout;
     PangoRectangle logical_rect;
     gint width, height;
@@ -181,12 +200,12 @@ gtk_scrollbox_expose_event(GtkWidget *widget,
             height = widget->allocation.y
                 + (widget->allocation.height
                    - PANGO_PIXELS(logical_rect.height)) / 2
-                + (self->animate ? self->offset : 0);
+                + (self->animate || self->fade == FADE_OUT ? self->offset : 0);
         } else {
             width = widget->allocation.x
                 + (widget->allocation.width
                    - PANGO_PIXELS(logical_rect.height)) / 2
-                + (self->animate ? self->offset : 0);
+                + (self->animate || self->fade == FADE_OUT ? self->offset : 0);
             height = widget->allocation.y
                 + (widget->allocation.height
                    - PANGO_PIXELS(logical_rect.width)) / 2;
@@ -202,12 +221,94 @@ gtk_scrollbox_expose_event(GtkWidget *widget,
 }
 
 
+void
+gtk_scrollbox_add_label(GtkScrollbox *self,
+                        const gint position,
+                        gchar *markup)
+{
+    PangoLayout *layout;
+
+    g_return_if_fail(GTK_IS_SCROLLBOX(self));
+
+    layout = gtk_widget_create_pango_layout(GTK_WIDGET(self), NULL);
+    pango_layout_set_markup(layout, markup, -1);
+    gtk_scrollbox_set_font(self, layout);
+    self->labels_new = g_list_insert(self->labels_new, layout, position);
+}
+
+
+void
+gtk_scrollbox_swap_labels(GtkScrollbox *self)
+{
+    guint len;
+    gint pos;
+
+    g_return_if_fail(GTK_IS_SCROLLBOX(self));
+
+    if (G_LIKELY(self->labels_new == NULL))
+        return;
+
+    pos = g_list_position(self->labels, self->active);
+    len = g_list_length(self->labels_new);
+
+    if (pos >= len)
+        pos = 0;
+
+    self->active = g_list_nth(self->labels_new, pos);
+    if (self->active == NULL)
+        self->active = self->labels_new;
+
+    gtk_scrollbox_labels_free(self);
+    self->labels = self->labels_new;
+    self->labels_new = NULL;
+
+    gtk_widget_queue_resize(GTK_WIDGET(self));
+}
+
+
+static gboolean
+gtk_scrollbox_fade_none(gpointer user_data)
+{
+    GtkScrollbox *self = GTK_SCROLLBOX(user_data);
+
+    if (!self->visible)
+        return FALSE;
+
+    /* start fading out if animation has been enabled */
+    if (self->animate) {
+        self->fade = FADE_OUT;
+        self->offset = 0;
+        self->timeout_id = g_timeout_add(LABEL_SPEED,
+                                         gtk_scrollbox_fade_out, self);
+        return FALSE;
+    }
+
+    if (self->timeout_id != 0) {
+        g_source_remove(self->timeout_id);
+        self->timeout_id = 0;
+    }
+
+    if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
+        self->offset = GTK_WIDGET(self)->allocation.height;
+    else
+        self->offset = GTK_WIDGET(self)->allocation.width;
+
+    gtk_scrollbox_swap_labels(self);
+    gtk_scrollbox_next_label(self);
+
+    self->timeout_id = g_timeout_add_seconds(LABEL_REFRESH_NO_ANIMATION,
+                                             gtk_scrollbox_fade_none, self);
+    return FALSE;
+}
+
+
 static gboolean
 gtk_scrollbox_sleep(gpointer user_data)
 {
     GtkScrollbox *self = GTK_SCROLLBOX(user_data);
 
-    self->timeout_id = g_timeout_add(LABEL_SPEED, gtk_scrollbox_fade_out, self);
+    self->timeout_id = g_timeout_add(LABEL_SPEED,
+                                     gtk_scrollbox_fade_out, self);
     return FALSE;
 }
 
@@ -229,7 +330,18 @@ gtk_scrollbox_fade_in(gpointer user_data)
         (self->orientation == GTK_ORIENTATION_VERTICAL && self->offset < 0))
         return TRUE;
 
-    self->timeout_id = g_timeout_add(LABEL_REFRESH, gtk_scrollbox_sleep, self);
+    if (self->visible)
+        if (self->animate) {
+            self->fade = FADE_OUT;
+            self->timeout_id =
+                g_timeout_add_seconds(LABEL_REFRESH,
+                                      gtk_scrollbox_sleep, self);
+        } else {
+            self->fade = FADE_NONE;
+            self->timeout_id =
+                g_timeout_add_seconds(LABEL_REFRESH_NO_ANIMATION,
+                                      gtk_scrollbox_fade_none, self);
+        }
     return FALSE;
 }
 
@@ -253,12 +365,9 @@ gtk_scrollbox_fade_out(gpointer user_data)
          self->offset > 0 - GTK_WIDGET(self)->allocation.width))
         return TRUE;
 
-    if (self->active != NULL) {
-        if (self->active->next != NULL)
-            self->active = self->active->next;
-        else
-            self->active = self->labels;
-
+    gtk_scrollbox_swap_labels(self);
+    gtk_scrollbox_next_label(self);
+    if (self->visible) {
         self->timeout_id = g_timeout_add(LABEL_SPEED,
                                          gtk_scrollbox_fade_in, self);
     }
@@ -274,41 +383,23 @@ gtk_scrollbox_start_fade(GtkScrollbox *self)
         self->timeout_id = 0;
     }
 
-    self->active = self->labels;
+    gtk_scrollbox_swap_labels(self);
 
-    if (g_slist_length(self->labels) > 1) {
+    if (self->animate && g_list_length(self->labels) > 1) {
         if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
             self->offset = GTK_WIDGET(self)->allocation.height;
         else
             self->offset = 0;
 
+        self->fade = FADE_IN;
         self->timeout_id = g_timeout_add(LABEL_SPEED,
-                                         gtk_scrollbox_fade_in,
-                                         self);
+                                         gtk_scrollbox_fade_in, self);
     } else
         self->offset = 0;
 }
 
 
 void
-gtk_scrollbox_set_label(GtkScrollbox *self,
-                        const gint position,
-                        gchar *markup)
-{
-    PangoLayout *layout;
-
-    g_return_if_fail(GTK_IS_SCROLLBOX(self));
-
-    layout = gtk_widget_create_pango_layout(GTK_WIDGET(self), NULL);
-    pango_layout_set_markup(layout, markup, -1);
-    gtk_scrollbox_set_font(self, layout);
-    self->labels = g_slist_insert(self->labels, layout, position);
-    gtk_widget_queue_resize(GTK_WIDGET(self));
-    gtk_scrollbox_start_fade(self);
-}
-
-
-void
 gtk_scrollbox_set_orientation(GtkScrollbox *self,
                               const GtkOrientation orientation)
 {
@@ -327,14 +418,35 @@ gtk_scrollbox_new(void)
 
 
 void
-gtk_scrollbox_clear(GtkScrollbox *self)
+gtk_scrollbox_clear_new(GtkScrollbox *self)
 {
     g_return_if_fail(GTK_IS_SCROLLBOX(self));
 
-    g_slist_foreach(self->labels, (GFunc) g_object_unref, NULL);
-    g_slist_free(self->labels);
-    self->labels = NULL;
+    /* free all the new labels */
+    g_list_foreach(self->labels_new, (GFunc) g_object_unref, NULL);
+    g_list_free(self->labels_new);
+    self->labels_new = NULL;
+}
+
 
+void
+gtk_scrollbox_reset(GtkScrollbox *self)
+{
+    g_return_if_fail(GTK_IS_SCROLLBOX(self));
+
+    if (self->timeout_id != 0) {
+        g_source_remove(self->timeout_id);
+        self->timeout_id = 0;
+    }
+
+    if (self->animate)
+        gtk_scrollbox_start_fade(self);
+    else {
+        self->fade = FADE_NONE;
+        self->timeout_id =
+            g_timeout_add_seconds(LABEL_REFRESH_NO_ANIMATION,
+                                  gtk_scrollbox_fade_none, self);
+    }
     gtk_widget_queue_resize(GTK_WIDGET(self));
 }
 
@@ -350,13 +462,58 @@ gtk_scrollbox_set_animate(GtkScrollbox *self,
 
 
 void
+gtk_scrollbox_set_visible(GtkScrollbox *self,
+                          gboolean visible)
+{
+    g_return_if_fail(GTK_IS_SCROLLBOX(self));
+
+    gtk_widget_set_visible(GTK_WIDGET(self), visible);
+    self->visible = visible;
+    if (visible) {
+        if (self->timeout_id == 0)
+            if (self->animate)
+                gtk_scrollbox_start_fade(self);
+            else {
+                self->fade = FADE_NONE;
+                self->timeout_id =
+                    g_timeout_add_seconds(LABEL_REFRESH_NO_ANIM_INIT,
+                                          gtk_scrollbox_fade_none,
+                                          self);
+            }
+    } else
+        if (self->timeout_id != 0) {
+            g_source_remove(self->timeout_id);
+            self->timeout_id = 0;
+        }
+}
+
+
+void
+gtk_scrollbox_prev_label(GtkScrollbox *self)
+{
+    g_return_if_fail(GTK_IS_SCROLLBOX(self));
+
+    if (g_list_length(self->labels) > 1) {
+        if (self->active->prev != NULL)
+            self->active = self->active->prev;
+        else
+            self->active = g_list_last(self->labels);
+        gtk_widget_queue_draw(GTK_WIDGET(self));
+    }
+}
+
+
+void
 gtk_scrollbox_next_label(GtkScrollbox *self)
 {
     g_return_if_fail(GTK_IS_SCROLLBOX(self));
 
-    if (self->active->next != NULL) {
-        self->active = self->active->next;
-        gtk_widget_queue_resize(GTK_WIDGET(self));
+    if (g_list_length(self->labels) > 1) {
+        if (self->active->next != NULL)
+            self->active = self->active->next;
+        else
+            self->active = self->labels;
+        gtk_widget_queue_draw(GTK_WIDGET(self));
     }
 }
 
diff --git a/panel-plugin/weather-scrollbox.h b/panel-plugin/weather-scrollbox.h
index 216dcc0..70dc4a7 100644
--- a/panel-plugin/weather-scrollbox.h
+++ b/panel-plugin/weather-scrollbox.h
@@ -37,17 +37,26 @@ GType gtk_scrollbox_get_type(void);
     (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_SCROLLBOX, GtkScrollboxClass))
 
 
+typedef enum {
+    FADE_IN,
+    FADE_OUT,
+    FADE_NONE
+} fade_states;
+
 typedef struct _GtkScrollbox GtkScrollbox;
 typedef struct _GtkScrollboxClass GtkScrollboxClass;
 
 struct _GtkScrollbox {
     GtkDrawingArea __parent__;
 
-    GSList *labels;
+    GList *labels;
+    GList *labels_new;
+    GList *active;
     guint timeout_id;
     gint offset;
-    GSList *active;
     gboolean animate;
+    gboolean visible;
+    fade_states fade;
     GtkOrientation orientation;
     gchar *fontname;
     PangoAttrList *pattr_list;
@@ -58,20 +67,29 @@ struct _GtkScrollboxClass {
 };
 
 
-void gtk_scrollbox_set_label(GtkScrollbox *self,
+void gtk_scrollbox_add_label(GtkScrollbox *self,
                              gint position,
                              gchar *markup);
 
+void gtk_scrollbox_swap_labels(GtkScrollbox *self);
+
 void gtk_scrollbox_set_orientation(GtkScrollbox *self,
                                    GtkOrientation orientation);
 
 GtkWidget *gtk_scrollbox_new(void);
 
-void gtk_scrollbox_clear(GtkScrollbox *self);
+void gtk_scrollbox_clear_new(GtkScrollbox *self);
+
+void gtk_scrollbox_reset(GtkScrollbox *self);
 
 void gtk_scrollbox_set_animate(GtkScrollbox *self,
                                gboolean animate);
 
+void gtk_scrollbox_set_visible(GtkScrollbox *self,
+                               gboolean visible);
+
+void gtk_scrollbox_prev_label(GtkScrollbox *self);
+
 void gtk_scrollbox_next_label(GtkScrollbox *self);
 
 void gtk_scrollbox_set_fontname(GtkScrollbox *self,
diff --git a/panel-plugin/weather.c b/panel-plugin/weather.c
index fd096e2..ca7f0fb 100644
--- a/panel-plugin/weather.c
+++ b/panel-plugin/weather.c
@@ -271,6 +271,8 @@ scrollbox_set_visible(plugin_data *data)
         gtk_widget_show_all(GTK_WIDGET(data->vbox_center_scrollbox));
     else
         gtk_widget_hide_all(GTK_WIDGET(data->vbox_center_scrollbox));
+    gtk_scrollbox_set_visible(GTK_SCROLLBOX(data->scrollbox),
+                              data->show_scrollbox);
 }
 
 
@@ -282,10 +284,7 @@ update_scrollbox(plugin_data *data)
     data_types type;
     gint i = 0, j = 0;
 
-    gtk_scrollbox_clear(GTK_SCROLLBOX(data->scrollbox));
-    gtk_scrollbox_set_animate(GTK_SCROLLBOX(data->scrollbox),
-                              data->scrollbox_animate);
-
+    gtk_scrollbox_clear_new(GTK_SCROLLBOX(data->scrollbox));
     if (data->weatherdata && data->weatherdata->current_conditions) {
         while (i < data->labels->len) {
             j = 0;
@@ -300,7 +299,7 @@ update_scrollbox(plugin_data *data)
                 g_free(single);
                 j++;
             }
-            gtk_scrollbox_set_label(GTK_SCROLLBOX(data->scrollbox),
+            gtk_scrollbox_add_label(GTK_SCROLLBOX(data->scrollbox),
                                     -1, out->str);
             g_string_free(out, TRUE);
             i = i + j;
@@ -308,15 +307,12 @@ update_scrollbox(plugin_data *data)
         weather_debug("Added %u labels to scrollbox.", data->labels->len);
     } else {
         single = g_strdup(_("No Data"));
-        gtk_scrollbox_set_label(GTK_SCROLLBOX(data->scrollbox), -1, single);
+        gtk_scrollbox_add_label(GTK_SCROLLBOX(data->scrollbox), -1, single);
         g_free(single);
         weather_debug("No weather data available, set single label '%s'.",
                       _("No Data"));
     }
-
-    /* show or hide scrollbox */
     scrollbox_set_visible(data);
-
     weather_debug("Updated scrollbox.");
 }
 
@@ -1131,6 +1127,7 @@ update_weatherdata_with_reset(plugin_data *data, gboolean clear)
         read_cache_file(data);
     }
     schedule_next_wakeup(data);
+    gtk_scrollbox_reset(GTK_SCROLLBOX(data->scrollbox));
     weather_debug("Updated weatherdata with reset.");
 }
 
@@ -1188,9 +1185,10 @@ cb_scroll(GtkWidget *widget,
 {
     plugin_data *data = (plugin_data *) user_data;
 
-    if (event->direction == GDK_SCROLL_UP ||
-        event->direction == GDK_SCROLL_DOWN)
+    if (event->direction == GDK_SCROLL_UP)
         gtk_scrollbox_next_label(GTK_SCROLLBOX(data->scrollbox));
+    else if (event->direction == GDK_SCROLL_DOWN)
+        gtk_scrollbox_prev_label(GTK_SCROLLBOX(data->scrollbox));
 
     return FALSE;
 }
@@ -1552,13 +1550,6 @@ xfceweather_create_control(XfcePanelPlugin *plugin)
     lbl = WIND_SPEED;
     g_array_append_val(data->labels, lbl);
 
-    /*
-     * FIXME: Without this the first label looks odd, because
-     * the gc isn't created yet
-     */
-    gtk_scrollbox_set_label(GTK_SCROLLBOX(data->scrollbox), -1, "1");
-    gtk_scrollbox_clear(GTK_SCROLLBOX(data->scrollbox));
-
     weather_debug("Plugin widgets set up and ready.");
     return data;
 }


More information about the Xfce4-commits mailing list