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);
  }
}
Exemple #4
0
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);
  }
}