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