[totem] browser-plugin: Update glow button for recent GTK+



commit 4006fc59ae4effb82214a9080b750036d229c938
Author: Bastien Nocera <hadess hadess net>
Date:   Mon Dec 16 15:16:04 2013 +0100

    browser-plugin: Update glow button for recent GTK+
    
    With the colour changing in CSS instead of gross hacks.

 browser-plugin/totem-glow-button.c |  330 +++++++-----------------------------
 browser-plugin/totem-glow-button.h |    7 +-
 2 files changed, 65 insertions(+), 272 deletions(-)
---
diff --git a/browser-plugin/totem-glow-button.c b/browser-plugin/totem-glow-button.c
index 9a0b3fd..691d0db 100644
--- a/browser-plugin/totem-glow-button.c
+++ b/browser-plugin/totem-glow-button.c
@@ -1,11 +1,5 @@
 /*
- * (C) Copyright 2007 Bastien Nocera <hadess hadess net>
- *
- * Glow code from libwnck/libwnck/tasklist.c:
- * Copyright © 2001 Havoc Pennington
- * Copyright © 2003 Kim Woelders
- * Copyright © 2003 Red Hat, Inc.
- *
+ * (C) Copyright 2007, 2013 Bastien Nocera <hadess hadess net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -27,253 +21,97 @@
 #include "config.h"
 #endif
 
-#include <math.h>
 #include <gtk/gtk.h>
 #include "totem-glow-button.h"
 
-#define FADE_OPACITY_DEFAULT 0.6
-#define ENTER_SPEEDUP_RATIO 0.4
-#define FADE_MAX_LOOPS 4
+struct _TotemGlowButtonClass {
+  GtkButtonClass parent_class;
+};
 
 struct _TotemGlowButton {
        GtkButton parent;
 
-       gdouble glow_start_time;
-       gdouble glow_factor;
-
-       guint button_glow;
-
-       guint glow : 1;
-       guint anim_enabled : 1;
-       guint pointer_entered : 1;
-       /* Set when we don't want to play animation
-        * anymore in pointer entered mode */
-       guint anim_finished :1;
+       gboolean glow;
 };
 
-static void totem_glow_button_set_timeout (TotemGlowButton *button, gboolean set_timeout);
+enum {
+       PROP_0,
+       PROP_GLOW
+};
 
 static GtkButtonClass *parent_class;
 
 G_DEFINE_TYPE (TotemGlowButton, totem_glow_button, GTK_TYPE_BUTTON);
 
-static gboolean
-totem_glow_button_glow (TotemGlowButton *button)
-{
-       GtkWidget *buttonw;
-       GTimeVal tv;
-       gdouble now;
-       gfloat fade_opacity, loop_time;
-
-       buttonw = GTK_WIDGET (button);
-
-       if (gtk_widget_get_realized (buttonw) == FALSE)
-               return TRUE;
-
-       if (button->anim_enabled != FALSE) {
-               g_get_current_time (&tv);
-               now = (tv.tv_sec * (1.0 * G_USEC_PER_SEC) +
-                      tv.tv_usec) / G_USEC_PER_SEC;
-
-               /* Hard-coded values */
-               fade_opacity = FADE_OPACITY_DEFAULT;
-               loop_time = 3.0;
-
-               if (button->glow_start_time <= G_MINDOUBLE) {
-                       button->glow_start_time = now;
-                       /* If the pointer entered, we want to start with 'dark' */
-                       if (button->pointer_entered != FALSE) {
-                               button->glow_start_time -= loop_time / 4.0;
-                       }
-               }
-
-               /* Timing for mouse hover animation
-                  [light]......[dark]......[light]......[dark]...
-                  {mouse hover event}
-                  [dark]..[light]..[dark]..[light]
-                  {mouse leave event}
-                  [light]......[dark]......[light]......[dark]
-               */
-               if (button->pointer_entered != FALSE) {
-                       /* pointer entered animation should be twice as fast */
-                       loop_time *= ENTER_SPEEDUP_RATIO;
-               }
-               if ((now - button->glow_start_time) > loop_time * FADE_MAX_LOOPS) {
-                       button->anim_finished = TRUE;
-                       button->glow_factor = FADE_OPACITY_DEFAULT * 0.5;
-               } else {
-                       button->glow_factor = fade_opacity * (0.5 - 0.5 * cos ((now - 
button->glow_start_time) * M_PI * 2.0 / loop_time));
-               }
-       } else {
-               button->glow_factor = FADE_OPACITY_DEFAULT * 0.5;
-       }
-
-       gtk_widget_queue_draw (GTK_WIDGET (button));
-
-       if (button->anim_finished != FALSE)
-               totem_glow_button_set_timeout (button, FALSE);
-
-       return button->anim_enabled;
-}
-
-static void
-totem_glow_button_clear_glow_start_timeout_id (TotemGlowButton *button)
-{
-       button->button_glow = 0;
-}
-
-static gboolean
-totem_glow_button_draw (GtkWidget *widget,
-                       cairo_t   *cr,
-                       gpointer   user_data)
-{
-       TotemGlowButton *button;
-       GtkStyleContext *context;
-       GtkAllocation allocation, child_allocation;
-       gint width, height;
-       GtkWidget *child;
-       GdkRGBA acolor;
-
-       button = TOTEM_GLOW_BUTTON (widget);
-
-       if (button->glow_factor == 0.0)
-               return FALSE;
-
-       context = gtk_widget_get_style_context (widget);
-
-       /* push a translucent overlay to paint to, so we can blend later */
-       cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA);
-
-       gtk_widget_get_allocation (widget, &allocation);
-
-       width = allocation.width;
-       height = allocation.height;
-
-       /* Draw a rectangle with bg[SELECTED] */
-       gtk_style_context_save (context);
-       gtk_style_context_add_class (context, "button");
-       gtk_style_context_set_state (context, GTK_STATE_SELECTED);
-       gtk_style_context_get_background_color (context, GTK_STATE_SELECTED, &acolor);
-       gdk_cairo_set_source_rgba (cr, &acolor);
-       gtk_render_background (context, cr, 0, 0, width, height);
-       gtk_style_context_restore (context);
-
-       /* then the image */
-       cairo_save (cr);
-       child = gtk_bin_get_child (GTK_BIN (button));
-       gtk_widget_get_allocation (child, &child_allocation);
-       cairo_translate (cr,
-                        child_allocation.x - allocation.x,
-                        child_allocation.y - allocation.y);
-       gtk_widget_draw (gtk_bin_get_child (GTK_BIN (button)), cr);
-       cairo_restore (cr);
-
-       /* finally blend it */
-       cairo_pop_group_to_source (cr);
-       cairo_paint_with_alpha (cr, button->glow_factor);
-
-       return FALSE;
-}
+static const char *css =
+"@keyframes blink {\n"
+"      100% { background-color: @suggested_action_button_a; }\n"
+"}\n"
+".blink {\n"
+"      background-color: @theme_bg_color;\n"
+"      background-image: none;\n"
+"      animation: blink 1s ease-in 5 alternate;\n"
+"}";
 
 static void
-totem_glow_button_map (GtkWidget *buttonw)
+totem_glow_button_get_property (GObject    *object,
+                               guint       param_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
 {
-       TotemGlowButton *button;
-
-       (* GTK_WIDGET_CLASS (parent_class)->map) (buttonw);
-
-       button = TOTEM_GLOW_BUTTON (buttonw);
-
-       if (button->glow != FALSE && button->button_glow == 0) {
-               totem_glow_button_set_glow (button, TRUE);
+       switch (param_id) {
+       case PROP_GLOW:
+               g_value_set_boolean (value, TOTEM_GLOW_BUTTON (object)->glow);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
        }
 }
 
 static void
-totem_glow_button_unmap (GtkWidget *buttonw)
+totem_glow_button_set_property (GObject      *object,
+                               guint         param_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
 {
-       TotemGlowButton *button;
-
-       button = TOTEM_GLOW_BUTTON (buttonw);
-
-       if (button->button_glow > 0) {
-               g_source_remove (button->button_glow);
-               button->button_glow = 0;
+       switch (param_id) {
+       case PROP_GLOW:
+               totem_glow_button_set_glow (TOTEM_GLOW_BUTTON (object), g_value_get_boolean (value));
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
        }
-
-       (* GTK_WIDGET_CLASS (parent_class)->unmap) (buttonw);
-}
-
-static void
-totem_glow_button_enter (GtkButton *buttonw)
-{
-       TotemGlowButton *button;
-
-       button = TOTEM_GLOW_BUTTON (buttonw);
-
-       (* GTK_BUTTON_CLASS (parent_class)->enter) (buttonw);
-
-       button->pointer_entered = TRUE;
-       button->anim_finished = FALSE;
-       button->glow_start_time = G_MINDOUBLE;
-       totem_glow_button_set_timeout (button, FALSE);
-}
-
-static void
-totem_glow_button_leave (GtkButton *buttonw)
-{
-       TotemGlowButton *button;
-
-       button = TOTEM_GLOW_BUTTON (buttonw);
-
-       (* GTK_BUTTON_CLASS (parent_class)->leave) (buttonw);
-
-       button->pointer_entered = FALSE;
-       button->glow_start_time = G_MINDOUBLE;
-       button->anim_finished = FALSE;
-       if (button->glow != FALSE)
-               totem_glow_button_set_timeout (button, TRUE);
-}
-
-static void
-totem_glow_button_finalize (GObject *object)
-{
-       TotemGlowButton *button = TOTEM_GLOW_BUTTON (object);
-
-       totem_glow_button_set_glow (button, FALSE);
-
-       G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
 static void
 totem_glow_button_class_init (TotemGlowButtonClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
-       GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-       GtkButtonClass *button_class = GTK_BUTTON_CLASS (klass);
 
        parent_class = g_type_class_peek_parent (klass);
 
-       object_class->finalize = totem_glow_button_finalize;
-       /* Note that we don't use a draw here because we
-        * want to modify what the button will draw by itself */
-       widget_class->map = totem_glow_button_map;
-       widget_class->unmap = totem_glow_button_unmap;
-       button_class->enter = totem_glow_button_enter;
-       button_class->leave = totem_glow_button_leave;
+       object_class->get_property = totem_glow_button_get_property;
+       object_class->set_property = totem_glow_button_set_property;
+
+       g_object_class_install_property (object_class,
+                                        PROP_GLOW,
+                                        g_param_spec_boolean ("glow",
+                                                              "Glow",
+                                                              "Whether the button is glowing",
+                                                              FALSE,
+                                                              G_PARAM_READWRITE));
 }
 
 static void
 totem_glow_button_init (TotemGlowButton *button)
 {
-       button->glow_start_time = 0.0;
-       button->button_glow = 0;
-       button->glow_factor = 0.0;
+       GtkCssProvider *provider;
 
-       g_signal_connect_object (button, "draw",
-                                G_CALLBACK (totem_glow_button_draw),
-                                G_OBJECT (button),
-                                G_CONNECT_AFTER);
+       provider = gtk_css_provider_new ();
+       gtk_css_provider_load_from_data (provider, css, -1, NULL);
+       gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
+                                                  GTK_STYLE_PROVIDER (provider),
+                                                  GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
 }
 
 GtkWidget *
@@ -282,65 +120,25 @@ totem_glow_button_new (void)
        return g_object_new (TOTEM_TYPE_GLOW_BUTTON, NULL);
 }
 
-/* We can only add a timeout once, we assert that, though
- * calling it multiple times to disable the animation is fine */
-static void
-totem_glow_button_set_timeout (TotemGlowButton *button, gboolean set_timeout)
-{
-       if (set_timeout != FALSE) {
-               if (button->button_glow > 0)
-                       return;
-
-               button->glow_start_time = 0.0;
-
-               /* The animation doesn't speed up or slow down based on the
-                * timeout value, but instead will just appear smoother or
-                * choppier.
-                */
-               button->button_glow =
-                       g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE,
-                                           100,
-                                           (GSourceFunc) totem_glow_button_glow, button,
-                                           (GDestroyNotify) totem_glow_button_clear_glow_start_timeout_id);
-       } else {
-               if (button->button_glow > 0) {
-                       g_source_remove (button->button_glow);
-                       button->button_glow = 0;
-               }
-               button->glow_factor = 0.0;
-               gtk_widget_queue_draw (GTK_WIDGET (button));
-       }
-}
-
 void
-totem_glow_button_set_glow (TotemGlowButton *button, gboolean glow)
+totem_glow_button_set_glow (TotemGlowButton *button,
+                           gboolean         glow)
 {
-       GtkSettings *settings;
-       gboolean anim_enabled;
+       GtkStyleContext *context;
 
        g_return_if_fail (TOTEM_IS_GLOW_BUTTON (button));
 
-       if (gtk_widget_get_mapped (GTK_WIDGET (button)) == FALSE
-           && glow != FALSE) {
-               button->glow = glow;
-               return;
-       }
-
-       settings = gtk_settings_get_for_screen
-               (gtk_widget_get_screen (GTK_WIDGET (button)));
-       g_object_get (G_OBJECT (settings),
-                     "gtk-enable-animations", &anim_enabled,
-                     NULL);
-       button->anim_enabled = anim_enabled;
-
-       if (glow == FALSE && button->button_glow == 0 && button->anim_enabled != FALSE)
-               return;
-       if (glow != FALSE && button->button_glow != 0)
+       if (button->glow == glow)
                return;
 
        button->glow = glow;
+       g_object_notify (G_OBJECT (button), "glow");
 
-       totem_glow_button_set_timeout (button, glow);
+       context = gtk_widget_get_style_context (GTK_WIDGET (button));
+       if (glow)
+               gtk_style_context_add_class (context, "blink");
+       else
+               gtk_style_context_remove_class (context, "blink");
 }
 
 gboolean
diff --git a/browser-plugin/totem-glow-button.h b/browser-plugin/totem-glow-button.h
index 138f8c4..a338b6f 100644
--- a/browser-plugin/totem-glow-button.h
+++ b/browser-plugin/totem-glow-button.h
@@ -34,12 +34,7 @@ G_BEGIN_DECLS
 #define TOTEM_IS_GLOW_BUTTON(obj)  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TOTEM_TYPE_GLOW_BUTTON))
 
 typedef struct _TotemGlowButton TotemGlowButton;
-
-typedef struct _TotemGlowButtonClass {
-  GtkButtonClass parent_class;
-
-  gpointer __bla[4];
-} TotemGlowButtonClass;
+typedef struct _TotemGlowButtonClass TotemGlowButtonClass;
 
 GType          totem_glow_button_get_type      (void) G_GNUC_CONST;
 


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