Index: src/cheese-countdown.c =================================================================== --- src/cheese-countdown.c (revision 678) +++ src/cheese-countdown.c (working copy) @@ -53,8 +53,160 @@ cheese_countdown_cb_t picture_callback; cheese_countdown_cb_t hide_callback; gpointer callback_data; + gdouble bg[3]; + gdouble bg_light[3]; + gdouble text[3]; } CheeseCountdownPrivate; +/* copied from gtk/gtkhsv.c, released under GPL v2 */ +/* Converts from HSV to RGB */ +static void +hsv_to_rgb (gdouble *h, + gdouble *s, + gdouble *v) +{ + gdouble hue, saturation, value; + gdouble f, p, q, t; + + if (*s <= 0.0) + { + *h = *v; + *s = *v; + *v = *v; /* heh */ + } + else + { + hue = *h * 6.0; + saturation = *s; + value = *v; + + if (hue >= 6.0) + hue = 0.0; + + f = hue - (int) hue; + p = value * (1.0 - saturation); + q = value * (1.0 - saturation * f); + t = value * (1.0 - saturation * (1.0 - f)); + + switch ((int) hue) + { + case 0: + *h = value; + *s = t; + *v = p; + break; + + case 1: + *h = q; + *s = value; + *v = p; + break; + + case 2: + *h = p; + *s = value; + *v = t; + break; + + case 3: + *h = p; + *s = q; + *v = value; + break; + + case 4: + *h = t; + *s = p; + *v = value; + break; + + case 5: + *h = value; + *s = p; + *v = q; + break; + + default: + g_assert_not_reached (); + } + } +} + +/* Converts from RGB to HSV */ +static void +rgb_to_hsv (gdouble *r, + gdouble *g, + gdouble *b) +{ + gdouble red, green, blue; + gdouble h, s, v; + gdouble min, max; + gdouble delta; + + red = *r; + green = *g; + blue = *b; + + h = 0.0; + + if (red > green) + { + if (red > blue) + max = red; + else + max = blue; + + if (green < blue) + min = green; + else + min = blue; + } + else + { + if (green > blue) + max = green; + else + max = blue; + + if (red < blue) + min = red; + else + min = blue; + } + + v = max; + + if (max != 0.0) + s = (max - min) / max; + else + s = 0.0; + + if (s <= 0.0) + h = 0.0; + else + { + delta = max - min; + + if (red == max) + h = (green - blue) / delta; + else if (green == max) + h = 2 + (blue - red) / delta; + else if (blue == max) + h = 4 + (red - green) / delta; + + h /= 6.0; + + if (h < 0.0) + h += 1.0; + else if (h > 1.0) + h -= 1.0; + } + + *r = h; + *g = s; + *b = v; +} + static gint do_text (cairo_t* pContext, gchar* pcText, @@ -126,8 +278,8 @@ static gboolean on_expose (GtkWidget* widget, GdkEventExpose* pEvent, gpointer data) { - CheeseCountdownPrivate* priv = CHEESE_COUNTDOWN_GET_PRIVATE (widget); - cairo_t* pContext = NULL; + CheeseCountdownPrivate *priv = CHEESE_COUNTDOWN_GET_PRIVATE (widget); + cairo_t *pContext = NULL; gdouble fWidth = (gdouble) widget->allocation.width; gdouble fHeight = (gdouble) widget->allocation.height; gint iOffsetX = (widget->allocation.width - 4 * 24) / 2; @@ -155,6 +307,7 @@ else fAlphaClick = 0.5f; + /* clear drawing-context */ pContext = gdk_cairo_create (widget->window); cairo_set_operator (pContext, CAIRO_OPERATOR_CLEAR); @@ -165,23 +318,24 @@ cairo_rectangle (pContext, 0.0f, 0.0f, fWidth, fHeight); cairo_clip (pContext); - /* draw the red-ish background */ + /* draw the color-ish background */ /* glossy version */ - /* - cairo_set_source_rgba (pContext, 1.0f, 0.5f, 0.5f, 1.0f); + cairo_set_source_rgba (pContext, priv->bg_light[R], priv->bg_light[G], priv->bg_light[B], 1.0f); cairo_rectangle (pContext, 0.0f, 0.0f, fWidth, fHeight); cairo_fill (pContext); - cairo_set_source_rgba (pContext, 1.0f, 0.25f, 0.25f, 1.0f); + + cairo_set_source_rgba (pContext, priv->bg[R], priv->bg[G], priv->bg[B], 1.0f); cairo_rectangle (pContext, 0.0f, fHeight / 2.0f, fWidth, fHeight / 2.0f); cairo_fill (pContext); - */ /* plain version */ - cairo_set_source_rgba (pContext, 1.0f, 0.25f, 0.25f, 1.0f); + /* + cairo_set_source_rgba (pContext, bg[R], bg[G], bg[B], 1.0f); cairo_rectangle (pContext, 0.0f, 0.0f, fWidth, fHeight); cairo_fill (pContext); + */ /* draw the 3 */ - cairo_set_source_rgba (pContext, 1.0f, 1.0f, 1.0f, fAlpha3); + cairo_set_source_rgba (pContext, priv->text[R], priv->text[G], priv->text[B], fAlpha3); cairo_move_to (pContext, (gdouble) iOffsetX, (gdouble) iOffsetY); iOffsetX += do_text (pContext, "3 ", @@ -192,7 +346,7 @@ cairo_fill (pContext); /* draw the 2 */ - cairo_set_source_rgba (pContext, 1.0f, 1.0f, 1.0f, fAlpha2); + cairo_set_source_rgba (pContext, priv->text[R], priv->text[G], priv->text[B], fAlpha2); cairo_move_to (pContext, (gdouble) iOffsetX, (gdouble) iOffsetY); iOffsetX += do_text (pContext, "2 ", @@ -203,7 +357,7 @@ cairo_fill (pContext); /* draw the 1 */ - cairo_set_source_rgba (pContext, 1.0f, 1.0f, 1.0f, fAlpha1); + cairo_set_source_rgba (pContext, priv->text[R], priv->text[G], priv->text[B], fAlpha1); cairo_move_to (pContext, (gdouble) iOffsetX, (gdouble) iOffsetY); iOffsetX += do_text (pContext, "1 ", @@ -235,7 +389,7 @@ } static cairo_surface_t* -create_surface_from_svg (gchar* pcFilename) +create_surface_from_svg (GtkWidget *widget, gchar* pcFilename) { cairo_surface_t* pSurface = NULL; RsvgHandle* pSvgHandle = NULL; @@ -243,6 +397,8 @@ cairo_t* pContext = NULL; RsvgDimensionData dimension; + CheeseCountdownPrivate* priv = CHEESE_COUNTDOWN_GET_PRIVATE (widget); + rsvg_init (); /* load svg-file from disk */ @@ -250,7 +406,7 @@ if (!pSvgHandle) { g_print ("Could not load file %s!\n", pcFilename); - g_error_free(pError); + g_error_free (pError); return NULL; } @@ -259,8 +415,8 @@ /* create a surface-buffer */ pSurface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, - dimension.width, - dimension.height); + dimension.width, + dimension.height); if (cairo_surface_status (pSurface) != CAIRO_STATUS_SUCCESS) { g_print ("Could not create surface for svg-icon!\n"); @@ -276,8 +432,8 @@ } /* clear that context */ - cairo_set_source_rgba (pContext, 1.0f, 1.0f, 1.0f, 0.0f); - cairo_set_operator (pContext, CAIRO_OPERATOR_OVER); + cairo_set_source_rgba (pContext, priv->text[R], priv->text[G], priv->text[B], 1.0f); + cairo_set_operator (pContext, CAIRO_OPERATOR_XOR); cairo_paint (pContext); /* draw icon into surface-buffer */ @@ -291,6 +447,44 @@ return pSurface; } +static void +on_style_set_cb (GtkWidget *widget, GtkStyle *previous_style, gpointer data) +{ + CheeseCountdownPrivate* priv = CHEESE_COUNTDOWN_GET_PRIVATE (data); + + GdkColor *color_bg = >K_WIDGET(widget)->style->bg[GTK_STATE_SELECTED]; + GdkColor *color_text = >K_WIDGET(widget)->style->text[GTK_STATE_SELECTED]; + priv->bg[R] = ((double)color_bg->red) / 65535; + priv->bg[G] = ((double)color_bg->green) / 65535; + priv->bg[B] = ((double)color_bg->blue) / 65535; + priv->text[R] = ((double)color_text->red) / 65535; + priv->text[G] = ((double)color_text->green) / 65535; + priv->text[B] = ((double)color_text->blue) / 65535; + gdouble h, s, v; + gdouble s_mid, s_light, s_dark; + + h = priv->bg[R]; s = priv->bg[G]; v = priv->bg[B]; + rgb_to_hsv (&h, &s, &v); + + s_mid = s; + if (s_mid <= 0.125) + s_mid = 0.125; + if (s_mid >= 0.875) + s_mid = 0.875; + s_dark = s_mid - 0.125; + s_light = s_mid + 0.125; + + priv->bg[R] = h; priv->bg[G] = s_light; priv->bg[B] = v; + hsv_to_rgb (&priv->bg[R], &priv->bg[G], &priv->bg[B]); + + priv->bg_light[R] = h; priv->bg_light[G] = s_dark; priv->bg_light[B] = v; + hsv_to_rgb (&priv->bg_light[R], &priv->bg_light[G], &priv->bg_light[B]); + + /* create/load svg-icon */ + g_free(priv->pSurface); + priv->pSurface = create_surface_from_svg (widget, PACKAGE_DATADIR "/pixmaps/camera-icon.svg"); +} + static gboolean cheese_countdown_cb (gpointer countdown) { @@ -366,14 +560,14 @@ { CheeseCountdownPrivate* priv = CHEESE_COUNTDOWN_GET_PRIVATE (countdown); - /* create/load svg-icon */ - priv->pSurface = create_surface_from_svg (PACKAGE_DATADIR "/pixmaps/camera-icon.svg"); priv->iState = STATE_OFF; priv->picture_callback = NULL; priv->hide_callback = NULL; g_signal_connect (G_OBJECT (countdown), "expose-event", - G_CALLBACK (on_expose), NULL); + G_CALLBACK (on_expose), NULL); + g_signal_connect (G_OBJECT (countdown), "style-set", + G_CALLBACK (on_style_set_cb), countdown); g_timeout_add (100, redraw_handler, (gpointer) countdown); } Index: data/pixmaps/camera-icon.svg =================================================================== --- data/pixmaps/camera-icon.svg (revision 678) +++ data/pixmaps/camera-icon.svg (working copy) @@ -2,7 +2,7 @@ @@ -29,10 +29,10 @@ + inkscape:zoom="13.566667" + inkscape:cx="19.732415" + inkscape:cy="17.268334" + inkscape:window-x="3" + inkscape:window-y="51" + inkscape:current-layer="layer3" + showgrid="true"> + + + - - - - - - - +