Implement tinting by icon content (issue #638; thanks @heisenbug)

This commit is contained in:
o9000
2017-11-19 22:12:07 +01:00
parent 247687307b
commit 9f4087b471
10 changed files with 205 additions and 44 deletions

View File

@@ -490,28 +490,59 @@ void draw(Area *a)
cairo_surface_destroy(cs);
}
double tint_color_channel(double a, double b, double tint_weight)
{
double gamma = 2.2;
if (tint_weight == 0.0)
return a;
double result = sqrt((1.-tint_weight)*pow(a, gamma) + tint_weight * pow(b, gamma));
return result;
}
void set_cairo_source_tinted(cairo_t *c, Color *color1, Color *color2, double tint_weight)
{
cairo_set_source_rgba(c,
tint_color_channel(color1->rgb[0], color2->rgb[0], tint_weight),
tint_color_channel(color1->rgb[1], color2->rgb[1], tint_weight),
tint_color_channel(color1->rgb[2], color2->rgb[2], tint_weight),
color1->alpha);
}
void set_cairo_source_bg_color(Area *a, cairo_t *c)
{
Color content_color;
if (a->_get_content_color)
a->_get_content_color(a, &content_color);
else
bzero(&content_color, sizeof(content_color));
if (a->mouse_state == MOUSE_OVER)
set_cairo_source_tinted(c, &a->bg->fill_color_hover, &content_color, a->bg->fill_content_tint_weight);
else if (a->mouse_state == MOUSE_DOWN)
set_cairo_source_tinted(c, &a->bg->fill_color_pressed, &content_color, a->bg->fill_content_tint_weight);
else
set_cairo_source_tinted(c, &a->bg->fill_color, &content_color, a->bg->fill_content_tint_weight);
}
void set_cairo_source_border_color(Area *a, cairo_t *c)
{
Color content_color;
if (a->_get_content_color)
a->_get_content_color(a, &content_color);
else
bzero(&content_color, sizeof(content_color));
if (a->mouse_state == MOUSE_OVER)
set_cairo_source_tinted(c, &a->bg->border_color_hover, &content_color, a->bg->border_content_tint_weight);
else if (a->mouse_state == MOUSE_DOWN)
set_cairo_source_tinted(c, &a->bg->border_color_pressed, &content_color, a->bg->border_content_tint_weight);
else
set_cairo_source_tinted(c, &a->bg->border.color, &content_color, a->bg->border_content_tint_weight);
}
void draw_background(Area *a, cairo_t *c)
{
if ((a->bg->fill_color.alpha > 0.0) ||
(panel_config.mouse_effects && (a->has_mouse_over_effect || a->has_mouse_press_effect))) {
if (a->mouse_state == MOUSE_OVER)
cairo_set_source_rgba(c,
a->bg->fill_color_hover.rgb[0],
a->bg->fill_color_hover.rgb[1],
a->bg->fill_color_hover.rgb[2],
a->bg->fill_color_hover.alpha);
else if (a->mouse_state == MOUSE_DOWN)
cairo_set_source_rgba(c,
a->bg->fill_color_pressed.rgb[0],
a->bg->fill_color_pressed.rgb[1],
a->bg->fill_color_pressed.rgb[2],
a->bg->fill_color_pressed.alpha);
else
cairo_set_source_rgba(c,
a->bg->fill_color.rgb[0],
a->bg->fill_color.rgb[1],
a->bg->fill_color.rgb[2],
a->bg->fill_color.alpha);
// Not sure about this
draw_rect(c,
left_border_width(a),
@@ -519,7 +550,7 @@ void draw_background(Area *a, cairo_t *c)
a->width - left_right_border_width(a),
a->height - top_bottom_border_width(a),
a->bg->border.radius - a->bg->border.width / 1.571);
set_cairo_source_bg_color(a, c);
cairo_fill(c);
}
for (GList *l = a->gradient_instances_by_state[a->mouse_state]; l; l = l->next) {
@@ -540,24 +571,7 @@ void draw_background(Area *a, cairo_t *c)
cairo_set_line_width(c, a->bg->border.width);
// draw border inside (x, y, width, height)
if (a->mouse_state == MOUSE_OVER)
cairo_set_source_rgba(c,
a->bg->border_color_hover.rgb[0],
a->bg->border_color_hover.rgb[1],
a->bg->border_color_hover.rgb[2],
a->bg->border_color_hover.alpha);
else if (a->mouse_state == MOUSE_DOWN)
cairo_set_source_rgba(c,
a->bg->border_color_pressed.rgb[0],
a->bg->border_color_pressed.rgb[1],
a->bg->border_color_pressed.rgb[2],
a->bg->border_color_pressed.alpha);
else
cairo_set_source_rgba(c,
a->bg->border.color.rgb[0],
a->bg->border.color.rgb[1],
a->bg->border.color.rgb[2],
a->bg->border.color.alpha);
set_cairo_source_border_color(a, c);
draw_rect_on_sides(c,
left_border_width(a) / 2.,
top_border_width(a) / 2.,