1 /*
2  * Clutter.
3  *
4  * An OpenGL based 'interactive canvas' library.
5  *
6  * Copyright (C) 2009  Intel Corporation.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
20  *
21  * Author:
22  *   Emmanuele Bassi <ebassi@linux.intel.com>
23  *
24  * Based on the fixed layout code inside clutter-group.c
25  */
26 
27 /**
28  * SECTION:clutter-fixed-layout
29  * @short_description: A fixed layout manager
30  *
31  * #ClutterFixedLayout is a layout manager implementing the same
32  * layout policies as #ClutterGroup.
33  *
34  * #ClutterFixedLayout is available since Clutter 1.2
35  */
36 
37 #include "clutter-build-config.h"
38 
39 #include "clutter-debug.h"
40 #include "clutter-fixed-layout.h"
41 #include "clutter-private.h"
42 
43 G_DEFINE_TYPE (ClutterFixedLayout,
44                clutter_fixed_layout,
45                CLUTTER_TYPE_LAYOUT_MANAGER);
46 
47 static void
clutter_fixed_layout_get_preferred_width(ClutterLayoutManager * manager,ClutterContainer * container,gfloat for_height,gfloat * min_width_p,gfloat * nat_width_p)48 clutter_fixed_layout_get_preferred_width (ClutterLayoutManager *manager,
49                                           ClutterContainer     *container,
50                                           gfloat                for_height,
51                                           gfloat               *min_width_p,
52                                           gfloat               *nat_width_p)
53 {
54   ClutterActor *actor, *child;
55   gdouble min_right;
56   gdouble natural_right;
57 
58   min_right = 0;
59   natural_right = 0;
60 
61   actor = CLUTTER_ACTOR (container);
62 
63   for (child = clutter_actor_get_first_child (actor);
64        child != NULL;
65        child = clutter_actor_get_next_sibling (child))
66     {
67       gfloat child_x, child_min, child_natural;
68 
69       child_x = clutter_actor_get_x (child);
70 
71       clutter_actor_get_preferred_size (child,
72                                         &child_min, NULL,
73                                         &child_natural, NULL);
74 
75       if (child_x + child_min > min_right)
76         min_right = child_x + child_min;
77 
78       if (child_x + child_natural > natural_right)
79         natural_right = child_x + child_natural;
80     }
81 
82   if (min_width_p)
83     *min_width_p = min_right;
84 
85   if (nat_width_p)
86     *nat_width_p = natural_right;
87 }
88 
89 static void
clutter_fixed_layout_get_preferred_height(ClutterLayoutManager * manager,ClutterContainer * container,gfloat for_width,gfloat * min_height_p,gfloat * nat_height_p)90 clutter_fixed_layout_get_preferred_height (ClutterLayoutManager *manager,
91                                            ClutterContainer     *container,
92                                            gfloat                for_width,
93                                            gfloat               *min_height_p,
94                                            gfloat               *nat_height_p)
95 {
96   ClutterActor *actor, *child;
97   gdouble min_bottom;
98   gdouble natural_bottom;
99 
100   min_bottom = 0;
101   natural_bottom = 0;
102 
103   actor = CLUTTER_ACTOR (container);
104 
105   for (child = clutter_actor_get_first_child (actor);
106        child != NULL;
107        child = clutter_actor_get_next_sibling (child))
108     {
109       gfloat child_y, child_min, child_natural;
110 
111       child_y = clutter_actor_get_y (child);
112 
113       clutter_actor_get_preferred_size (child,
114                                         NULL, &child_min,
115                                         NULL, &child_natural);
116 
117       if (child_y + child_min > min_bottom)
118         min_bottom = child_y + child_min;
119 
120       if (child_y + child_natural > natural_bottom)
121         natural_bottom = child_y + child_natural;
122     }
123 
124   if (min_height_p)
125     *min_height_p = min_bottom;
126 
127   if (nat_height_p)
128     *nat_height_p = natural_bottom;
129 }
130 
131 static void
clutter_fixed_layout_allocate(ClutterLayoutManager * manager,ClutterContainer * container,const ClutterActorBox * allocation)132 clutter_fixed_layout_allocate (ClutterLayoutManager   *manager,
133                                ClutterContainer       *container,
134                                const ClutterActorBox  *allocation)
135 {
136   ClutterActor *child;
137 
138   for (child = clutter_actor_get_first_child (CLUTTER_ACTOR (container));
139        child != NULL;
140        child = clutter_actor_get_next_sibling (child))
141     {
142       float x = 0.f;
143       float y = 0.f;
144 
145       clutter_actor_get_fixed_position (child, &x, &y);
146       clutter_actor_allocate_preferred_size (child, x, y);
147     }
148 }
149 
150 static void
clutter_fixed_layout_class_init(ClutterFixedLayoutClass * klass)151 clutter_fixed_layout_class_init (ClutterFixedLayoutClass *klass)
152 {
153   ClutterLayoutManagerClass *manager_class =
154     CLUTTER_LAYOUT_MANAGER_CLASS (klass);
155 
156   manager_class->get_preferred_width =
157     clutter_fixed_layout_get_preferred_width;
158   manager_class->get_preferred_height =
159     clutter_fixed_layout_get_preferred_height;
160   manager_class->allocate = clutter_fixed_layout_allocate;
161 }
162 
163 static void
clutter_fixed_layout_init(ClutterFixedLayout * self)164 clutter_fixed_layout_init (ClutterFixedLayout *self)
165 {
166 }
167 
168 /**
169  * clutter_fixed_layout_new:
170  *
171  * Creates a new #ClutterFixedLayout
172  *
173  * Return value: the newly created #ClutterFixedLayout
174  *
175  * Since: 1.2
176  */
177 ClutterLayoutManager *
clutter_fixed_layout_new(void)178 clutter_fixed_layout_new (void)
179 {
180   return g_object_new (CLUTTER_TYPE_FIXED_LAYOUT, NULL);
181 }
182