gnome-shell-3.6.3.1/src/shell-stack.c

No issues found

  1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
  2 
  3 /**
  4  * SECTION:shell-stack
  5  * @short_description: Pure "Z-axis" container class
  6  *
  7  * A #ShellStack draws its children on top of each other,
  8  * aligned to the top left.  It will be sized in width/height
  9  * according to the largest such dimension of its children, and
 10  * all children will be allocated that size.  This differs
 11  * from #ClutterGroup which allocates its children their natural
 12  * size, even if that would overflow the size allocated to the stack.
 13  */
 14 
 15 #include "config.h"
 16 
 17 #include "shell-stack.h"
 18 
 19 G_DEFINE_TYPE (ShellStack,
 20                shell_stack,
 21                ST_TYPE_WIDGET);
 22 
 23 static void
 24 shell_stack_allocate (ClutterActor           *self,
 25                       const ClutterActorBox  *box,
 26                       ClutterAllocationFlags  flags)
 27 {
 28   StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (self));
 29   ClutterActorBox content_box;
 30   ClutterActor *child;
 31 
 32   clutter_actor_set_allocation (self, box, flags);
 33 
 34   st_theme_node_get_content_box (theme_node, box, &content_box);
 35 
 36   for (child = clutter_actor_get_first_child (self);
 37        child != NULL;
 38        child = clutter_actor_get_next_sibling (child))
 39     {
 40       ClutterActorBox child_box = content_box;
 41       clutter_actor_allocate (child, &child_box, flags);
 42     }
 43 }
 44 
 45 static void
 46 shell_stack_get_preferred_height (ClutterActor *actor,
 47                                   gfloat for_width,
 48                                   gfloat *min_height_p,
 49                                   gfloat *natural_height_p)
 50 {
 51   StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
 52   gboolean first = TRUE;
 53   float min = 0, natural = 0;
 54   ClutterActor *child;
 55 
 56   st_theme_node_adjust_for_width (theme_node, &for_width);
 57 
 58   for (child = clutter_actor_get_first_child (actor);
 59        child != NULL;
 60        child = clutter_actor_get_next_sibling (child))
 61     {
 62       float child_min, child_natural;
 63 
 64       clutter_actor_get_preferred_height (child,
 65                                           for_width,
 66                                           &child_min,
 67                                           &child_natural);
 68 
 69       if (first)
 70         {
 71           first = FALSE;
 72           min = child_min;
 73           natural = child_natural;
 74         }
 75       else
 76         {
 77           if (child_min > min)
 78             min = child_min;
 79 
 80           if (child_natural > natural)
 81             natural = child_natural;
 82         }
 83     }
 84 
 85   if (min_height_p)
 86     *min_height_p = min;
 87 
 88   if (natural_height_p)
 89     *natural_height_p = natural;
 90 
 91   st_theme_node_adjust_preferred_height (theme_node, min_height_p, natural_height_p);
 92 }
 93 
 94 static void
 95 shell_stack_get_preferred_width (ClutterActor *actor,
 96                                  gfloat for_height,
 97                                  gfloat *min_width_p,
 98                                  gfloat *natural_width_p)
 99 {
100   StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
101   gboolean first = TRUE;
102   float min = 0, natural = 0;
103   ClutterActor *child;
104 
105   st_theme_node_adjust_for_height (theme_node, &for_height);
106 
107   for (child = clutter_actor_get_first_child (actor);
108        child != NULL;
109        child = clutter_actor_get_next_sibling (child))
110     {
111       float child_min, child_natural;
112 
113       clutter_actor_get_preferred_width (child,
114                                          for_height,
115                                          &child_min,
116                                          &child_natural);
117 
118       if (first)
119         {
120           first = FALSE;
121           min = child_min;
122           natural = child_natural;
123         }
124       else
125         {
126           if (child_min > min)
127             min = child_min;
128 
129           if (child_natural > natural)
130             natural = child_natural;
131         }
132     }
133 
134   if (min_width_p)
135     *min_width_p = min;
136 
137   if (natural_width_p)
138     *natural_width_p = natural;
139 
140   st_theme_node_adjust_preferred_width (theme_node, min_width_p, natural_width_p);
141 }
142 
143 static gboolean
144 shell_stack_navigate_focus (StWidget         *widget,
145                             ClutterActor     *from,
146                             GtkDirectionType  direction)
147 {
148   ClutterActor *top_actor;
149 
150   /* If the stack is itself focusable, then focus into or out of
151    * it, as appropriate.
152    */
153   if (st_widget_get_can_focus (widget))
154     {
155       if (from && clutter_actor_contains (CLUTTER_ACTOR (widget), from))
156         return FALSE;
157 
158       if (CLUTTER_ACTOR_IS_MAPPED (CLUTTER_ACTOR (widget)))
159         {
160           clutter_actor_grab_key_focus (CLUTTER_ACTOR (widget));
161           return TRUE;
162         }
163       else
164         {
165           return FALSE;
166         }
167     }
168 
169   top_actor = clutter_actor_get_last_child (CLUTTER_ACTOR (widget));
170   if (ST_IS_WIDGET (top_actor))
171     return st_widget_navigate_focus (ST_WIDGET (top_actor), from, direction, FALSE);
172   else
173     return FALSE;
174 }
175 
176 static void
177 shell_stack_class_init (ShellStackClass *klass)
178 {
179   ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
180   StWidgetClass *widget_class = ST_WIDGET_CLASS (klass);
181 
182   actor_class->get_preferred_width = shell_stack_get_preferred_width;
183   actor_class->get_preferred_height = shell_stack_get_preferred_height;
184   actor_class->allocate = shell_stack_allocate;
185 
186   widget_class->navigate_focus = shell_stack_navigate_focus;
187 }
188 
189 static void
190 shell_stack_init (ShellStack *actor)
191 {
192 }