Skip to content
This repository
Fetching contributors…

Cannot retrieve contributors at this time

file 165 lines (131 sloc) 4.722 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */

/**
* SECTION:cinnamon-slicer
* @short_description: Display only part of another actor
*
* A #StBin that has 0 minimum size, and will clip its child
* in the middle.
*/

#include "config.h"

#include "cinnamon-slicer.h"

G_DEFINE_TYPE (CinnamonSlicer,
               cinnamon_slicer,
               ST_TYPE_BIN);

static void
cinnamon_slicer_get_preferred_width (ClutterActor *self,
                                  gfloat for_height,
                                  gfloat *min_width_p,
                                  gfloat *natural_width_p)
{
  ClutterActor *child = st_bin_get_child (ST_BIN (self));
  StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (self));

  st_theme_node_adjust_for_height (theme_node, &for_height);

  if (min_width_p)
    *min_width_p = 0;

  if (child == NULL)
    {
      if (natural_width_p)
        *natural_width_p = 0;
    }
  else
    {
      _st_actor_get_preferred_width (child, for_height, FALSE,
                                     NULL,
                                     natural_width_p);
    }

  st_theme_node_adjust_preferred_width (theme_node, min_width_p, natural_width_p);
}

static void
cinnamon_slicer_get_preferred_height (ClutterActor *self,
                                   gfloat for_width,
                                   gfloat *min_height_p,
                                   gfloat *natural_height_p)
{
  ClutterActor *child = st_bin_get_child (ST_BIN (self));
  StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (self));

  st_theme_node_adjust_for_width (theme_node, &for_width);

  if (min_height_p)
    *min_height_p = 0;

  if (child == NULL)
    {
      if (natural_height_p)
        *natural_height_p = 0;
    }
  else
    {
      _st_actor_get_preferred_height (child, for_width, FALSE,
                                      NULL,
                                      natural_height_p);
    }

  st_theme_node_adjust_preferred_height (theme_node, min_height_p, natural_height_p);
}

static void
cinnamon_slicer_allocate (ClutterActor *self,
                       const ClutterActorBox *box,
                       ClutterAllocationFlags flags)
{
  ClutterActor *child;

  /* Chain up directly to ClutterActor to set actor->allocation. We explicitly skip our parent class
* StBin here because we want to override the allocate function. */
  CLUTTER_ACTOR_CLASS (g_type_class_peek (clutter_actor_get_type ()))->allocate (self, box, flags);

  child = st_bin_get_child (ST_BIN (self));
  if (child)
    clutter_actor_allocate_preferred_size (child, flags);
}

static void
cinnamon_slicer_paint_child (CinnamonSlicer *self)
{
  ClutterActor *child;
  ClutterActorBox self_box;
  ClutterActorBox child_box;
  float width, height, child_width, child_height;
  StAlign x_align, y_align;
  double x_align_factor, y_align_factor;

  child = st_bin_get_child (ST_BIN (self));

  if (!child)
    return;

  st_bin_get_alignment (ST_BIN (self), &x_align, &y_align);
  _st_get_align_factors (ST_WIDGET (self), x_align, y_align,
                         &x_align_factor, &y_align_factor);

  clutter_actor_get_allocation_box (CLUTTER_ACTOR (self), &self_box);
  clutter_actor_get_allocation_box (child, &child_box);

  width = self_box.x2 - self_box.x1;
  height = self_box.y2 - self_box.y1;
  child_width = child_box.x2 - child_box.x1;
  child_height = child_box.y2 - child_box.y1;

  cogl_push_matrix ();

  cogl_clip_push_rectangle (0, 0, width, height);
  cogl_translate ((int)(0.5 + x_align_factor * (width - child_width)),
                  (int)(0.5 + y_align_factor * (height - child_height)),
                  0);

  clutter_actor_paint (child);

  cogl_clip_pop ();

  cogl_pop_matrix ();
}

static void
cinnamon_slicer_paint (ClutterActor *self)
{
  /* StWidget paints CSS elements */
  CLUTTER_ACTOR_CLASS (g_type_class_peek (st_widget_get_type ()))->paint (self);

  cinnamon_slicer_paint_child (CINNAMON_SLICER (self));
}

static void
cinnamon_slicer_pick (ClutterActor *self,
                   const ClutterColor *pick_color)
{
  cinnamon_slicer_paint_child (CINNAMON_SLICER (self));
}

static void
cinnamon_slicer_class_init (CinnamonSlicerClass *klass)
{
  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);

  actor_class->get_preferred_width = cinnamon_slicer_get_preferred_width;
  actor_class->get_preferred_height = cinnamon_slicer_get_preferred_height;
  actor_class->allocate = cinnamon_slicer_allocate;
  actor_class->paint = cinnamon_slicer_paint;
  actor_class->pick = cinnamon_slicer_pick;
}

static void
cinnamon_slicer_init (CinnamonSlicer *actor)
{
}
Something went wrong with that request. Please try again.