static void mnb_toolbar_background_paint_background (MxWidget *self, ClutterActor *background, const ClutterColor *color) { MnbToolbarBackgroundPrivate *priv = TOOLBAR_BACKGROUND_PRIVATE (self); ClutterActor *actor = (ClutterActor *) self; CoglHandle cogl_texture, cogl_material; ClutterActorBox box = { 0, }; gfloat width, height; gfloat tex_width, tex_height; gfloat ex, ey; gfloat tx1, ty1, tx2, ty2; guint8 opacity; /* Copied from MxWidget: * * Default implementation just draws the background * colour and the image on top */ if (color && color->alpha != 0) { ClutterColor bg_color = *color; bg_color.alpha = clutter_actor_get_paint_opacity (actor) * bg_color.alpha / 255; clutter_actor_get_allocation_box (actor, &box); width = box.x2 - box.x1; height = box.y2 - box.y1; cogl_set_source_color4ub (bg_color.red, bg_color.green, bg_color.blue, bg_color.alpha); cogl_rectangle (0, 0, width, height); } /* * Copied from MxTextureFrame */ /* no need to paint stuff if we don't have a texture */ if (G_UNLIKELY (priv->parent_texture == NULL)) return; cogl_texture = clutter_texture_get_cogl_texture (priv->parent_texture); if (cogl_texture == COGL_INVALID_HANDLE) return; cogl_material = clutter_texture_get_cogl_material (priv->parent_texture); if (cogl_material == COGL_INVALID_HANDLE) return; tex_width = cogl_texture_get_width (cogl_texture); tex_height = cogl_texture_get_height (cogl_texture); clutter_actor_get_allocation_box (actor, &box); width = box.x2 - box.x1; height = box.y2 - box.y1; opacity = clutter_actor_get_paint_opacity (actor); /* Paint using the parent texture's material. It should already have the cogl texture set as the first layer */ /* NB: for correct blending we need set a preumultiplied color here: */ cogl_material_set_color4ub (cogl_material, opacity, opacity, opacity, opacity); selector_texture = mnb_toolbar_get_selector_texture (priv->toolbar); cogl_material_set_layer (cogl_material, 1, selector_texture); cogl_material_set_layer_wrap_mode (cogl_material, 1, COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE); if (!cogl_material_set_layer_combine (cogl_material, 1, "RGBA = MODULATE(PREVIOUS,TEXTURE)", &error)) { g_warning (G_STRLOC ": Error setting layer combine blend string: %s", error->message); g_error_free (error); } cogl_set_source (cogl_material); /* simple stretch */ if (priv->left == 0 && priv->right == 0 && priv->top == 0 && priv->bottom == 0) { float spot_width, spot_height; float coords[8] = { 0, 0, 1, 1, 0, 0, 0, 0 }; mnb_toolbar_get_selector_allocation_box (priv->toolbar, &box); spot_width = box.x2 - box.x1; spot_height = box.y2 - box.y1; coords[4] = -(box.x1 / width) * (width / spot_width); coords[5] = -(box.y1 / height) * (height / spot_height); coords[6] = width / spot_width - (box.x1 / width) * (width / spot_width); coords[7] = height / spot_height - (box.y1 / height) * (height / spot_height); cogl_rectangle_with_multitexture_coords (0, 0, width, height, coords, 8); return; } tx1 = priv->left / tex_width; tx2 = (tex_width - priv->right) / tex_width; ty1 = priv->top / tex_height; ty2 = (tex_height - priv->bottom) / tex_height; ex = width - priv->right; if (ex < priv->left) ex = priv->left; ey = height - priv->bottom; if (ey < priv->top) ey = priv->top; { GLfloat rectangles[] = { /* top left corner */ 0, 0, priv->left, priv->top, 0.0, 0.0, tx1, ty1, /* top middle */ priv->left, 0, MAX (priv->left, ex), priv->top, tx1, 0.0, tx2, ty1, /* top right */ ex, 0, MAX (ex + priv->right, width), priv->top, tx2, 0.0, 1.0, ty1, /* mid left */ 0, priv->top, priv->left, ey, 0.0, ty1, tx1, ty2, /* center */ priv->left, priv->top, ex, ey, tx1, ty1, tx2, ty2, /* mid right */ ex, priv->top, MAX (ex + priv->right, width), ey, tx2, ty1, 1.0, ty2, /* bottom left */ 0, ey, priv->left, MAX (ey + priv->bottom, height), 0.0, ty2, tx1, 1.0, /* bottom center */ priv->left, ey, ex, MAX (ey + priv->bottom, height), tx1, ty2, tx2, 1.0, /* bottom right */ ex, ey, MAX (ex + priv->right, width), MAX (ey + priv->bottom, height), tx2, ty2, 1.0, 1.0 }; cogl_rectangles_with_texture_coords (rectangles, 9); } }
/* * Paints the provided texture frame trimming to the area indicated by padding. * * (Basically, we have one asset that gets split into two parts: an border area * that matches the padding, and the inside; MplPanelBackground paints the * latter, while the border is painted by the compositor as the window shadow.) */ static void mpl_panel_background_paint_border_image (CoglHandle *frame, MxPadding *padding) { CoglHandle cogl_texture = COGL_INVALID_HANDLE; CoglHandle cogl_material = COGL_INVALID_HANDLE; ClutterActorBox box = { 0, }; gfloat width, height; gfloat tex_width, tex_height; gfloat ex, ey; gfloat tx1, ty1, tx2, ty2; gfloat left = 4, right = 4 , top = 4, bottom =4; guint8 opacity; ClutterTexture *parent_texture; gfloat margin_l, margin_r, margin_t, margin_b; parent_texture = mx_texture_frame_get_parent_texture (frame); mx_texture_frame_get_border_values (frame, &top, &right, &bottom, &left); /* no need to paint stuff if we don't have a texture */ if (G_UNLIKELY (parent_texture == NULL)) return; /* parent texture may have been hidden, so need to make sure it gets * realized */ if (!CLUTTER_ACTOR_IS_REALIZED (parent_texture)) clutter_actor_realize (CLUTTER_ACTOR (parent_texture)); cogl_texture = clutter_texture_get_cogl_texture (parent_texture); if (cogl_texture == COGL_INVALID_HANDLE) return; cogl_material = clutter_texture_get_cogl_material (parent_texture); if (cogl_material == COGL_INVALID_HANDLE) return; tex_width = cogl_texture_get_width (cogl_texture); tex_height = cogl_texture_get_height (cogl_texture); clutter_actor_get_allocation_box ((ClutterActor*) frame, &box); width = box.x2 - box.x1; height = box.y2 - box.y1; /* * These are the margins we are to trim expressed in texture coordinates. */ margin_l = padding->left / tex_width; margin_r = padding->right / tex_width; margin_t = padding->top / tex_height; margin_b = padding->bottom / tex_height; tx1 = left / tex_width; tx2 = (tex_width - right) / tex_width; ty1 = top / tex_height; ty2 = (tex_height - bottom) / tex_height; ex = width - right; if (ex < 0) ex = right; ey = height - bottom; if (ey < 0) ey = bottom; opacity = clutter_actor_get_paint_opacity ((ClutterActor*)frame); cogl_material_set_color4ub (cogl_material, opacity, opacity, opacity, opacity); cogl_set_source (cogl_material); cogl_material_set_layer_filters (cogl_material, 0, COGL_MATERIAL_FILTER_NEAREST, COGL_MATERIAL_FILTER_NEAREST); { GLfloat rectangles[] = { /* top left corner */ 0.0, 0.0, left, top, margin_l, margin_t, tx1, ty1, /* top middle */ left, 0.0, ex, top, tx1, margin_t, tx2, ty1, /* top right */ ex, 0.0, width, top, tx2, margin_t, 1.0 - margin_r, ty1, /* mid left */ 0.0, top, left, ey, margin_l, ty1, tx1, ty2, /* center */ left, top, ex, ey, tx1, ty1, tx2, ty2, /* mid right */ ex, top, width, ey, tx2, ty1, 1.0 - margin_r, ty2, /* bottom left */ 0.0, ey, left, height, margin_l, ty2, tx1, 1.0 - margin_b, /* bottom center */ left, ey, ex, height, tx1, ty2, tx2, 1.0 - margin_b, /* bottom right */ ex, ey, width, height, tx2, ty2, 1.0 - margin_r, 1.0 - margin_b }; cogl_rectangles_with_texture_coords (rectangles, 9); } }
static void mnb_toolbar_shadow_paint (ClutterActor *self) { MnbToolbarShadowPrivate *priv = MNB_TOOLBAR_SHADOW (self)->priv; CoglHandle cogl_texture = COGL_INVALID_HANDLE; CoglHandle cogl_material = COGL_INVALID_HANDLE; ClutterActorBox box = { 0, }; gfloat width, height; gfloat tex_width, tex_height; gfloat ex, ey; gfloat tx1, ty1, tx2, ty2; guint8 opacity; /* no need to paint stuff if we don't have a texture */ if (G_UNLIKELY (priv->parent_texture == NULL)) return; /* parent texture may have been hidden, so need to make sure it gets * realized */ if (!CLUTTER_ACTOR_IS_REALIZED (priv->parent_texture)) clutter_actor_realize (CLUTTER_ACTOR (priv->parent_texture)); cogl_texture = clutter_texture_get_cogl_texture (priv->parent_texture); if (cogl_texture == COGL_INVALID_HANDLE) return; cogl_material = clutter_texture_get_cogl_material (priv->parent_texture); if (cogl_material == COGL_INVALID_HANDLE) return; tex_width = cogl_texture_get_width (cogl_texture); tex_height = cogl_texture_get_height (cogl_texture); clutter_actor_get_allocation_box (self, &box); width = box.x2 - box.x1; height = box.y2 - box.y1; opacity = clutter_actor_get_paint_opacity (self); /* Paint using the parent texture's material. It should already have the cogl texture set as the first layer */ /* NB: for correct blending we need set a preumultiplied color here: */ cogl_material_set_color4ub (cogl_material, opacity, opacity, opacity, opacity); #if TOOLBAR_CUT_OUT selector_texture = mnb_toolbar_get_selector_texture (priv->toolbar); cogl_material_set_layer (cogl_material, 1, selector_texture); cogl_material_set_layer_wrap_mode (cogl_material, 1, COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE); if (!cogl_material_set_layer_combine (cogl_material, 1, "RGBA = MODULATE(PREVIOUS,TEXTURE)", &error)) { g_warning (G_STRLOC ": Error setting layer combine blend string: %s", error->message); g_error_free (error); } #endif cogl_set_source (cogl_material); /* simple stretch */ if (priv->left == 0 && priv->right == 0 && priv->top == 0 && priv->bottom == 0) { #if TOOLBAR_CUT_OUT float spot_width, spot_height; float coords[8] = { 0, 0, 1, 1, 0, 0, 0, 0 }; mnb_toolbar_get_selector_allocation_box (priv->toolbar, &box); spot_width = box.x2 - box.x1; spot_height = box.y2 - box.y1; coords[4] = -(box.x1 / width) * (width / spot_width); coords[5] = -(box.y1 + SHADOW_CUT_OUT_OFFSET / height) * (height / spot_height); coords[6] = width / spot_width - (box.x1 / width) * (width / spot_width); coords[7] = height / spot_height - (box.y1 + SHADOW_CUT_OUT_OFFSET / height) * (height / spot_height); cogl_rectangle_with_multitexture_coords (0, 0, width, height, coords, 8); #else cogl_rectangle (0, 0, width, height); #endif /* TOOLBAR_CUT_OUT */ return; } tx1 = priv->left / tex_width; tx2 = (tex_width - priv->right) / tex_width; ty1 = priv->top / tex_height; ty2 = (tex_height - priv->bottom) / tex_height; ex = width - priv->right; if (ex < priv->left) ex = priv->left; ey = height - priv->bottom; if (ey < priv->top) ey = priv->top; { GLfloat rectangles[] = { /* top left corner */ 0, 0, priv->left, priv->top, 0.0, 0.0, tx1, ty1, /* top middle */ priv->left, 0, MAX (priv->left, ex), priv->top, tx1, 0.0, tx2, ty1, /* top right */ ex, 0, MAX (ex + priv->right, width), priv->top, tx2, 0.0, 1.0, ty1, /* mid left */ 0, priv->top, priv->left, ey, 0.0, ty1, tx1, ty2, /* center */ priv->left, priv->top, ex, ey, tx1, ty1, tx2, ty2, /* mid right */ ex, priv->top, MAX (ex + priv->right, width), ey, tx2, ty1, 1.0, ty2, /* bottom left */ 0, ey, priv->left, MAX (ey + priv->bottom, height), 0.0, ty2, tx1, 1.0, /* bottom center */ priv->left, ey, ex, MAX (ey + priv->bottom, height), tx1, ty2, tx2, 1.0, /* bottom right */ ex, ey, MAX (ex + priv->right, width), MAX (ey + priv->bottom, height), tx2, ty2, 1.0, 1.0 }; cogl_rectangles_with_texture_coords (rectangles, 9); } }
static void mx_texture_frame_paint_texture_internal (CoglHandle material, CoglHandle texture, guint8 opacity, gfloat top, gfloat right, gfloat bottom, gfloat left, gfloat width, gfloat height) { gfloat tex_width, tex_height; gfloat ex, ey; gfloat tx1, ty1, tx2, ty2; /* apply opacity */ cogl_material_set_color4ub (material, opacity, opacity, opacity, opacity); /* add the texture */ cogl_material_set_layer (material, 0, texture); /* set the source */ cogl_set_source (material); tex_width = cogl_texture_get_width (texture); tex_height = cogl_texture_get_height (texture); /* simple stretch */ if (left == 0 && right == 0 && top == 0 && bottom == 0) { cogl_rectangle (0, 0, width, height); return; } tx1 = left / tex_width; tx2 = (tex_width - right) / tex_width; ty1 = top / tex_height; ty2 = (tex_height - bottom) / tex_height; ex = width - right; if (ex < left) ex = left; ey = height - bottom; if (ey < top) ey = top; { float rectangles[] = { /* top left corner */ 0, 0, left, top, 0.0, 0.0, tx1, ty1, /* top middle */ left, 0, MAX (left, ex), top, tx1, 0.0, tx2, ty1, /* top right */ ex, 0, MAX (ex + right, width), top, tx2, 0.0, 1.0, ty1, /* mid left */ 0, top, left, ey, 0.0, ty1, tx1, ty2, /* center */ left, top, ex, ey, tx1, ty1, tx2, ty2, /* mid right */ ex, top, MAX (ex + right, width), ey, tx2, ty1, 1.0, ty2, /* bottom left */ 0, ey, left, MAX (ey + bottom, height), 0.0, ty2, tx1, 1.0, /* bottom center */ left, ey, ex, MAX (ey + bottom, height), tx1, ty2, tx2, 1.0, /* bottom right */ ex, ey, MAX (ex + right, width), MAX (ey + bottom, height), tx2, ty2, 1.0, 1.0 }; cogl_rectangles_with_texture_coords (rectangles, 9); } }