From 1208f2bde04face0b25fb31bbce3c85d3fb66f2e Mon Sep 17 00:00:00 2001 From: Cosimo Cecchi Date: Mon, 6 Jun 2011 11:38:45 -0400 Subject: [PATCH] shadow: render icon-shadow for spinners --- gtk/Makefile.am | 1 + gtk/gtkshadow.c | 25 ++++++ gtk/gtkshadowprivate.h | 5 ++ gtk/gtkthemingengine.c | 151 ++++++++++++++++++++++------------ gtk/gtkthemingengineprivate.h | 30 +++++++ 5 files changed, 160 insertions(+), 52 deletions(-) create mode 100644 gtk/gtkthemingengineprivate.h diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 9e37c3a944..03f4381bb8 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -445,6 +445,7 @@ gtk_private_h_sources = \ gtktexttagprivate.h \ gtktexttypes.h \ gtktextutil.h \ + gtkthemingengineprivate.h \ gtktimeline.h \ gtktoolpaletteprivate.h \ gtktreedatalist.h \ diff --git a/gtk/gtkshadow.c b/gtk/gtkshadow.c index c8757b33ba..180c968171 100644 --- a/gtk/gtkshadow.c +++ b/gtk/gtkshadow.c @@ -24,6 +24,7 @@ #include "gtkshadowprivate.h" #include "gtkstylecontext.h" #include "gtkpango.h" +#include "gtkthemingengineprivate.h" typedef struct _GtkShadowElement GtkShadowElement; @@ -298,3 +299,27 @@ _gtk_icon_shadow_paint (GtkShadow *shadow, cairo_pattern_destroy (pattern); } } + +void +_gtk_icon_shadow_paint_spinner (GtkShadow *shadow, + cairo_t *cr, + gdouble radius, + gdouble progress) +{ + GtkShadowElement *element; + GList *l; + + for (l = g_list_last (shadow->elements); l != NULL; l = l->prev) + { + element = l->data; + + cairo_save (cr); + + cairo_translate (cr, element->hoffset, element->voffset); + _gtk_theming_engine_paint_spinner (cr, + radius, progress, + &element->color); + + cairo_restore (cr); + } +} diff --git a/gtk/gtkshadowprivate.h b/gtk/gtkshadowprivate.h index 6f1165566d..08dd3b6df7 100644 --- a/gtk/gtkshadowprivate.h +++ b/gtk/gtkshadowprivate.h @@ -61,6 +61,11 @@ void _gtk_text_shadow_paint_layout (GtkShadow *shadow, void _gtk_icon_shadow_paint (GtkShadow *shadow, cairo_t *cr); +void _gtk_icon_shadow_paint_spinner (GtkShadow *shadow, + cairo_t *cr, + gdouble radius, + gdouble progress); + G_END_DECLS #endif /* __GTK_SHADOW_H__ */ diff --git a/gtk/gtkthemingengine.c b/gtk/gtkthemingengine.c index 13c5e34b9f..68520a0160 100644 --- a/gtk/gtkthemingengine.c +++ b/gtk/gtkthemingengine.c @@ -31,6 +31,7 @@ #include "gtkpango.h" #include "gtkshadowprivate.h" #include "gtkcsstypesprivate.h" +#include "gtkthemingengineprivate.h" /** * SECTION:gtkthemingengine @@ -3031,6 +3032,103 @@ gtk_theming_engine_render_handle (GtkThemingEngine *engine, cairo_restore (cr); } +void +_gtk_theming_engine_paint_spinner (cairo_t *cr, + gdouble radius, + gdouble progress, + GdkRGBA *color) +{ + guint num_steps, step; + gdouble half; + gint i; + + num_steps = 12; + + if (progress >= 0) + step = (guint) (progress * num_steps); + else + step = 0; + + cairo_save (cr); + + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_set_line_width (cr, 2.0); + + half = num_steps / 2; + + for (i = 0; i < num_steps; i++) + { + gint inset = 0.7 * radius; + + /* transparency is a function of time and intial value */ + gdouble t = 1.0 - (gdouble) ((i + step) % num_steps) / num_steps; + gdouble xscale = - sin (i * G_PI / half); + gdouble yscale = - cos (i * G_PI / half); + + cairo_set_source_rgba (cr, + color->red, + color->green, + color->blue, + color->alpha * t); + + cairo_move_to (cr, + (radius - inset) * xscale, + (radius - inset) * yscale); + cairo_line_to (cr, + radius * xscale, + radius * yscale); + + cairo_stroke (cr); + } + + cairo_restore (cr); +} + +static void +render_spinner (GtkThemingEngine *engine, + cairo_t *cr, + gdouble x, + gdouble y, + gdouble width, + gdouble height) +{ + GtkStateFlags state; + GtkShadow *shadow; + GdkRGBA color; + gdouble progress; + gdouble radius; + + state = gtk_theming_engine_get_state (engine); + + if (!gtk_theming_engine_state_is_running (engine, GTK_STATE_ACTIVE, &progress)) + progress = -1; + + radius = MIN (width / 2, height / 2); + + gtk_theming_engine_get_color (engine, state, &color); + gtk_theming_engine_get (engine, state, + "icon-shadow", &shadow, + NULL); + + cairo_save (cr); + cairo_translate (cr, x + width / 2, y + height / 2); + + if (shadow != NULL) + { + _gtk_icon_shadow_paint_spinner (shadow, cr, + radius, + progress); + _gtk_shadow_unref (shadow); + } + + _gtk_theming_engine_paint_spinner (cr, + radius, + progress, + &color); + + cairo_restore (cr); +} + static void gtk_theming_engine_render_activity (GtkThemingEngine *engine, cairo_t *cr, @@ -3041,58 +3139,7 @@ gtk_theming_engine_render_activity (GtkThemingEngine *engine, { if (gtk_theming_engine_has_class (engine, GTK_STYLE_CLASS_SPINNER)) { - GtkStateFlags state; - guint num_steps, step; - GdkRGBA color; - gdouble progress; - gdouble radius; - gdouble half; - gint i; - - num_steps = 12; - - state = gtk_theming_engine_get_state (engine); - gtk_theming_engine_get_color (engine, state, &color); - - if (gtk_theming_engine_state_is_running (engine, GTK_STATE_ACTIVE, &progress)) - step = (guint) (progress * num_steps); - else - step = 0; - - cairo_save (cr); - - cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - cairo_set_line_width (cr, 2.0); - cairo_translate (cr, x + width / 2, y + height / 2); - - radius = MIN (width / 2, height / 2); - half = num_steps / 2; - - for (i = 0; i < num_steps; i++) - { - gint inset = 0.7 * radius; - - /* transparency is a function of time and intial value */ - gdouble t = 1.0 - (gdouble) ((i + step) % num_steps) / num_steps; - gdouble xscale = - sin (i * G_PI / half); - gdouble yscale = - cos (i * G_PI / half); - - cairo_set_source_rgba (cr, - color.red, - color.green, - color.blue, - color.alpha * t); - - cairo_move_to (cr, - (radius - inset) * xscale, - (radius - inset) * yscale); - cairo_line_to (cr, - radius * xscale, - radius * yscale); - cairo_stroke (cr); - } - - cairo_restore (cr); + render_spinner (engine, cr, x, y, width, height); } else { diff --git a/gtk/gtkthemingengineprivate.h b/gtk/gtkthemingengineprivate.h new file mode 100644 index 0000000000..caf189ec6b --- /dev/null +++ b/gtk/gtkthemingengineprivate.h @@ -0,0 +1,30 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2010 Carlos Garnacho + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GTK_THEMING_ENGINE_PRIVATE_H__ +#define __GTK_THEMING_ENGINE_PRIVATE_H__ + +#include + +void _gtk_theming_engine_paint_spinner (cairo_t *cr, + gdouble radius, + gdouble progress, + GdkRGBA *color); + +#endif /* __GTK_THEMING_ENGINE_PRIVATE_H__ */