efl

Форк
0
/
edje_box_layout.c 
258 строк · 9.1 Кб
1
#include "edje_private.h"
2

3
#include "../evas/canvas/evas_box_eo.h"
4

5
#include <Eo.h>
6

7
typedef struct _Edje_Transition_Animation_Data Edje_Transition_Animation_Data;
8
struct _Edje_Transition_Animation_Data
9
{
10
   Evas_Object *obj;
11
   struct
12
   {
13
      Evas_Coord x, y, w, h;
14
   } start, end;
15
};
16

17
struct _Edje_Part_Box_Animation
18
{
19
   struct
20
   {
21
      Evas_Object_Box_Layout layout;
22
      void                  *data;
23
      void                   (*free_data)(void *data);
24
      Edje_Alignment         align;
25
      Evas_Point             padding;
26
   } start, end;
27
   Eina_List   *objs;
28
   Eina_Bool    recalculate : 1;
29
   Evas_Object *box;
30
   double       progress;
31
   double       start_progress;
32
   int          box_start_w, box_start_h;
33
};
34

35
static void
36
_edje_box_layout_find_all(const char *name, const char *name_alt, Evas_Object_Box_Layout *cb, void **data, void(**free_data) (void *data))
37
{
38
   if (!_edje_box_layout_find(name, cb, data, free_data))
39
     {
40
        if ((!name_alt) ||
41
            (!_edje_box_layout_find(name_alt, cb, data, free_data)))
42
          {
43
             ERR("box layout '%s' (fallback '%s') not available, using horizontal.",
44
                 name, name_alt);
45
             *cb = evas_object_box_layout_horizontal;
46
             *free_data = NULL;
47
             *data = NULL;
48
          }
49
     }
50
}
51

52
static void
53
_edje_box_layout_calculate_coords(Evas_Object *obj, Evas_Object_Box_Data *priv, Edje_Part_Box_Animation *anim)
54
{
55
   Eina_List *l;
56
   Edje_Transition_Animation_Data *tad;
57
   Evas_Coord x, y;
58

59
   evas_object_geometry_get(obj, &x, &y, &anim->box_start_w, &anim->box_start_h);
60
   EINA_LIST_FOREACH(anim->objs, l, tad)
61
     {
62
        evas_object_geometry_get(tad->obj, &tad->start.x, &tad->start.y,
63
                                 &tad->start.w, &tad->start.h);
64
        tad->start.x = tad->start.x - x;
65
        tad->start.y = tad->start.y - y;
66
     }
67
   evas_object_box_padding_set(obj, anim->end.padding.x, anim->end.padding.y);
68
   evas_object_box_align_set(obj, TO_DOUBLE(anim->end.align.x), TO_DOUBLE(anim->end.align.y));
69
   if (anim->end.layout)
70
     anim->end.layout(obj, priv, anim->end.data);
71
   else if (anim->start.layout)
72
     anim->start.layout(obj, priv, anim->start.data);
73

74
   EINA_LIST_FOREACH(anim->objs, l, tad)
75
     {
76
        evas_object_geometry_get(tad->obj, &tad->end.x, &tad->end.y,
77
                                 &tad->end.w, &tad->end.h);
78
        tad->end.x = tad->end.x - x;
79
        tad->end.y = tad->end.y - y;
80
     }
81
}
82

83
static void
84
_edje_box_layout_exec(Evas_Object *obj, Edje_Part_Box_Animation *anim)
85
{
86
   Eina_List *l;
87
   Edje_Transition_Animation_Data *tad;
88
   Evas_Coord x, y, w, h;
89
   Evas_Coord cur_x, cur_y, cur_w, cur_h;
90
   double progress;
91

92
   evas_object_geometry_get(obj, &x, &y, &w, &h);
93
   progress = (anim->progress - anim->start_progress) / (1 - anim->start_progress);
94

95
   EINA_LIST_FOREACH(anim->objs, l, tad)
96
     {
97
        cur_x = x + (tad->start.x + ((tad->end.x - tad->start.x) * progress)) * (w / (double)anim->box_start_w);
98
        cur_y = y + (tad->start.y + ((tad->end.y - tad->start.y) * progress)) * (h / (double)anim->box_start_h);
99
        cur_w = (w / (double)anim->box_start_w) * (tad->start.w + ((tad->end.w - tad->start.w) * progress));
100
        cur_h = (h / (double)anim->box_start_h) * (tad->start.h + ((tad->end.h - tad->start.h) * progress));
101
        evas_object_move(tad->obj, cur_x, cur_y);
102
        evas_object_resize(tad->obj, cur_w, cur_h);
103
     }
104
}
105

106
static void
107
_edje_box_layout(Evas_Object *obj, Evas_Object_Box_Data *priv, void *data)
108
{
109
   Edje_Part_Box_Animation *anim = data;
110

111
   if (EINA_DBL_EQ(anim->progress, 0.0))
112
     {
113
        if (anim->start.layout)
114
          {
115
             evas_object_box_padding_set(obj, anim->start.padding.x, anim->start.padding.y);
116
             evas_object_box_align_set(obj, TO_DOUBLE(anim->start.align.x), TO_DOUBLE(anim->start.align.y));
117
             anim->start.layout(obj, priv, anim->start.data);
118
          }
119
        return;
120
     }
121

122
   if (anim->recalculate)
123
     {
124
        _edje_box_layout_calculate_coords(obj, priv, anim);
125
        anim->start_progress = anim->progress;
126
        anim->recalculate = EINA_FALSE;
127
     }
128

129
   if ((anim->progress > 0) && (anim->start_progress < 1))
130
     _edje_box_layout_exec(obj, anim);
131
}
132

133
void
134
_edje_box_layout_free_data(void *data)
135
{
136
   Edje_Transition_Animation_Data *tad;
137
   Edje_Part_Box_Animation *anim = data;
138
   if (anim->start.free_data && anim->start.data)
139
     anim->start.free_data(anim->start.data);
140
   if (anim->end.free_data && anim->end.data)
141
     anim->end.free_data(anim->end.data);
142
   EINA_LIST_FREE(anim->objs, tad)
143
     free(tad);
144
   free(data);
145
}
146

147
Edje_Part_Box_Animation *
148
_edje_box_layout_anim_new(Evas_Object *box)
149
{
150
   Edje_Part_Box_Animation *anim = calloc(1, sizeof(Edje_Part_Box_Animation));
151
   if (!anim)
152
     return NULL;
153

154
   anim->box = box;
155
   evas_object_box_layout_set(box, _edje_box_layout, anim, NULL);
156

157
   return anim;
158
}
159

160
void
161
_edje_box_recalc_apply(Edje *ed EINA_UNUSED, Edje_Real_Part *ep, Edje_Calc_Params *p3 EINA_UNUSED, Edje_Part_Description_Box *chosen_desc)
162
{
163
   Evas_Object_Box_Data *priv;
164
#if 0
165
   int min_w, min_h;
166
#endif
167
   if ((ep->type != EDJE_RP_TYPE_CONTAINER) ||
168
       (!ep->typedata.container)) return;
169

170
   if ((ep->param2) && (NEQ(ep->description_pos, ZERO)))
171
     {
172
        Edje_Part_Description_Box *param2_desc = (Edje_Part_Description_Box *)ep->param2->description;
173
        if (ep->typedata.container->anim->end.layout == NULL)
174
          {
175
             _edje_box_layout_find_all(param2_desc->box.layout, param2_desc->box.alt_layout, &ep->typedata.container->anim->end.layout, &ep->typedata.container->anim->end.data, &ep->typedata.container->anim->end.free_data);
176
             ep->typedata.container->anim->end.padding.x = param2_desc->box.padding.x;
177
             ep->typedata.container->anim->end.padding.y = param2_desc->box.padding.y;
178
             ep->typedata.container->anim->end.align.x = param2_desc->box.align.x;
179
             ep->typedata.container->anim->end.align.y = param2_desc->box.align.y;
180

181
             priv = efl_data_scope_get(ep->object, EVAS_BOX_CLASS);
182
             if (priv == NULL)
183
               return;
184

185
             evas_object_box_padding_set(ep->object, ep->typedata.container->anim->start.padding.x, ep->typedata.container->anim->start.padding.y);
186
             evas_object_box_align_set(ep->object, TO_DOUBLE(ep->typedata.container->anim->start.align.x), TO_DOUBLE(ep->typedata.container->anim->start.align.y));
187
             ep->typedata.container->anim->start.layout(ep->object, priv, ep->typedata.container->anim->start.data);
188
             _edje_box_layout_calculate_coords(ep->object, priv, ep->typedata.container->anim);
189
             ep->typedata.container->anim->start_progress = 0.0;
190
          }
191
        evas_object_smart_changed(ep->object);
192
     }
193
   else
194
     {
195
        ep->typedata.container->anim->end.layout = NULL;
196
     }
197

198
   if (EINA_DBL_EQ(ep->description_pos, 0.0) || !ep->typedata.container->anim->start.layout)
199
     {
200
        _edje_box_layout_find_all(chosen_desc->box.layout, chosen_desc->box.alt_layout, &ep->typedata.container->anim->start.layout, &ep->typedata.container->anim->start.data, &ep->typedata.container->anim->start.free_data);
201
        ep->typedata.container->anim->start.padding.x = chosen_desc->box.padding.x;
202
        ep->typedata.container->anim->start.padding.y = chosen_desc->box.padding.y;
203
        ep->typedata.container->anim->start.align.x = chosen_desc->box.align.x;
204
        ep->typedata.container->anim->start.align.y = chosen_desc->box.align.y;
205
        evas_object_smart_changed(ep->object);
206
     }
207

208
   ep->typedata.container->anim->progress = ep->description_pos;
209

210
   if (evas_object_smart_need_recalculate_get(ep->object))
211
     {
212
        evas_object_smart_need_recalculate_set(ep->object, 0);
213
        evas_object_smart_calculate(ep->object);
214
     }
215
#if 0 /* Why the hell do we affect part size after resize ??? */
216
   evas_object_size_hint_combined_min_get(ep->object, &min_w, &min_h);
217
   if (chosen_desc->box.min.h && (p3->w < min_w))
218
     p3->w = min_w;
219
   if (chosen_desc->box.min.v && (p3->h < min_h))
220
     p3->h = min_h;
221
#endif
222
}
223

224
Eina_Bool
225
_edje_box_layout_add_child(Edje_Real_Part *rp, Evas_Object *child_obj)
226
{
227
   Edje_Transition_Animation_Data *tad;
228

229
   if ((rp->type != EDJE_RP_TYPE_CONTAINER) ||
230
       (!rp->typedata.container)) return EINA_FALSE;
231
   tad = calloc(1, sizeof(Edje_Transition_Animation_Data));
232
   if (!tad) return EINA_FALSE;
233
   tad->obj = child_obj;
234
   rp->typedata.container->anim->objs = eina_list_append(rp->typedata.container->anim->objs, tad);
235
   rp->typedata.container->anim->recalculate = EINA_TRUE;
236
   return EINA_TRUE;
237
}
238

239
void
240
_edje_box_layout_remove_child(Edje_Real_Part *rp, Evas_Object *child_obj)
241
{
242
   Eina_List *l;
243
   Edje_Transition_Animation_Data *tad;
244

245
   if ((rp->type != EDJE_RP_TYPE_CONTAINER) ||
246
       (!rp->typedata.container)) return;
247
   EINA_LIST_FOREACH(rp->typedata.container->anim->objs, l, tad)
248
     {
249
        if (tad->obj == child_obj)
250
          {
251
             free(eina_list_data_get(l));
252
             rp->typedata.container->anim->objs = eina_list_remove_list(rp->typedata.container->anim->objs, l);
253
             rp->typedata.container->anim->recalculate = EINA_TRUE;
254
             break;
255
          }
256
     }
257
   rp->typedata.container->anim->recalculate = EINA_TRUE;
258
}
259

260

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.