static void _eventd_nd_cairo_image_and_icon_draw_background(cairo_t *cr, cairo_surface_t *image, cairo_surface_t *icon, EventdNdStyle *style, gint width, gint height) { gint padding; padding = eventd_nd_style_get_bubble_padding(style); if ( image != NULL ) _eventd_nd_cairo_surface_draw(cr, image, padding, padding); if ( icon != NULL ) { gint x1, x2, y; cairo_pattern_t *mask; x2 = width - padding; x1 = x2 - cairo_image_surface_get_width(icon); y = _eventd_nd_cairo_get_valign(eventd_nd_style_get_icon_anchor(style), height, padding, cairo_image_surface_get_height(icon)); mask = cairo_pattern_create_linear(x1, 0, x2, 0); cairo_pattern_add_color_stop_rgba(mask, 0, 0, 0, 0, 0); cairo_pattern_add_color_stop_rgba(mask, eventd_nd_style_get_icon_fade_width(style), 0, 0, 0, 1); cairo_set_source_surface(cr, icon, x1, y); cairo_mask(cr, mask); cairo_surface_destroy(icon); } }
static void _eventd_nd_cairo_image_and_icon_draw_overlay(cairo_t *cr, cairo_surface_t *image, cairo_surface_t *icon, EventdNdStyle *style) { if ( image == NULL ) return; gint padding; padding = eventd_nd_style_get_bubble_padding(style); if ( icon == NULL ) _eventd_nd_cairo_surface_draw(cr, image, padding, padding); else { gint image_x, image_y; gint icon_x, icon_y; gint w, h; w = cairo_image_surface_get_width(icon); h = cairo_image_surface_get_height(icon); image_x = padding + w / 4; image_y = padding + h / 4; icon_x = padding + cairo_image_surface_get_width(image) - ( w / 2 ); icon_y = padding + cairo_image_surface_get_height(image) - ( h / 2 ); _eventd_nd_cairo_surface_draw(cr, image, image_x, image_y); _eventd_nd_cairo_surface_draw(cr, icon, icon_x, icon_y); } }
static void _eventd_nd_cairo_image_and_icon_draw_foreground(cairo_t *cr, cairo_surface_t *image, cairo_surface_t *icon, EventdNdStyle *style, gint width, gint height) { gint padding; padding = eventd_nd_style_get_bubble_padding(style); if ( image != NULL ) _eventd_nd_cairo_surface_draw(cr, image, padding, padding); if ( icon != NULL ) { gint x, y; x = width - padding - cairo_image_surface_get_width(icon); y = _eventd_nd_cairo_get_valign(eventd_nd_style_get_icon_anchor(style), height, padding, cairo_image_surface_get_height(icon)); _eventd_nd_cairo_surface_draw(cr, icon, x, y); } }
void eventd_nd_notification_draw(EventdNdNotification *self, cairo_surface_t *surface) { gint padding; gint offset_y = 0; gdouble value = -1; padding = eventd_nd_style_get_bubble_padding(self->style); switch ( eventd_nd_style_get_text_valign(self->style) ) { case EVENTD_ND_VANCHOR_BOTTOM: offset_y = self->content_size.height - self->text.height; break; case EVENTD_ND_VANCHOR_CENTER: offset_y = self->content_size.height / 2 - self->text.height / 2; break; case EVENTD_ND_VANCHOR_TOP: break; } if ( self->event != NULL ) { GVariant *val; val = eventd_event_get_data(self->event, eventd_nd_style_get_template_progress(self->style)); if ( val != NULL ) value = g_variant_get_double(val); if ( eventd_nd_style_get_progress_reversed(self->style) ) value = 1.0 - value; } cairo_t *cr; cr = cairo_create(surface); eventd_nd_draw_bubble_draw(cr, self->style, self->bubble_size.width, self->bubble_size.height, self->context->shaping, value); cairo_translate(cr, padding, padding); eventd_nd_draw_image_and_icon_draw(cr, self->image, self->icon, self->style, self->content_size.width, self->content_size.height, value); eventd_nd_draw_text_draw(cr, self->style, self->text.text, self->text.x, offset_y); cairo_destroy(cr); cairo_surface_flush(surface); }
static void _eventd_nd_notification_process(EventdNdNotification *self, EventdEvent *event) { _eventd_nd_notification_clean(self); if ( event != NULL ) self->event = eventd_event_ref(event); gint border, padding; gint progress_bar_width = 0; gint min_width, max_width; gint text_width = 0, text_max_width; gint image_width = 0, image_height = 0; switch ( self->context->shaping ) { case EVENTD_ND_SHAPING_NONE: case EVENTD_ND_SHAPING_SHAPE: self->offset.x = 0; self->offset.y = 0; self->surface_size.width = 0; self->surface_size.height = 0; break; case EVENTD_ND_SHAPING_COMPOSITING: { gint blur, offset_x, offset_y; blur = eventd_nd_style_get_bubble_border_blur(self->style) * 2; /* We must reserve enough space to avoid clipping */ offset_x = eventd_nd_style_get_bubble_border_blur_offset_x(self->style); offset_y = eventd_nd_style_get_bubble_border_blur_offset_y(self->style); self->offset.x = MAX(0, blur - offset_x); self->offset.y = MAX(0, blur - offset_y); self->surface_size.width = 2 * blur + MAX(0, ABS(offset_x) - blur); self->surface_size.height = 2 * blur + MAX(0, ABS(offset_y) - blur); } break; } border = eventd_nd_style_get_bubble_border(self->style); padding = eventd_nd_style_get_bubble_padding(self->style); min_width = eventd_nd_style_get_bubble_min_width(self->style); max_width = eventd_nd_style_get_bubble_max_width(self->style); switch ( eventd_nd_style_get_progress_placement(self->style) ) { case EVENTD_ND_STYLE_PROGRESS_PLACEMENT_BAR_BOTTOM: if ( self->event != NULL ) { GVariant *val; val = eventd_event_get_data(self->event, eventd_nd_style_get_template_progress(self->style)); if ( val != NULL ) progress_bar_width = eventd_nd_style_get_progress_bar_width(self->style); } break; case EVENTD_ND_STYLE_PROGRESS_PLACEMENT_IMAGE_BOTTOM_TOP: case EVENTD_ND_STYLE_PROGRESS_PLACEMENT_IMAGE_TOP_BOTTOM: case EVENTD_ND_STYLE_PROGRESS_PLACEMENT_IMAGE_LEFT_RIGHT: case EVENTD_ND_STYLE_PROGRESS_PLACEMENT_IMAGE_RIGHT_LEFT: case EVENTD_ND_STYLE_PROGRESS_PLACEMENT_IMAGE_CIRCULAR: break; } if ( max_width < 0 ) max_width = self->context->geometry.w - 2 * ( self->queue->margin_x + border ); max_width -= 2 * padding; min_width += 2 * padding; if ( min_width > max_width ) min_width = max_width; /* proccess data and compute the bubble size */ text_max_width = eventd_nd_style_get_text_max_width(self->style); if ( text_max_width < 0 ) text_max_width = max_width; else text_max_width = MIN(text_max_width, max_width); self->text.text = eventd_nd_draw_text_process(self->style, self->event, text_max_width, g_queue_get_length(self->queue->wait_queue), &text_width); self->content_size.width = text_width; if ( self->content_size.width < max_width ) { if ( self->event != NULL ) eventd_nd_draw_image_and_icon_process(self->context->theme_context, self->style, self->event, max_width - self->content_size.width, self->context->geometry.s, &self->image, &self->icon, &self->text.x, &image_width, &image_height); self->content_size.width += image_width; } /* We are sure that min_width <= max_width */ if ( min_width > self->content_size.width ) { self->content_size.width = min_width; /* Let the text take the remaining space if needed (e.g. Right-to-Left) */ text_width = self->content_size.width - image_width; } pango_layout_set_width(self->text.text, text_width * PANGO_SCALE); pango_layout_get_pixel_size(self->text.text, NULL, &self->text.height); self->content_size.height = MAX(image_height, self->text.height); self->bubble_size.width = self->content_size.width + 2 * padding; self->bubble_size.height = self->content_size.height + 2 * padding + progress_bar_width; self->border_size.width = self->bubble_size.width + 2 * border; self->border_size.height = self->bubble_size.height + 2 * border; self->surface_size.width += self->border_size.width; self->surface_size.height += self->border_size.height; if ( self->timeout > 0 ) { g_source_remove(self->timeout); self->timeout = g_timeout_add_full(G_PRIORITY_DEFAULT, eventd_nd_style_get_bubble_timeout(self->style), _eventd_nd_event_timedout, self, NULL); } }