aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/edje/src/lib/edje_box_layout.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/edje/src/lib/edje_box_layout.c')
-rw-r--r--libraries/edje/src/lib/edje_box_layout.c242
1 files changed, 242 insertions, 0 deletions
diff --git a/libraries/edje/src/lib/edje_box_layout.c b/libraries/edje/src/lib/edje_box_layout.c
new file mode 100644
index 0000000..3585046
--- /dev/null
+++ b/libraries/edje/src/lib/edje_box_layout.c
@@ -0,0 +1,242 @@
1#include "edje_private.h"
2
3typedef struct _Edje_Transition_Animation_Data Edje_Transition_Animation_Data;
4struct _Edje_Transition_Animation_Data
5{
6 Evas_Object *obj;
7 struct
8 {
9 Evas_Coord x, y, w, h;
10 } start, end;
11};
12
13struct _Edje_Part_Box_Animation
14{
15 struct
16 {
17 Evas_Object_Box_Layout layout;
18 void *data;
19 void(*free_data)(void *data);
20 Edje_Alignment align;
21 Evas_Point padding;
22 } start, end;
23 Eina_List *objs;
24 Eina_Bool recalculate:1;
25 Evas_Object *box;
26 double progress;
27 double start_progress;
28 int box_start_w, box_start_h;
29};
30
31static void
32_edje_box_layout_find_all(const char *name, const char *name_alt, Evas_Object_Box_Layout *cb, void **data, void (**free_data)(void *data))
33{
34 if (!_edje_box_layout_find(name, cb, data, free_data))
35 {
36 if ((!name_alt) ||
37 (!_edje_box_layout_find(name_alt, cb, data, free_data)))
38 {
39 ERR("box layout '%s' (fallback '%s') not available, using horizontal.",
40 name, name_alt);
41 *cb = evas_object_box_layout_horizontal;
42 *free_data = NULL;
43 *data = NULL;
44 }
45 }
46}
47
48static void
49_edje_box_layout_calculate_coords(Evas_Object *obj, Evas_Object_Box_Data *priv, Edje_Part_Box_Animation *anim)
50{
51 Eina_List *l;
52 Edje_Transition_Animation_Data *tad;
53 Evas_Coord x, y;
54
55 evas_object_geometry_get(obj, &x, &y, &anim->box_start_w, &anim->box_start_h);
56 EINA_LIST_FOREACH(anim->objs, l, tad)
57 {
58 evas_object_geometry_get(tad->obj, &tad->start.x, &tad->start.y,
59 &tad->start.w, &tad->start.h);
60 tad->start.x = tad->start.x - x;
61 tad->start.y = tad->start.y - y;
62 }
63 evas_object_box_padding_set(obj, anim->end.padding.x, anim->end.padding.y);
64 evas_object_box_align_set(obj, TO_DOUBLE(anim->end.align.x), TO_DOUBLE(anim->end.align.y));
65 anim->end.layout(obj, priv, anim->end.data);
66 EINA_LIST_FOREACH(anim->objs, l, tad)
67 {
68 evas_object_geometry_get(tad->obj, &tad->end.x, &tad->end.y,
69 &tad->end.w, &tad->end.h);
70 tad->end.x = tad->end.x - x;
71 tad->end.y = tad->end.y - y;
72 }
73}
74
75static void
76_edje_box_layout_exec(Evas_Object *obj, Edje_Part_Box_Animation *anim)
77{
78 Eina_List *l;
79 Edje_Transition_Animation_Data *tad;
80 Evas_Coord x, y, w, h;
81 Evas_Coord cur_x, cur_y, cur_w, cur_h;
82 double progress;
83
84 evas_object_geometry_get(obj, &x, &y, &w, &h);
85 progress = (anim->progress - anim->start_progress) / (1 - anim->start_progress);
86
87 EINA_LIST_FOREACH(anim->objs, l, tad)
88 {
89 cur_x = x + (tad->start.x + ((tad->end.x - tad->start.x) * progress)) * (w / (double)anim->box_start_w);
90 cur_y = y + (tad->start.y + ((tad->end.y - tad->start.y) * progress)) * (h / (double)anim->box_start_h);
91 cur_w = (w / (double)anim->box_start_w) * (tad->start.w + ((tad->end.w - tad->start.w) * progress));
92 cur_h = (h / (double)anim->box_start_h) * (tad->start.h + ((tad->end.h - tad->start.h) * progress));
93 evas_object_move(tad->obj, cur_x, cur_y);
94 evas_object_resize(tad->obj, cur_w, cur_h);
95 }
96}
97
98static void
99_edje_box_layout(Evas_Object *obj, Evas_Object_Box_Data *priv, void *data)
100{
101 Edje_Part_Box_Animation *anim = data;
102 if (anim->progress < 0.01)
103 {
104 if (anim->start.layout)
105 {
106 evas_object_box_padding_set(obj, anim->start.padding.x, anim->start.padding.y);
107 evas_object_box_align_set(obj, TO_DOUBLE(anim->start.align.x), TO_DOUBLE(anim->start.align.y));
108 anim->start.layout(obj, priv, anim->start.data);
109 }
110 return;
111 }
112
113 if (anim->recalculate)
114 {
115 _edje_box_layout_calculate_coords(obj, priv, anim);
116 anim->start_progress = anim->progress;
117 anim->recalculate = EINA_FALSE;
118 }
119
120 if ((anim->progress > 0) && (anim->start_progress < 1))
121 _edje_box_layout_exec(obj, anim);
122}
123
124void
125_edje_box_layout_free_data(void *data)
126{
127 Edje_Transition_Animation_Data *tad;
128 Edje_Part_Box_Animation *anim = data;
129 if (anim->start.free_data && anim->start.data)
130 anim->start.free_data(anim->start.data);
131 if (anim->end.free_data && anim->end.data)
132 anim->end.free_data(anim->end.data);
133 EINA_LIST_FREE(anim->objs, tad)
134 free(tad);
135 free(data);
136}
137
138Edje_Part_Box_Animation *
139_edje_box_layout_anim_new(Evas_Object *box)
140{
141 Edje_Part_Box_Animation *anim = calloc(1, sizeof(Edje_Part_Box_Animation));
142 if (!anim)
143 return NULL;
144
145 anim->box = box;
146 evas_object_box_layout_set(box, _edje_box_layout, anim, NULL);
147
148 return anim;
149}
150
151void
152_edje_box_recalc_apply(Edje *ed __UNUSED__, Edje_Real_Part *ep, Edje_Calc_Params *p3 __UNUSED__, Edje_Part_Description_Box *chosen_desc)
153{
154 Evas_Object_Box_Data *priv;
155#if 0
156 int min_w, min_h;
157#endif
158 if ((ep->param2) && (ep->description_pos != ZERO))
159 {
160 Edje_Part_Description_Box *param2_desc = (Edje_Part_Description_Box *)ep->param2->description;
161 if (ep->anim->end.layout == NULL)
162 {
163 _edje_box_layout_find_all(param2_desc->box.layout, param2_desc->box.alt_layout, &ep->anim->end.layout, &ep->anim->end.data, &ep->anim->end.free_data);
164 ep->anim->end.padding.x = param2_desc->box.padding.x;
165 ep->anim->end.padding.y = param2_desc->box.padding.y;
166 ep->anim->end.align.x = param2_desc->box.align.x;
167 ep->anim->end.align.y = param2_desc->box.align.y;
168
169 priv = evas_object_smart_data_get(ep->object);
170 if (priv == NULL)
171 return;
172
173 evas_object_box_padding_set(ep->object, ep->anim->start.padding.x, ep->anim->start.padding.y);
174 evas_object_box_align_set(ep->object, TO_DOUBLE(ep->anim->start.align.x), TO_DOUBLE(ep->anim->start.align.y));
175 ep->anim->start.layout(ep->object, priv, ep->anim->start.data);
176 _edje_box_layout_calculate_coords(ep->object, priv, ep->anim);
177 ep->anim->start_progress = 0.0;
178 }
179 evas_object_smart_changed(ep->object);
180 }
181 else
182 {
183 ep->anim->end.layout = NULL;
184 }
185
186 if (ep->description_pos < 0.01 || !ep->anim->start.layout)
187 {
188 _edje_box_layout_find_all(chosen_desc->box.layout, chosen_desc->box.alt_layout, &ep->anim->start.layout, &ep->anim->start.data, &ep->anim->start.free_data);
189 ep->anim->start.padding.x = chosen_desc->box.padding.x;
190 ep->anim->start.padding.y = chosen_desc->box.padding.y;
191 ep->anim->start.align.x = chosen_desc->box.align.x;
192 ep->anim->start.align.y = chosen_desc->box.align.y;
193 evas_object_smart_changed(ep->object);
194 }
195
196 ep->anim->progress = ep->description_pos;
197
198 if (evas_object_smart_need_recalculate_get(ep->object))
199 {
200 evas_object_smart_need_recalculate_set(ep->object, 0);
201 evas_object_smart_calculate(ep->object);
202 }
203#if 0 /* Why the hell do we affect part size after resize ??? */
204 evas_object_size_hint_min_get(ep->object, &min_w, &min_h);
205 if (chosen_desc->box.min.h && (p3->w < min_w))
206 p3->w = min_w;
207 if (chosen_desc->box.min.v && (p3->h < min_h))
208 p3->h = min_h;
209#endif
210}
211
212Eina_Bool
213_edje_box_layout_add_child(Edje_Real_Part *rp, Evas_Object *child_obj)
214{
215 Edje_Transition_Animation_Data *tad;
216 tad = calloc(1, sizeof(Edje_Transition_Animation_Data));
217 if (!tad)
218 return EINA_FALSE;
219 tad->obj = child_obj;
220 rp->anim->objs = eina_list_append(rp->anim->objs, tad);
221 rp->anim->recalculate = EINA_TRUE;
222 return EINA_TRUE;
223}
224
225void
226_edje_box_layout_remove_child(Edje_Real_Part *rp, Evas_Object *child_obj)
227{
228 Eina_List *l;
229 Edje_Transition_Animation_Data *tad;
230
231 EINA_LIST_FOREACH(rp->anim->objs, l, tad)
232 {
233 if (tad->obj == child_obj)
234 {
235 free(eina_list_data_get(l));
236 rp->anim->objs = eina_list_remove_list(rp->anim->objs, l);
237 rp->anim->recalculate = EINA_TRUE;
238 break;
239 }
240 }
241 rp->anim->recalculate = EINA_TRUE;
242}