Release Clutter 1.11.4 (snapshot)
[profile/ivi/clutter.git] / clutter / clutter-fixed-layout.c
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 #ifdef HAVE_CONFIG_H
38 #include "config.h"
39 #endif
40
41 #include "clutter-debug.h"
42 #include "clutter-fixed-layout.h"
43 #include "clutter-private.h"
44
45 G_DEFINE_TYPE (ClutterFixedLayout,
46                clutter_fixed_layout,
47                CLUTTER_TYPE_LAYOUT_MANAGER);
48
49 static void
50 clutter_fixed_layout_get_preferred_width (ClutterLayoutManager *manager,
51                                           ClutterContainer     *container,
52                                           gfloat                for_height,
53                                           gfloat               *min_width_p,
54                                           gfloat               *nat_width_p)
55 {
56   ClutterActor *actor, *child;
57   gdouble min_right;
58   gdouble natural_right;
59
60   min_right = 0;
61   natural_right = 0;
62
63   actor = CLUTTER_ACTOR (container);
64
65   for (child = clutter_actor_get_first_child (actor);
66        child != NULL;
67        child = clutter_actor_get_next_sibling (child))
68     {
69       gfloat child_x, child_min, child_natural;
70
71       child_x = clutter_actor_get_x (child);
72
73       clutter_actor_get_preferred_size (child,
74                                         &child_min, NULL,
75                                         &child_natural, NULL);
76
77       if (child_x + child_min > min_right)
78         min_right = child_x + child_min;
79
80       if (child_x + child_natural > natural_right)
81         natural_right = child_x + child_natural;
82     }
83
84   if (min_width_p)
85     *min_width_p = min_right;
86
87   if (nat_width_p)
88     *nat_width_p = natural_right;
89 }
90
91 static void
92 clutter_fixed_layout_get_preferred_height (ClutterLayoutManager *manager,
93                                            ClutterContainer     *container,
94                                            gfloat                for_width,
95                                            gfloat               *min_height_p,
96                                            gfloat               *nat_height_p)
97 {
98   ClutterActor *actor, *child;
99   gdouble min_bottom;
100   gdouble natural_bottom;
101
102   min_bottom = 0;
103   natural_bottom = 0;
104
105   actor = CLUTTER_ACTOR (container);
106
107   for (child = clutter_actor_get_first_child (actor);
108        child != NULL;
109        child = clutter_actor_get_next_sibling (child))
110     {
111       gfloat child_y, child_min, child_natural;
112
113       child_y = clutter_actor_get_y (child);
114
115       clutter_actor_get_preferred_size (child,
116                                         NULL, &child_min,
117                                         NULL, &child_natural);
118
119       if (child_y + child_min > min_bottom)
120         min_bottom = child_y + child_min;
121
122       if (child_y + child_natural > natural_bottom)
123         natural_bottom = child_y + child_natural;
124     }
125
126   if (min_height_p)
127     *min_height_p = min_bottom;
128
129   if (nat_height_p)
130     *nat_height_p = natural_bottom;
131 }
132
133 static void
134 clutter_fixed_layout_allocate (ClutterLayoutManager   *manager,
135                                ClutterContainer       *container,
136                                const ClutterActorBox  *allocation,
137                                ClutterAllocationFlags  flags)
138 {
139   ClutterActor *child;
140
141   for (child = clutter_actor_get_first_child (CLUTTER_ACTOR (container));
142        child != NULL;
143        child = clutter_actor_get_next_sibling (child))
144     {
145       clutter_actor_allocate_preferred_size (child, flags);
146     }
147 }
148
149 static void
150 clutter_fixed_layout_class_init (ClutterFixedLayoutClass *klass)
151 {
152   ClutterLayoutManagerClass *manager_class =
153     CLUTTER_LAYOUT_MANAGER_CLASS (klass);
154
155   manager_class->get_preferred_width =
156     clutter_fixed_layout_get_preferred_width;
157   manager_class->get_preferred_height =
158     clutter_fixed_layout_get_preferred_height;
159   manager_class->allocate = clutter_fixed_layout_allocate;
160 }
161
162 static void
163 clutter_fixed_layout_init (ClutterFixedLayout *self)
164 {
165 }
166
167 /**
168  * clutter_fixed_layout_new:
169  *
170  * Creates a new #ClutterFixedLayout
171  *
172  * Return value: the newly created #ClutterFixedLayout
173  *
174  * Since: 1.2
175  */
176 ClutterLayoutManager *
177 clutter_fixed_layout_new (void)
178 {
179   return g_object_new (CLUTTER_TYPE_FIXED_LAYOUT, NULL);
180 }