1 /*
2 Concerning the EDC reference:
3
4 The formatting for blocks and properties has been implemented as a table
5 which is filled using ALIASES.
6 For maximum flexibility I implemented them in the \@code/\@encode style,
7 this means that missing one or changing the order most certainly cause
8 formatting errors.
9
10 \@block
11 block name
12 \@context
13 code sample of the block
14 \@description
15 the block's description
16 \@since X.X
17 \@endblock
18
19 \@property
20 property name
21 \@parameters
22 property's parameter list
23 \@effect
24 the property description (lol)
25 \@since X.X
26 \@endproperty
27 */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <string.h>
34 #include <errno.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <ctype.h>
39 #ifdef _WIN32
40 # include <evil_private.h> /* mmap */
41 #else
42 # include <sys/mman.h>
43 #endif
44
45 #include "edje_cc.h"
46
47 /**
48 * @page edcref Edje Data Collection reference
49 *
50 * An Edje Data Collection, it's a plain text file (normally identified with the
51 * .edc extension), consisting of instructions for the Edje Compiler.
52 *
53 * The syntax for the edje data collection files follows a simple structure of
54 * "blocks { .. }" that can contain "properties: ..", more blocks, or both.
55 *
56 * @anchor sec_quickaccess Quick access to block descriptions:
57 * <ul>
58 * <li>@ref sec_toplevel "Top-Level"</li>
59 * <ul>
60 * <li>@ref sec_toplevel_externals "Externals"</li>
61 * <li>@ref sec_toplevel_images "Images"</li>
62 * <ul>
63 * <li>@ref sec_toplevel_images_set "Set"</li>
64 * <ul>
65 * <li>@ref sec_toplevel_images_set_image "Image"</li>
66 * </ul>
67 * </ul>
68 * <li>@ref sec_toplevel_fonts "Fonts"</li>
69 * <li>@ref sec_toplevel_data "Data"</li>
70 * <li>@ref sec_toplevel_color_classes "Color Classes"</li>
71 * <li>@ref sec_toplevel_styles "Styles"</li>
72 * <li>@ref sec_collections_group_filters "Filters"</li>
73 * </ul>
74 * <li>@ref sec_collections "Collections"</li>
75 * <ul>
76 * <li>@ref sec_collections_sounds "Sounds"</li>
77 * <ul>
78 * <li>@ref sec_collections_sounds_sample "Sample"</li>
79 * </ul>
80 * <li>@ref sec_collections_group_filters "Filters"</li>
81 * <li>@ref sec_collections_vibrations "Vibrations"</li>
82 * <ul>
83 * <li>@ref sec_collections_vibrations_sample "Sample"</li>
84 * </ul>
85 * <li>@ref sec_collections_group "Group"</li>
86 * <ul>
87 * <li>@ref sec_collections_group_script "Script"</li>
88 * <li>@ref sec_collections_group_limits "Limits"</li>
89 * <li>@ref sec_collections_group_data "Data"</li>
90 * <li>@ref sec_collections_group_filters "Filters"</li>
91 * <li>@ref sec_collections_group_parts "Parts"</li>
92 * <ul>
93 * <li>@ref sec_collections_group_parts_part "Part"</li>
94 * <ul>
95 * <li>@ref sec_collections_group_parts_dragable "Dragable"</li>
96 * <li>@ref sec_collections_group_parts_items "Items"</li>
97 * <li>@ref sec_collections_group_parts_description "Description"</li>
98 * <ul>
99 * <li>@ref sec_collections_group_parts_description_relatives "Relatives (rel1/rel2)"</li>
100 * <li>@ref sec_collections_group_parts_description_image "Image"</li>
101 * <li>@ref sec_collections_group_parts_description_proxy "Proxy"</li>
102 * <li>@ref sec_collections_group_parts_description_fill "Fill"</li>
103 * <ul>
104 * <li>@ref sec_collections_group_parts_description_fill_origin "Origin"</li>
105 * <li>@ref sec_collections_group_parts_description_fill_size "Size"</li>
106 * </ul>
107 * <li>@ref sec_collections_group_parts_description_text "Text"</li>
108 * <li>@ref sec_collections_group_parts_description_box "Box"</li>
109 * <ul>
110 * <li>@ref sec_collections_group_parts_items "Items"</li>
111 * </ul>
112 * <li>@ref sec_collections_group_parts_description_table "Table"</li>
113 * <li>@ref sec_collections_group_parts_description_physics "Physics"</li>
114 * <ul>
115 * <li>@ref sec_collections_group_parts_description_physics_movement_freedom "Movement Freedom"</li>
116 * <li>@ref sec_collections_group_parts_description_physics_faces "Faces"</li>
117 * </ul>
118 * <li>@ref sec_collections_group_parts_description_map "Map (3d/transformations)"</li>
119 * <ul>
120 * <li>@ref sec_collections_group_parts_description_map_rotation "Rotation"</li>
121 * </ul>
122 * <li>@ref sec_collections_group_parts_description_perspective "Perspective"</li>
123 * <li>@ref sec_collections_group_parts_descriptions_params "Params"</li>
124 * <li>@ref sec_collections_group_parts_description_links "Links"</li>
125 * <li>@ref sec_collections_group_parts_description_filter "Filter"</li>
126 * </ul>
127 * </ul>
128 * </ul>
129 * <li>@ref sec_collections_group_programs "Programs"</li>
130 * <ul>
131 * <li>@ref sec_collections_group_script "Script"</li>
132 * <li>@ref sec_collections_group_programs_program "Program"</li>
133 * <ul>
134 * <li>@ref sec_collections_group_script "Script"</li>
135 * <li>@ref sec_collections_group_program_sequence "Sequence"</li>
136 * <ul>
137 * <li>@ref sec_collections_group_script "Script"</li>
138 * </ul>
139 * </ul>
140 * <li>@ref sec_collections_group_script "Script"</li>
141 * <li>@ref sec_toplevel_fonts "Fonts"</li>
142 * </ul>
143 * <li>@ref sec_collections_group_physics "Physics"</li>
144 * <ul>
145 * <li>@ref sec_collections_group_physics_world "World"</li>
146 * </ul>
147 * </ul>
148 * </ul>
149 * <li>@ref sec_lazedc "LazEDC"</li>
150 * <ul>
151 * <li>@ref sec_lazedc_intro "Intro"</li>
152 * <li>@ref sec_lazedc_synonyms "Synonyms"</li>
153 * <li>@ref sec_lazedc_shorthand "Shorthand"</li>
154 * </ul>
155 * </ul>
156 *
157 * @author Andres Blanc (dresb) andresblanc@gmail.com
158 *
159 * <table class="edcref" border="0">
160 */
161
162 static Edje_Part_Collection_Directory_Entry *current_de = NULL;
163 static Edje_Part *current_part = NULL;
164 static Edje_Pack_Element *current_item = NULL;
165 static Edje_Part_Description_Common *current_desc = NULL;
166 static Edje_Part_Description_Common *parent_desc = NULL;
167 static Edje_Program *current_program = NULL;
168 static Eina_List *current_program_lookups = NULL;
169 Eina_Bool current_group_inherit = EINA_FALSE;
170 Eina_Bool script_is_replaceable = EINA_FALSE;
171 static Edje_Program *sequencing = NULL;
172 static Eina_List *sequencing_lookups = NULL;
173 static int *anonymous_delete = NULL;
174 static Edje_Part_Description_Anchors *current_anchors = NULL;
175 static Eina_Bool has_relatives = EINA_FALSE;
176
177 Eina_List *po_files;
178
179 static Eina_Hash *desc_hash = NULL;
180
181 struct _Edje_Cc_Handlers_Hierarchy_Info /* Struct that keeps globals value to impl hierarchy */
182 {
183 Edje_Part_Collection_Directory_Entry *current_de;
184 Edje_Part *current_part;
185 Edje_Pack_Element *current_item;
186 Edje_Part_Description_Common *current_desc;
187 Edje_Part_Description_Common *parent_desc;
188 Edje_Program *current_program;
189 Edje_Part *ep;
190 };
191 typedef struct _Edje_Cc_Handlers_Hierarchy_Info Edje_Cc_Handlers_Hierarchy_Info;
192
193 static Eina_Array *part_hierarchy = NULL; /* stack parts,support nested parts */
194 static void edje_cc_handlers_hierarchy_set(Edje_Part *src);
195 static Edje_Part *edje_cc_handlers_hierarchy_parent_get(void);
196 static void edje_cc_handlers_hierarchy_push(Edje_Part *ep, Edje_Part *cp);
197 static void edje_cc_handlers_hierarchy_rename(Edje_Part *old, Edje_Part *new);
198 static void edje_cc_handlers_hierarchy_pop(void);
199
200 static void _program_target_add(char *name);
201 static void _program_after(const char *name);
202 static void _program_free(Edje_Program *pr);
203 static Eina_Bool _program_remove(const char *name, Edje_Program **pgrms, unsigned int count);
204
205 static void *_part_free(Edje_Part_Collection *pc, Edje_Part *ep);
206
207 static void check_has_anchors(void);
208
209 static void st_id(void);
210 static void st_requires(void);
211 static void st_efl_version(void);
212 static void st_externals_external(void);
213
214 static void st_images_image(void);
215 static void ob_images_set(void);
216 static void st_images_set_name(void);
217 static void ob_images_set_image(void);
218 static void st_images_set_image_image(void);
219 static void st_images_set_image_size(void);
220 static void st_images_set_image_border(void);
221 static void st_images_set_image_border_scale_by(void);
222
223 static void st_fonts_font(void);
224
225 static void st_data_item(void);
226 static void st_data_file(void);
227
228 static void ob_styles_style(void);
229 static void st_styles_style_name(void);
230 static void st_styles_style_base(void);
231 static void st_styles_style_tag(void);
232
233 static void ob_color_tree(void);
234
235 static void ob_color_class(void);
236 static void st_color_class_name(void);
237 static void st_color_class_color(void);
238 static void st_color_class_color2(void);
239 static void st_color_class_color3(void);
240 static void st_color_class_desc(void);
241
242 static void ob_text_class(void);
243 static void st_text_class_name(void);
244 static void st_text_class_font(void);
245 static void st_text_class_size(void);
246
247 static void ob_size_class(void);
248 static void st_size_class_name(void);
249 static void st_size_class_min(void);
250 static void st_size_class_max(void);
251
252 static void ob_filters_filter(void);
253 static void ob_filters_filter_script(void);
254 static void st_filters_filter_file(void);
255 static void st_filters_filter_name(void);
256
257 static void ob_collections(void);
258 static void st_collections_base_scale(void);
259
260 static void ob_collections_group(void);
261 static void st_collections_group_name(void);
262 static void st_collections_group_skip_namespace_validation(void);
263 static void st_collections_group_inherit_only(void);
264 static void st_collections_group_inherit(void);
265 static void st_collections_group_program_source(void);
266 static void st_collections_group_part_remove(void);
267 static void st_collections_group_program_remove(void);
268 static void st_collections_group_lua_script_only(void);
269 static void st_collections_group_script_recursion(void);
270 static void st_collections_group_alias(void);
271 static void st_collections_group_min(void);
272 static void st_collections_group_max(void);
273 static void st_collections_group_broadcast_signal(void);
274 static void st_collections_group_data_item(void);
275 static void st_collections_group_orientation(void);
276 static void st_collections_group_mouse_events(void);
277 static void st_collections_group_use_custom_seat_names(void);
278 static void st_collections_group_inherit_script(void);
279
280 static void st_collections_group_limits_vertical(void);
281 static void st_collections_group_limits_horizontal(void);
282
283 static void ob_collections_group_script(void);
284 static void ob_collections_group_lua_script(void);
285
286 static void st_collections_group_parts_alias(void);
287
288 static Edje_Part *edje_cc_handlers_part_make(int);
289 static void ob_collections_group_parts_part(void);
290 static void st_collections_group_parts_part_name(void);
291 static void st_collections_group_parts_part_inherit(void);
292 static void st_collections_group_parts_part_type(void);
293 #ifdef HAVE_EPHYSICS
294 static void st_collections_group_parts_part_physics_body(void);
295 #endif
296 static void st_collections_group_parts_part_insert_before(void);
297 static void st_collections_group_parts_part_insert_after(void);
298 static void st_collections_group_parts_part_effect(void);
299 static void st_collections_group_parts_part_mouse_events(void);
300 static void st_collections_group_parts_part_anti_alias(void);
301 static void st_collections_group_parts_part_repeat_events(void);
302 static void st_collections_group_parts_part_ignore_flags(void);
303 static void st_collections_group_parts_part_mask_flags(void);
304 static void st_collections_group_parts_part_scale(void);
305 static void st_collections_group_parts_part_pointer_mode(void);
306 static void st_collections_group_parts_part_precise_is_inside(void);
307 static void st_collections_group_parts_part_use_alternate_font_metrics(void);
308 static void st_collections_group_parts_part_clip_to_id(void);
309 static void st_collections_group_parts_part_render(void);
310 static void st_collections_group_parts_part_no_render(void);
311 static void st_collections_group_parts_part_required(void);
312 static void st_collections_group_parts_part_norequired(void);
313 static void st_collections_group_parts_part_source(void);
314 static void st_collections_group_parts_part_source2(void);
315 static void st_collections_group_parts_part_source3(void);
316 static void st_collections_group_parts_part_source4(void);
317 static void st_collections_group_parts_part_source5(void);
318 static void st_collections_group_parts_part_source6(void);
319 static void st_collections_group_parts_part_entry_mode(void);
320 static void st_collections_group_parts_part_select_mode(void);
321 static void st_collections_group_parts_part_cursor_mode(void);
322 static void st_collections_group_parts_part_multiline(void);
323 static void st_collections_group_parts_part_access(void);
324 static void st_collections_group_parts_part_dragable_x(void);
325 static void st_collections_group_parts_part_dragable_y(void);
326 static void st_collections_group_parts_part_dragable_confine(void);
327 static void st_collections_group_parts_part_dragable_threshold(void);
328 static void st_collections_group_parts_part_dragable_events(void);
329 static void st_collections_group_parts_part_allowed_seats(void);
330
331 /* box and table items share these */
332 static void ob_collections_group_parts_part_box_items_item(void);
333 static void st_collections_group_parts_part_box_items_item_type(void);
334 static void st_collections_group_parts_part_box_items_item_name(void);
335 static void st_collections_group_parts_part_box_items_item_source(void);
336 static void st_collections_group_parts_part_box_items_item_min(void);
337 static void st_collections_group_parts_part_box_items_item_spread(void);
338 static void st_collections_group_parts_part_box_items_item_prefer(void);
339 static void st_collections_group_parts_part_box_items_item_max(void);
340 static void st_collections_group_parts_part_box_items_item_padding(void);
341 static void st_collections_group_parts_part_box_items_item_align(void);
342 static void st_collections_group_parts_part_box_items_item_weight(void);
343 static void st_collections_group_parts_part_box_items_item_aspect(void);
344 static void st_collections_group_parts_part_box_items_item_aspect_mode(void);
345 static void st_collections_group_parts_part_box_items_item_options(void);
346 /* but these are only for table */
347 static void st_collections_group_parts_part_table_items_item_position(void);
348 static void st_collections_group_parts_part_table_items_item_span(void);
349
350 static void ob_collections_group_parts_part_description(void);
351 static void ob_collections_group_parts_part_desc(void);
352 static void st_collections_group_parts_part_description_inherit(void);
353 static void ob_collections_group_parts_part_description_link(void);
354 static void st_collections_group_parts_part_description_link_base(void);
355 static void st_collections_group_parts_part_description_source(void);
356 static void st_collections_group_parts_part_description_state(void);
357 static void st_collections_group_parts_part_description_visible(void);
358 static void st_collections_group_parts_part_description_no_render(void);
359 static void st_collections_group_parts_part_description_limit(void);
360 static void st_collections_group_parts_part_description_align(void);
361 static void st_collections_group_parts_part_description_fixed(void);
362 static void st_collections_group_parts_part_description_min(void);
363 static void st_collections_group_parts_part_description_minmul(void);
364 static void st_collections_group_parts_part_description_max(void);
365 static void st_collections_group_parts_part_description_step(void);
366 static void st_collections_group_parts_part_description_aspect(void);
367 static void st_collections_group_parts_part_description_aspect_preference(void);
368 static void st_collections_group_parts_part_description_rel_to(void);
369 static void st_collections_group_parts_part_description_rel_to_x(void);
370 static void st_collections_group_parts_part_description_rel_to_y(void);
371 static void st_collections_group_parts_part_description_rel1_relative(void);
372 static void st_collections_group_parts_part_description_rel1_offset(void);
373 static void st_collections_group_parts_part_description_rel1_to_set(const char *name);
374 static void st_collections_group_parts_part_description_rel1_to(void);
375 static void st_collections_group_parts_part_description_rel1_to_x(void);
376 static void st_collections_group_parts_part_description_rel1_to_y(void);
377 static void st_collections_group_parts_part_description_rel2_relative(void);
378 static void st_collections_group_parts_part_description_rel2_offset(void);
379 static void st_collections_group_parts_part_description_rel2_to_set(const char *name);
380 static void st_collections_group_parts_part_description_rel2_to(void);
381 static void st_collections_group_parts_part_description_rel2_to_x(void);
382 static void st_collections_group_parts_part_description_rel2_to_y(void);
383 static void st_collections_group_parts_part_description_anchors_top(void);
384 static void st_collections_group_parts_part_description_anchors_bottom(void);
385 static void st_collections_group_parts_part_description_anchors_left(void);
386 static void st_collections_group_parts_part_description_anchors_right(void);
387 static void st_collections_group_parts_part_description_anchors_vertical_center(void);
388 static void st_collections_group_parts_part_description_anchors_horizontal_center(void);
389 static void st_collections_group_parts_part_description_anchors_fill(void);
390 static void st_collections_group_parts_part_description_anchors_margin(void);
391 static void st_collections_group_parts_part_description_clip_to_id(void);
392 static void st_collections_group_parts_part_description_size_class(void);
393 static void st_collections_group_parts_part_description_image_normal(void);
394 static void st_collections_group_parts_part_description_image_tween(void);
395 static void st_collections_group_parts_part_description_image_border(void);
396 static void st_collections_group_parts_part_description_image_middle(void);
397 static void st_collections_group_parts_part_description_image_border_scale(void);
398 static void st_collections_group_parts_part_description_image_border_scale_by(void);
399 static void st_collections_group_parts_part_description_image_scale_hint(void);
400 static void st_collections_group_parts_part_description_fill_smooth(void);
401 static void st_collections_group_parts_part_description_fill_origin_relative(void);
402 static void st_collections_group_parts_part_description_fill_origin_offset(void);
403 static void st_collections_group_parts_part_description_fill_size_relative(void);
404 static void st_collections_group_parts_part_description_fill_size_offset(void);
405 static void st_collections_group_parts_part_description_fill_type(void);
406 static void st_collections_group_parts_part_description_color_class(void);
407 static void st_collections_group_parts_part_description_color(void);
408 static void st_collections_group_parts_part_description_color2(void);
409 static void st_collections_group_parts_part_description_color3(void);
410 static void st_collections_group_parts_part_description_text_text(void);
411 static void st_collections_group_parts_part_description_text_domain(void);
412 static void st_collections_group_parts_part_description_text_text_class(void);
413 static void st_collections_group_parts_part_description_text_font(void);
414 static void st_collections_group_parts_part_description_text_style(void);
415 static void st_collections_group_parts_part_description_text_repch(void);
416 static void st_collections_group_parts_part_description_text_size(void);
417 static void st_collections_group_parts_part_description_text_size_range(void);
418 static void st_collections_group_parts_part_description_text_fit(void);
419 static void st_collections_group_parts_part_description_text_fit_step(void);
420 static void st_collections_group_parts_part_description_text_fit_size_array(void);
421 static void st_collections_group_parts_part_description_text_min(void);
422 static void st_collections_group_parts_part_description_text_max(void);
423 static void st_collections_group_parts_part_description_text_align(void);
424 static void st_collections_group_parts_part_description_text_source(void);
425 static void st_collections_group_parts_part_description_text_text_source(void);
426 static void st_collections_group_parts_part_description_text_ellipsis(void);
427 static void st_collections_group_parts_part_description_box_layout(void);
428 static void st_collections_group_parts_part_description_box_align(void);
429 static void st_collections_group_parts_part_description_box_padding(void);
430 static void st_collections_group_parts_part_description_box_min(void);
431 static void st_collections_group_parts_part_description_table_homogeneous(void);
432 static void st_collections_group_parts_part_description_table_align(void);
433 static void st_collections_group_parts_part_description_table_padding(void);
434 static void st_collections_group_parts_part_description_table_min(void);
435 static void st_collections_group_parts_part_description_proxy_source_visible(void);
436 static void st_collections_group_parts_part_description_proxy_source_clip(void);
437 static void st_collections_group_parts_part_description_offset_scale(void);
438 static void st_collections_group_parts_part_description_filter_code(void);
439 static void st_collections_group_parts_part_description_filter_source(void);
440 static void st_collections_group_parts_part_description_filter_data(void);
441
442 #ifdef HAVE_EPHYSICS
443 static void st_collections_group_parts_part_description_physics_mass(void);
444 static void st_collections_group_parts_part_description_physics_restitution(void);
445 static void st_collections_group_parts_part_description_physics_friction(void);
446 static void st_collections_group_parts_part_description_physics_damping(void);
447 static void st_collections_group_parts_part_description_physics_sleep(void);
448 static void st_collections_group_parts_part_description_physics_material(void);
449 static void st_collections_group_parts_part_description_physics_density(void);
450 static void st_collections_group_parts_part_description_physics_hardness(void);
451 static void st_collections_group_parts_part_description_physics_ignore_part_pos(void);
452 static void st_collections_group_parts_part_description_physics_light_on(void);
453 static void st_collections_group_parts_part_description_physics_z(void);
454 static void st_collections_group_parts_part_description_physics_depth(void);
455 static void st_collections_group_parts_part_description_physics_movement_freedom_linear(void);
456 static void st_collections_group_parts_part_description_physics_movement_freedom_angular(void);
457 static void st_collections_group_parts_part_description_physics_backface_cull(void);
458 static void st_collections_group_parts_part_description_physics_face(void);
459 static void st_collections_group_parts_part_description_physics_face_type(void);
460 static void st_collections_group_parts_part_description_physics_face_source(void);
461 #endif
462 static void st_collections_group_parts_part_description_map_perspective(void);
463 static void st_collections_group_parts_part_description_map_light(void);
464 static void st_collections_group_parts_part_description_map_rotation_center(void);
465 static void st_collections_group_parts_part_description_map_rotation_x(void);
466 static void st_collections_group_parts_part_description_map_rotation_y(void);
467 static void st_collections_group_parts_part_description_map_rotation_z(void);
468 static void st_collections_group_parts_part_description_map_on(void);
469 static void st_collections_group_parts_part_description_map_smooth(void);
470 static void st_collections_group_parts_part_description_map_alpha(void);
471 static void st_collections_group_parts_part_description_map_backface_cull(void);
472 static void st_collections_group_parts_part_description_map_perspective_on(void);
473 static void st_collections_group_parts_part_description_map_color(void);
474 static void st_collections_group_parts_part_description_map_zoom_x(void);
475 static void st_collections_group_parts_part_description_map_zoom_y(void);
476 static void st_collections_group_parts_part_description_map_zoom_center(void);
477 static void st_collections_group_parts_part_description_perspective_zplane(void);
478 static void st_collections_group_parts_part_description_perspective_focal(void);
479 static void st_collections_group_parts_part_api(void);
480
481 /* external part parameters */
482 static void st_collections_group_parts_part_description_params_int(void);
483 static void st_collections_group_parts_part_description_params_double(void);
484 static void st_collections_group_parts_part_description_params_string(void);
485 static void st_collections_group_parts_part_description_params_bool(void);
486 static void st_collections_group_parts_part_description_params_choice(void);
487 static void st_collections_group_parts_part_description_params_smart(void);
488
489 /* vector part parameter */
490 static void st_collections_group_parts_part_description_vector_frame(void);
491
492 static void ob_collections_group_programs_program(void);
493 static void st_collections_group_programs_program_name(void);
494 static void st_collections_group_programs_program_signal(void);
495 static void st_collections_group_programs_program_source(void);
496 static void st_collections_group_programs_program_filter(void);
497 static void st_collections_group_programs_program_in(void);
498 static void st_collections_group_programs_program_action(void);
499 static void st_collections_group_programs_program_transition(void);
500 static void st_collections_group_programs_program_target(void);
501 static void st_collections_group_programs_program_targets(void);
502 static void st_collections_group_programs_program_target_groups(void);
503 static void st_collections_group_programs_program_after(void);
504 static void st_collections_group_programs_program_api(void);
505 static void st_collections_group_target_group(void);
506
507 static void ob_collections_group_programs_program_sequence(void);
508
509 static void ob_collections_group_programs_program_script(void);
510 static void st_collections_group_sound_sample_name(void);
511 static void st_collections_group_sound_sample_source(void);
512 static void st_collections_group_sound_tone(void);
513 static void st_collections_group_vibration_sample_name(void);
514 static void st_collections_group_vibration_sample_source(void);
515
516 static void st_collections_group_translation_file_locale(void);
517 static void st_collections_group_translation_file_source(void);
518 #ifdef HAVE_EPHYSICS
519 static void st_collections_group_physics_world_gravity(void);
520 static void st_collections_group_physics_world_rate(void);
521 static void st_collections_group_physics_world_z(void);
522 static void st_collections_group_physics_world_depth(void);
523 #endif
524
525 /* short */
526 static void st_collections_group_parts_part_noscale(void);
527 static void st_collections_group_parts_part_precise(void);
528 static void st_collections_group_parts_part_noprecise(void);
529 static void st_collections_group_parts_part_mouse(void);
530 static void st_collections_group_parts_part_nomouse(void);
531 static void st_collections_group_parts_part_repeat(void);
532 static void st_collections_group_parts_part_norepeat(void);
533 static void st_collections_group_parts_part_description_vis(void);
534 static void st_collections_group_parts_part_description_hid(void);
535 static void ob_collections_group_parts_part_short(void);
536
537 static void st_collections_group_mouse(void);
538 static void st_collections_group_nomouse(void);
539 static void st_collections_group_broadcast(void);
540 static void st_collections_group_nobroadcast(void);
541 static void st_collections_group_noinherit_script(void);
542
543 static void st_images_vector(void);
544 static void _handle_vector_image(void);
545
546 /*****/
547
548 #define STRDUP(x) eina_strdup(x)
549
550 #define IMAGE_STATEMENTS(PREFIX) \
551 {PREFIX "images.image", st_images_image}, \
552 {PREFIX "images.vector", st_images_vector}, \
553 {PREFIX "images.set.name", st_images_set_name}, \
554 {PREFIX "images.set.image.image", st_images_set_image_image}, \
555 {PREFIX "images.set.image.size", st_images_set_image_size}, \
556 {PREFIX "images.set.image.border", st_images_set_image_border}, \
557 {PREFIX "images.set.image.scale_by", st_images_set_image_border_scale_by},
558
559 #define IMAGE_SET_STATEMENTS(PREFIX) \
560 {PREFIX ".image", st_images_image}, /* dup */ \
561 {PREFIX ".set.name", st_images_set_name}, /* dup */ \
562 {PREFIX ".set.image.image", st_images_set_image_image}, /* dup */ \
563 {PREFIX ".set.image.size", st_images_set_image_size}, /* dup */ \
564 {PREFIX ".set.image.border", st_images_set_image_border}, /* dup */ \
565 {PREFIX ".set.image.scale_by", st_images_set_image_border_scale_by}, /* dup */
566
567 #define FONT_STYLE_CC_STATEMENTS(PREFIX) \
568 {PREFIX "fonts.font", st_fonts_font}, /* dup */ \
569 {PREFIX "styles.style.name", st_styles_style_name}, /* dup */ \
570 {PREFIX "styles.style.base", st_styles_style_base}, /* dup */ \
571 {PREFIX "styles.style.tag", st_styles_style_tag}, /* dup */ \
572 {PREFIX "color_classes.color_class.name", st_color_class_name}, /* dup */ \
573 {PREFIX "color_classes.color_class.color", st_color_class_color}, /* dup */ \
574 {PREFIX "color_classes.color_class.color2", st_color_class_color2}, /* dup */ \
575 {PREFIX "color_classes.color_class.color3", st_color_class_color3}, /* dup */ \
576 {PREFIX "color_classes.color_class.description", st_color_class_desc}, /* dup */ \
577 {PREFIX "color_classes.color_class.desc", st_color_class_desc}, /* dup */
578
579 #define TEXT_CLASS_STATEMENTS(PREFIX) \
580 {PREFIX "text_classes.text_class.name", st_text_class_name}, /* dup */ \
581 {PREFIX "text_classes.text_class.font", st_text_class_font}, /* dup */ \
582 {PREFIX "text_classes.text_class.size", st_text_class_size}, /* dup */
583
584 #define SIZE_CLASS_STATEMENTS(PREFIX) \
585 {PREFIX "size_classes.size_class.name", st_size_class_name}, /* dup */ \
586 {PREFIX "size_classes.size_class.min", st_size_class_min}, /* dup */ \
587 {PREFIX "size_classes.size_class.max", st_size_class_max}, /* dup */
588
589 #define PROGRAM_SEQUENCE(PREFIX, NAME, FN) \
590 {PREFIX ".program."NAME, FN}, /* dup */ \
591 {PREFIX ".program.sequence."NAME, FN}, /* dup */
592
593 #define PROGRAM_BASE(PREFIX) \
594 PROGRAM_SEQUENCE(PREFIX, "name", st_collections_group_programs_program_name) \
595 PROGRAM_SEQUENCE(PREFIX, "signal", st_collections_group_programs_program_signal) \
596 PROGRAM_SEQUENCE(PREFIX, "source", st_collections_group_programs_program_source) \
597 PROGRAM_SEQUENCE(PREFIX, "in", st_collections_group_programs_program_in) \
598 PROGRAM_SEQUENCE(PREFIX, "action", st_collections_group_programs_program_action) \
599 PROGRAM_SEQUENCE(PREFIX, "transition", st_collections_group_programs_program_transition) \
600 PROGRAM_SEQUENCE(PREFIX, "target", st_collections_group_programs_program_target) \
601 PROGRAM_SEQUENCE(PREFIX, "target_groups", st_collections_group_programs_program_target_groups) \
602 PROGRAM_SEQUENCE(PREFIX, "groups", st_collections_group_programs_program_target_groups) \
603 PROGRAM_SEQUENCE(PREFIX, "targets", st_collections_group_programs_program_targets) \
604 PROGRAM_SEQUENCE(PREFIX, "after", st_collections_group_programs_program_after) \
605 PROGRAM_SEQUENCE(PREFIX, "api", st_collections_group_programs_program_api) \
606 PROGRAM_SEQUENCE(PREFIX, "filter", st_collections_group_programs_program_filter)
607
608 #define PROGRAM_STATEMENTS(PREFIX) \
609 IMAGE_SET_STATEMENTS(PREFIX ".programs") \
610 IMAGE_STATEMENTS(PREFIX ".programs.") \
611 IMAGE_SET_STATEMENTS(PREFIX ".programs") \
612 {PREFIX ".programs.font", st_fonts_font}, /* dup */ \
613 {PREFIX ".programs.fonts.font", st_fonts_font}, /* dup */ \
614 PROGRAM_BASE(PREFIX) \
615 PROGRAM_BASE(PREFIX ".programs")
616
617 #define FILTERS_STATEMENTS(PREFIX) \
618 {PREFIX "filters.filter.file", st_filters_filter_file}, \
619 {PREFIX "filters.filter.name", st_filters_filter_name},
620
621 New_Statement_Handler statement_handlers[] =
622 {
623 {"id", st_id},
624 {"requires", st_requires},
625 {"efl_version", st_efl_version},
626 {"externals.external", st_externals_external},
627 IMAGE_STATEMENTS("")
628 FONT_STYLE_CC_STATEMENTS("")
629 TEXT_CLASS_STATEMENTS("")
630 SIZE_CLASS_STATEMENTS("")
631 {
632 "data.item", st_data_item
633 },
634 {"data.file", st_data_file},
635 FILTERS_STATEMENTS("")
636 {
637 "collections.externals.external", st_externals_external
638 }, /* dup */
639 IMAGE_STATEMENTS("collections.")
640 IMAGE_SET_STATEMENTS("collections")
641 {
642 "collections.font", st_fonts_font
643 }, /* dup */
644 FONT_STYLE_CC_STATEMENTS("collections.")
645 TEXT_CLASS_STATEMENTS("collections.")
646 SIZE_CLASS_STATEMENTS("collections.")
647 {
648 "collections.base_scale", st_collections_base_scale
649 },
650 {"collections.translation.file.locale", st_collections_group_translation_file_locale},
651 {"collections.translation.file.source", st_collections_group_translation_file_source},
652 {"collections.group.translation.file.locale", st_collections_group_translation_file_locale},
653 {"collections.group.translation.file.source", st_collections_group_translation_file_source},
654
655 {"collections.sounds.sample.name", st_collections_group_sound_sample_name},
656 {"collections.sounds.sample.source", st_collections_group_sound_sample_source},
657 {"collections.group.sounds.sample.name", st_collections_group_sound_sample_name}, /* dup */
658 {"collections.group.sounds.sample.source", st_collections_group_sound_sample_source}, /* dup */
659 {"collections.sounds.tone", st_collections_group_sound_tone},
660 {"collections.group.sounds.tone", st_collections_group_sound_tone}, /* dup */
661 {"collections.vibrations.sample.name", st_collections_group_vibration_sample_name},
662 {"collections.vibrations.sample.source", st_collections_group_vibration_sample_source},
663 FILTERS_STATEMENTS("collections.") /* dup */
664 {
665 "collections.group.vibrations.sample.name", st_collections_group_vibration_sample_name
666 }, /* dup */
667 {"collections.group.vibrations.sample.source", st_collections_group_vibration_sample_source}, /* dup */
668 {"collections.group.name", st_collections_group_name},
669 {"collections.group.skip_namespace_validation", st_collections_group_skip_namespace_validation},
670 {"collections.group.program_source", st_collections_group_program_source},
671 {"collections.group.inherit", st_collections_group_inherit},
672 {"collections.group.inherit_only", st_collections_group_inherit_only},
673 {"collections.group.use_custom_seat_names", st_collections_group_use_custom_seat_names},
674 {"collections.group.target_group", st_collections_group_target_group}, /* dup */
675 {"collections.group.part_remove", st_collections_group_part_remove},
676 {"collections.group.program_remove", st_collections_group_program_remove},
677 {"collections.group.lua_script_only", st_collections_group_lua_script_only},
678 {"collections.group.script_recursion", st_collections_group_script_recursion},
679 {"collections.group.alias", st_collections_group_alias},
680 {"collections.group.min", st_collections_group_min},
681 {"collections.group.max", st_collections_group_max},
682 {"collections.group.broadcast_signal", st_collections_group_broadcast_signal},
683 {"collections.group.orientation", st_collections_group_orientation},
684 {"collections.group.mouse_events", st_collections_group_mouse_events},
685 {"collections.group.inherit_script", st_collections_group_inherit_script},
686 {"collections.group.data.item", st_collections_group_data_item},
687 {"collections.group.limits.horizontal", st_collections_group_limits_horizontal},
688 {"collections.group.limits.vertical", st_collections_group_limits_vertical},
689 {"collections.group.externals.external", st_externals_external}, /* dup */
690 {"collections.group.programs.target_group", st_collections_group_target_group}, /* dup */
691 IMAGE_SET_STATEMENTS("collections.group")
692 IMAGE_STATEMENTS("collections.group.")
693 {"collections.group.font", st_fonts_font}, /* dup */
694 FONT_STYLE_CC_STATEMENTS("collections.group.")
695 TEXT_CLASS_STATEMENTS("collections.group.")
696 SIZE_CLASS_STATEMENTS("collections.group.")
697 {
698 "collections.group.parts.alias", st_collections_group_parts_alias
699 },
700 IMAGE_SET_STATEMENTS("collections.group.parts")
701 IMAGE_STATEMENTS("collections.group.parts.")
702 {
703 "collections.group.parts.font", st_fonts_font
704 }, /* dup */
705 FONT_STYLE_CC_STATEMENTS("collections.group.parts.")
706 TEXT_CLASS_STATEMENTS("collections.group.parts.")
707 SIZE_CLASS_STATEMENTS("collections.group.parts.")
708 {
709 "collections.group.parts.target_group", st_collections_group_target_group
710 }, /* dup */
711 {"collections.group.parts.part.name", st_collections_group_parts_part_name},
712 {"collections.group.parts.part.target_group", st_collections_group_target_group}, /* dup */
713 {"collections.group.parts.part.inherit", st_collections_group_parts_part_inherit},
714 {"collections.group.parts.part.api", st_collections_group_parts_part_api},
715 {"collections.group.parts.part.type", st_collections_group_parts_part_type},
716 #ifdef HAVE_EPHYSICS
717 {"collections.group.parts.part.physics_body", st_collections_group_parts_part_physics_body},
718 #endif
719 {"collections.group.parts.part.insert_before", st_collections_group_parts_part_insert_before},
720 {"collections.group.parts.part.insert_after", st_collections_group_parts_part_insert_after},
721 {"collections.group.parts.part.effect", st_collections_group_parts_part_effect},
722 {"collections.group.parts.part.mouse_events", st_collections_group_parts_part_mouse_events},
723 {"collections.group.parts.part.anti_alias", st_collections_group_parts_part_anti_alias},
724 {"collections.group.parts.part.repeat_events", st_collections_group_parts_part_repeat_events},
725 {"collections.group.parts.part.ignore_flags", st_collections_group_parts_part_ignore_flags},
726 {"collections.group.parts.part.mask_flags", st_collections_group_parts_part_mask_flags},
727 {"collections.group.parts.part.scale", st_collections_group_parts_part_scale},
728 {"collections.group.parts.part.pointer_mode", st_collections_group_parts_part_pointer_mode},
729 {"collections.group.parts.part.precise_is_inside", st_collections_group_parts_part_precise_is_inside},
730 {"collections.group.parts.part.use_alternate_font_metrics", st_collections_group_parts_part_use_alternate_font_metrics},
731 {"collections.group.parts.part.clip_to", st_collections_group_parts_part_clip_to_id},
732 {"collections.group.parts.part.no_render", st_collections_group_parts_part_no_render},
733 {"collections.group.parts.part.required", st_collections_group_parts_part_required},
734 {"collections.group.parts.part.source", st_collections_group_parts_part_source},
735 {"collections.group.parts.part.source2", st_collections_group_parts_part_source2},
736 {"collections.group.parts.part.source3", st_collections_group_parts_part_source3},
737 {"collections.group.parts.part.source4", st_collections_group_parts_part_source4},
738 {"collections.group.parts.part.source5", st_collections_group_parts_part_source5},
739 {"collections.group.parts.part.source6", st_collections_group_parts_part_source6},
740 {"collections.group.parts.part.dragable.x", st_collections_group_parts_part_dragable_x},
741 {"collections.group.parts.part.dragable.y", st_collections_group_parts_part_dragable_y},
742 {"collections.group.parts.part.dragable.confine", st_collections_group_parts_part_dragable_confine},
743 {"collections.group.parts.part.dragable.threshold", st_collections_group_parts_part_dragable_threshold},
744 {"collections.group.parts.part.dragable.events", st_collections_group_parts_part_dragable_events},
745 {"collections.group.parts.part.entry_mode", st_collections_group_parts_part_entry_mode},
746 {"collections.group.parts.part.select_mode", st_collections_group_parts_part_select_mode},
747 {"collections.group.parts.part.cursor_mode", st_collections_group_parts_part_cursor_mode},
748 {"collections.group.parts.part.multiline", st_collections_group_parts_part_multiline},
749 {"collections.group.parts.part.access", st_collections_group_parts_part_access},
750 {"collections.group.parts.part.allowed_seats", st_collections_group_parts_part_allowed_seats},
751 IMAGE_SET_STATEMENTS("collections.group.parts.part")
752 IMAGE_STATEMENTS("collections.group.parts.part.")
753 {
754 "collections.group.parts.part.font", st_fonts_font
755 }, /* dup */
756 FONT_STYLE_CC_STATEMENTS("collections.group.parts.part.")
757 TEXT_CLASS_STATEMENTS("collections.group.parts.part.")
758 SIZE_CLASS_STATEMENTS("collections.group.parts.part.")
759 {
760 "collections.group.parts.part.box.items.item.type", st_collections_group_parts_part_box_items_item_type
761 },
762 {"collections.group.parts.part.box.items.item.name", st_collections_group_parts_part_box_items_item_name},
763 {"collections.group.parts.part.box.items.item.source", st_collections_group_parts_part_box_items_item_source},
764 {"collections.group.parts.part.box.items.item.min", st_collections_group_parts_part_box_items_item_min},
765 {"collections.group.parts.part.box.items.item.spread", st_collections_group_parts_part_box_items_item_spread},
766 {"collections.group.parts.part.box.items.item.prefer", st_collections_group_parts_part_box_items_item_prefer},
767 {"collections.group.parts.part.box.items.item.max", st_collections_group_parts_part_box_items_item_max},
768 {"collections.group.parts.part.box.items.item.padding", st_collections_group_parts_part_box_items_item_padding},
769 {"collections.group.parts.part.box.items.item.align", st_collections_group_parts_part_box_items_item_align},
770 {"collections.group.parts.part.box.items.item.weight", st_collections_group_parts_part_box_items_item_weight},
771 {"collections.group.parts.part.box.items.item.aspect", st_collections_group_parts_part_box_items_item_aspect},
772 {"collections.group.parts.part.box.items.item.aspect_mode", st_collections_group_parts_part_box_items_item_aspect_mode},
773 {"collections.group.parts.part.box.items.item.options", st_collections_group_parts_part_box_items_item_options},
774 {"collections.group.parts.part.table.items.item.type", st_collections_group_parts_part_box_items_item_type}, /* dup */
775 {"collections.group.parts.part.table.items.item.name", st_collections_group_parts_part_box_items_item_name}, /* dup */
776 {"collections.group.parts.part.table.items.item.source", st_collections_group_parts_part_box_items_item_source}, /* dup */
777 {"collections.group.parts.part.table.items.item.min", st_collections_group_parts_part_box_items_item_min}, /* dup */
778 {"collections.group.parts.part.table.items.item.spread", st_collections_group_parts_part_box_items_item_spread}, /* dup */
779 {"collections.group.parts.part.table.items.item.prefer", st_collections_group_parts_part_box_items_item_prefer}, /* dup */
780 {"collections.group.parts.part.table.items.item.max", st_collections_group_parts_part_box_items_item_max}, /* dup */
781 {"collections.group.parts.part.table.items.item.padding", st_collections_group_parts_part_box_items_item_padding}, /* dup */
782 {"collections.group.parts.part.table.items.item.align", st_collections_group_parts_part_box_items_item_align}, /* dup */
783 {"collections.group.parts.part.table.items.item.weight", st_collections_group_parts_part_box_items_item_weight}, /* dup */
784 {"collections.group.parts.part.table.items.item.aspect", st_collections_group_parts_part_box_items_item_aspect}, /* dup */
785 {"collections.group.parts.part.table.items.item.aspect_mode", st_collections_group_parts_part_box_items_item_aspect_mode}, /* dup */
786 {"collections.group.parts.part.table.items.item.options", st_collections_group_parts_part_box_items_item_options}, /* dup */
787 {"collections.group.parts.part.table.items.item.position", st_collections_group_parts_part_table_items_item_position},
788 {"collections.group.parts.part.table.items.item.span", st_collections_group_parts_part_table_items_item_span},
789 {"collections.group.parts.part.description.target_group", st_collections_group_target_group}, /* dup */
790 {"collections.group.parts.part.description.inherit", st_collections_group_parts_part_description_inherit},
791 {"collections.group.parts.part.description.link.base", st_collections_group_parts_part_description_link_base},
792 {"collections.group.parts.part.description.link.transition", st_collections_group_programs_program_transition},
793 {"collections.group.parts.part.description.link.after", st_collections_group_programs_program_after},
794 {"collections.group.parts.part.description.link.in", st_collections_group_programs_program_in},
795 {"collections.group.parts.part.description.source", st_collections_group_parts_part_description_source},
796 {"collections.group.parts.part.description.state", st_collections_group_parts_part_description_state},
797 {"collections.group.parts.part.description.visible", st_collections_group_parts_part_description_visible},
798 {"collections.group.parts.part.description.limit", st_collections_group_parts_part_description_limit},
799 {"collections.group.parts.part.description.no_render", st_collections_group_parts_part_description_no_render},
800 {"collections.group.parts.part.description.align", st_collections_group_parts_part_description_align},
801 {"collections.group.parts.part.description.fixed", st_collections_group_parts_part_description_fixed},
802 {"collections.group.parts.part.description.min", st_collections_group_parts_part_description_min},
803 {"collections.group.parts.part.description.minmul", st_collections_group_parts_part_description_minmul},
804 {"collections.group.parts.part.description.max", st_collections_group_parts_part_description_max},
805 {"collections.group.parts.part.description.step", st_collections_group_parts_part_description_step},
806 {"collections.group.parts.part.description.aspect", st_collections_group_parts_part_description_aspect},
807 {"collections.group.parts.part.description.aspect_preference", st_collections_group_parts_part_description_aspect_preference},
808 {"collections.group.parts.part.description.rel.to", st_collections_group_parts_part_description_rel_to},
809 {"collections.group.parts.part.description.rel.to_x", st_collections_group_parts_part_description_rel_to_x},
810 {"collections.group.parts.part.description.rel.to_y", st_collections_group_parts_part_description_rel_to_y},
811 {"collections.group.parts.part.description.rel1.relative", st_collections_group_parts_part_description_rel1_relative},
812 {"collections.group.parts.part.description.rel1.offset", st_collections_group_parts_part_description_rel1_offset},
813 {"collections.group.parts.part.description.rel1.to", st_collections_group_parts_part_description_rel1_to},
814 {"collections.group.parts.part.description.rel1.to_x", st_collections_group_parts_part_description_rel1_to_x},
815 {"collections.group.parts.part.description.rel1.to_y", st_collections_group_parts_part_description_rel1_to_y},
816 {"collections.group.parts.part.description.rel2.relative", st_collections_group_parts_part_description_rel2_relative},
817 {"collections.group.parts.part.description.rel2.offset", st_collections_group_parts_part_description_rel2_offset},
818 {"collections.group.parts.part.description.rel2.to", st_collections_group_parts_part_description_rel2_to},
819 {"collections.group.parts.part.description.rel2.to_x", st_collections_group_parts_part_description_rel2_to_x},
820 {"collections.group.parts.part.description.rel2.to_y", st_collections_group_parts_part_description_rel2_to_y},
821 {"collections.group.parts.part.description.offset_scale", st_collections_group_parts_part_description_offset_scale},
822 {"collections.group.parts.part.description.anchors.top", st_collections_group_parts_part_description_anchors_top},
823 {"collections.group.parts.part.description.anchors.bottom", st_collections_group_parts_part_description_anchors_bottom},
824 {"collections.group.parts.part.description.anchors.left", st_collections_group_parts_part_description_anchors_left},
825 {"collections.group.parts.part.description.anchors.right", st_collections_group_parts_part_description_anchors_right},
826 {"collections.group.parts.part.description.anchors.vertical_center", st_collections_group_parts_part_description_anchors_vertical_center},
827 {"collections.group.parts.part.description.anchors.horizontal_center", st_collections_group_parts_part_description_anchors_horizontal_center},
828 {"collections.group.parts.part.description.anchors.fill", st_collections_group_parts_part_description_anchors_fill},
829 {"collections.group.parts.part.description.anchors.margin", st_collections_group_parts_part_description_anchors_margin},
830 {"collections.group.parts.part.description.clip_to", st_collections_group_parts_part_description_clip_to_id},
831 {"collections.group.parts.part.description.size_class", st_collections_group_parts_part_description_size_class},
832 {"collections.group.parts.part.description.image.normal", st_collections_group_parts_part_description_image_normal},
833 {"collections.group.parts.part.description.image.tween", st_collections_group_parts_part_description_image_tween},
834 IMAGE_SET_STATEMENTS("collections.group.parts.part.description.image")
835 IMAGE_STATEMENTS("collections.group.parts.part.description.image.")
836 {
837 "collections.group.parts.part.description.image.border", st_collections_group_parts_part_description_image_border
838 },
839 {"collections.group.parts.part.description.image.middle", st_collections_group_parts_part_description_image_middle},
840 {"collections.group.parts.part.description.image.border_scale", st_collections_group_parts_part_description_image_border_scale},
841 {"collections.group.parts.part.description.image.border_scale_by", st_collections_group_parts_part_description_image_border_scale_by},
842 {"collections.group.parts.part.description.image.scale_hint", st_collections_group_parts_part_description_image_scale_hint},
843 {"collections.group.parts.part.description.fill.smooth", st_collections_group_parts_part_description_fill_smooth},
844 {"collections.group.parts.part.description.fill.origin.relative", st_collections_group_parts_part_description_fill_origin_relative},
845 {"collections.group.parts.part.description.fill.origin.offset", st_collections_group_parts_part_description_fill_origin_offset},
846 {"collections.group.parts.part.description.fill.size.relative", st_collections_group_parts_part_description_fill_size_relative},
847 {"collections.group.parts.part.description.fill.size.offset", st_collections_group_parts_part_description_fill_size_offset},
848 {"collections.group.parts.part.description.fill.type", st_collections_group_parts_part_description_fill_type},
849 {"collections.group.parts.part.description.color_class", st_collections_group_parts_part_description_color_class},
850 {"collections.group.parts.part.description.color", st_collections_group_parts_part_description_color},
851 {"collections.group.parts.part.description.color2", st_collections_group_parts_part_description_color2},
852 {"collections.group.parts.part.description.color3", st_collections_group_parts_part_description_color3},
853 {"collections.group.parts.part.description.text.text", st_collections_group_parts_part_description_text_text},
854 {"collections.group.parts.part.description.text.domain", st_collections_group_parts_part_description_text_domain},
855 {"collections.group.parts.part.description.text.text_class", st_collections_group_parts_part_description_text_text_class},
856 {"collections.group.parts.part.description.text.font", st_collections_group_parts_part_description_text_font},
857 {"collections.group.parts.part.description.text.style", st_collections_group_parts_part_description_text_style},
858 {"collections.group.parts.part.description.text.repch", st_collections_group_parts_part_description_text_repch},
859 {"collections.group.parts.part.description.text.size", st_collections_group_parts_part_description_text_size},
860 {"collections.group.parts.part.description.text.size_range", st_collections_group_parts_part_description_text_size_range},
861 {"collections.group.parts.part.description.text.fit", st_collections_group_parts_part_description_text_fit},
862 {"collections.group.parts.part.description.text.fit_step", st_collections_group_parts_part_description_text_fit_step},
863 {"collections.group.parts.part.description.text.fit_size_array", st_collections_group_parts_part_description_text_fit_size_array},
864 {"collections.group.parts.part.description.text.min", st_collections_group_parts_part_description_text_min},
865 {"collections.group.parts.part.description.text.max", st_collections_group_parts_part_description_text_max},
866 {"collections.group.parts.part.description.text.align", st_collections_group_parts_part_description_text_align},
867 {"collections.group.parts.part.description.text.source", st_collections_group_parts_part_description_text_source},
868 {"collections.group.parts.part.description.text.text_source", st_collections_group_parts_part_description_text_text_source},
869 {"collections.group.parts.part.description.text.font", st_fonts_font}, /* dup */
870 {"collections.group.parts.part.description.text.fonts.font", st_fonts_font}, /* dup */
871 {"collections.group.parts.part.description.text.elipsis", st_collections_group_parts_part_description_text_ellipsis},
872 {"collections.group.parts.part.description.text.ellipsis", st_collections_group_parts_part_description_text_ellipsis},
873 {"collections.group.parts.part.description.text.filter", st_collections_group_parts_part_description_filter_code}, /* dup */
874 {"collections.group.parts.part.description.box.layout", st_collections_group_parts_part_description_box_layout},
875 {"collections.group.parts.part.description.box.align", st_collections_group_parts_part_description_box_align},
876 {"collections.group.parts.part.description.box.padding", st_collections_group_parts_part_description_box_padding},
877 {"collections.group.parts.part.description.box.min", st_collections_group_parts_part_description_box_min},
878 {"collections.group.parts.part.description.table.homogeneous", st_collections_group_parts_part_description_table_homogeneous},
879 {"collections.group.parts.part.description.table.align", st_collections_group_parts_part_description_table_align},
880 {"collections.group.parts.part.description.table.padding", st_collections_group_parts_part_description_table_padding},
881 {"collections.group.parts.part.description.table.min", st_collections_group_parts_part_description_table_min},
882 {"collections.group.parts.part.description.proxy.source_visible", st_collections_group_parts_part_description_proxy_source_visible},
883 {"collections.group.parts.part.description.proxy.source_clip", st_collections_group_parts_part_description_proxy_source_clip},
884 {"collections.group.parts.part.description.filter.code", st_collections_group_parts_part_description_filter_code},
885 {"collections.group.parts.part.description.filter.source", st_collections_group_parts_part_description_filter_source},
886 {"collections.group.parts.part.description.filter.data", st_collections_group_parts_part_description_filter_data},
887
888 #ifdef HAVE_EPHYSICS
889 {"collections.group.parts.part.description.physics.mass", st_collections_group_parts_part_description_physics_mass},
890 {"collections.group.parts.part.description.physics.restitution", st_collections_group_parts_part_description_physics_restitution},
891 {"collections.group.parts.part.description.physics.friction", st_collections_group_parts_part_description_physics_friction},
892 {"collections.group.parts.part.description.physics.damping", st_collections_group_parts_part_description_physics_damping},
893 {"collections.group.parts.part.description.physics.sleep", st_collections_group_parts_part_description_physics_sleep},
894 {"collections.group.parts.part.description.physics.material", st_collections_group_parts_part_description_physics_material},
895 {"collections.group.parts.part.description.physics.density", st_collections_group_parts_part_description_physics_density},
896 {"collections.group.parts.part.description.physics.hardness", st_collections_group_parts_part_description_physics_hardness},
897 {"collections.group.parts.part.description.physics.movement_freedom.linear", st_collections_group_parts_part_description_physics_movement_freedom_linear},
898 {"collections.group.parts.part.description.physics.movement_freedom.angular", st_collections_group_parts_part_description_physics_movement_freedom_angular},
899 {"collections.group.parts.part.description.physics.ignore_part_pos", st_collections_group_parts_part_description_physics_ignore_part_pos},
900 {"collections.group.parts.part.description.physics.light_on", st_collections_group_parts_part_description_physics_light_on},
901 {"collections.group.parts.part.description.physics.z", st_collections_group_parts_part_description_physics_z},
902 {"collections.group.parts.part.description.physics.depth", st_collections_group_parts_part_description_physics_depth},
903 {"collections.group.parts.part.description.physics.backface_cull", st_collections_group_parts_part_description_physics_backface_cull},
904 {"collections.group.parts.part.description.physics.faces.face.type", st_collections_group_parts_part_description_physics_face_type},
905 {"collections.group.parts.part.description.physics.faces.face.source", st_collections_group_parts_part_description_physics_face_source},
906 #endif
907 {"collections.group.parts.part.description.map.perspective", st_collections_group_parts_part_description_map_perspective},
908 {"collections.group.parts.part.description.map.light", st_collections_group_parts_part_description_map_light},
909 {"collections.group.parts.part.description.map.rotation.center", st_collections_group_parts_part_description_map_rotation_center},
910 {"collections.group.parts.part.description.map.rotation.x", st_collections_group_parts_part_description_map_rotation_x},
911 {"collections.group.parts.part.description.map.rotation.y", st_collections_group_parts_part_description_map_rotation_y},
912 {"collections.group.parts.part.description.map.rotation.z", st_collections_group_parts_part_description_map_rotation_z},
913 {"collections.group.parts.part.description.map.on", st_collections_group_parts_part_description_map_on},
914 {"collections.group.parts.part.description.map.smooth", st_collections_group_parts_part_description_map_smooth},
915 {"collections.group.parts.part.description.map.alpha", st_collections_group_parts_part_description_map_alpha},
916 {"collections.group.parts.part.description.map.backface_cull", st_collections_group_parts_part_description_map_backface_cull},
917 {"collections.group.parts.part.description.map.perspective_on", st_collections_group_parts_part_description_map_perspective_on},
918 {"collections.group.parts.part.description.map.color", st_collections_group_parts_part_description_map_color},
919 {"collections.group.parts.part.description.map.zoom.x", st_collections_group_parts_part_description_map_zoom_x},
920 {"collections.group.parts.part.description.map.zoom.y", st_collections_group_parts_part_description_map_zoom_y},
921 {"collections.group.parts.part.description.map.zoom.center", st_collections_group_parts_part_description_map_zoom_center},
922 {"collections.group.parts.part.description.perspective.zplane", st_collections_group_parts_part_description_perspective_zplane},
923 {"collections.group.parts.part.description.perspective.focal", st_collections_group_parts_part_description_perspective_focal},
924 {"collections.group.parts.part.description.params.int", st_collections_group_parts_part_description_params_int},
925 {"collections.group.parts.part.description.params.double", st_collections_group_parts_part_description_params_double},
926 {"collections.group.parts.part.description.params.string", st_collections_group_parts_part_description_params_string},
927 {"collections.group.parts.part.description.params.bool", st_collections_group_parts_part_description_params_bool},
928 {"collections.group.parts.part.description.params.choice", st_collections_group_parts_part_description_params_choice},
929 {"collections.group.parts.part.description.params.*", st_collections_group_parts_part_description_params_smart},
930 {"collections.group.parts.part.description.vector.frame", st_collections_group_parts_part_description_vector_frame},
931 IMAGE_STATEMENTS("collections.group.parts.part.description.")
932 {
933 "collections.group.parts.part.description.font", st_fonts_font
934 }, /* dup */
935 FONT_STYLE_CC_STATEMENTS("collections.group.parts.part.description.")
936 TEXT_CLASS_STATEMENTS("collections.group.parts.part.description.")
937 SIZE_CLASS_STATEMENTS("collections.group.parts.part.description.")
938 #ifdef HAVE_EPHYSICS
939 {
940 "collections.group.physics.world.gravity", st_collections_group_physics_world_gravity
941 },
942 {"collections.group.physics.world.rate", st_collections_group_physics_world_rate},
943 {"collections.group.physics.world.z", st_collections_group_physics_world_z},
944 {"collections.group.physics.world.depth", st_collections_group_physics_world_depth},
945 #endif
946 FILTERS_STATEMENTS("collections.group.") /* dup */
947 PROGRAM_STATEMENTS("collections.group.parts.part.description")
948 PROGRAM_STATEMENTS("collections.group.parts.part")
949 PROGRAM_STATEMENTS("collections.group.parts")
950 PROGRAM_STATEMENTS("collections.group")
951 };
952
953 /** @edcsection{lazedc,
954 * LazEDC} */
955
956 /** @edcsubsection{lazedc_intro,
957 * LazEDC Intro} */
958
959 /**
960 @page edcref
961 @block
962 LazEDC
963 @context
964 ..
965 collections.group { "test";
966 parts {
967 rect { "clip"; }
968 rect { "test"; nomouse; repeat; precise;
969 clip: "clip";
970 desc { "default";
971 color: 255 0 0 255;
972 rel2.relative: 0.5 1;
973 }
974 }
975 rect { "test2"; inherit: "test";
976 clip: "clip";
977 desc { "default";
978 rel1.relative: 0.5 0;
979 rel2.relative: 1 1;
980 }
981 desc { "t2";
982 inherit: "default";
983 color: 0 255 0 255;
984 }
985 desc { "t3";
986 inherit; // "default" can be omitted.
987 color: 0 0 255 255;
988 }
989 }
990 program { signal: "load"; name: "start";
991 sequence {
992 action: STATE_SET "t2";
993 target: "test2";
994 transition: LINEAR 0.6;
995 in: 0.5 0;
996 action: STATE_SET "t3";
997 target: "test2";
998 transition: LINEAR 0.3;
999 name: "del";
1000 }
1001 }
1002 }
1003 }
1004 ..
1005 @description
1006 LazEDC is an advanced form of EDC which allows the developer to
1007 leave out or shorten various forms. Parts can be created by using
1008 their type names, and the "name" and "state" keywords can be omitted entirely.
1009 Additionally, default description blocks will be automatically created with default
1010 values even if the description isn't explicitly specified.
1011 @note Failing to use quotes for block names will trigger syntax errors
1012 if a block name is the same as an existing EDC keyword.
1013 @since 1.10
1014 @endblock
1015 */
1016
1017 /** @edcsubsection{lazedc_synonyms,
1018 * LazEDC Synonyms} */
1019
1020 /**
1021 @page edcref
1022 @block
1023 Synonyms
1024 @context
1025 group {
1026 parts {
1027 part {
1028 before -> insert_before
1029 after -> insert_after
1030 ignore -> ignore_flags
1031 mask -> mask_flags
1032 pointer -> pointer_mode
1033 alt_font -> use_alternate_font_metrics
1034 clip -> clip_to
1035 desc {
1036 clip -> clip_to
1037 }
1038 }
1039 }
1040 }
1041 color_class {
1042 desc -> description
1043 @since 1.14
1044 }
1045
1046 @description
1047 These statements on the left are identical to their original keywords on the right.
1048 @since 1.10
1049 @endblock
1050 */
1051
1052 New_Statement_Handler statement_handlers_short[] =
1053 {
1054 {"collections.group.parts.part.before", st_collections_group_parts_part_insert_before},
1055 {"collections.group.parts.part.after", st_collections_group_parts_part_insert_after},
1056 {"collections.group.parts.part.ignore", st_collections_group_parts_part_ignore_flags},
1057 {"collections.group.parts.part.mask", st_collections_group_parts_part_mask_flags},
1058 {"collections.group.parts.part.pointer", st_collections_group_parts_part_pointer_mode},
1059 {"collections.group.parts.part.alt_font", st_collections_group_parts_part_use_alternate_font_metrics},
1060 {"collections.group.parts.part.clip", st_collections_group_parts_part_clip_to_id},
1061 {"collections.group.parts.part.description.clip", st_collections_group_parts_part_description_clip_to_id},
1062 };
1063
1064 /** @edcsubsection{lazedc_shorthand,
1065 * LazEDC Shorthand} */
1066
1067 /**
1068 @page edcref
1069 @block
1070 Shorthand
1071 @context
1072 group {
1073 broadcast; -> broadcast_signal: 1;
1074 nobroadcast; -> broadcast_signal: 0;
1075 mouse; -> mouse_events: 1;
1076 nomouse; -> mouse_events: 0;
1077 inherit_script; -> inherit_script: 1;
1078 noinherit_script; -> inherit_script: 0;
1079 parts {
1080 part {
1081 mouse; -> mouse_events: 1;
1082 nomouse; -> mouse_events: 0;
1083 repeat; -> repeat_events: 1;
1084 norepeat; -> repeat_events: 0;
1085 precise; -> precise_is_inside: 1;
1086 noprecise; -> precise_is_inside: 0;
1087 render; -> no_render: 0;
1088 norender; -> no_render: 1;
1089 required; -> required: 1;
1090 norequired; -> required: 0;
1091 scale; -> scale: 1;
1092 noscale; -> scale: 0;
1093 desc {
1094 vis; -> visible: 1;
1095 hid; -> visible: 0;
1096 offscale; -> offset_scale: 1;
1097 }
1098 }
1099 }
1100 }
1101
1102 @description
1103 These statements on the left have the same meaning as statements on the right,
1104 but they are shorter.
1105 @since 1.10
1106 @endblock
1107 */
1108 New_Statement_Handler statement_handlers_short_single[] =
1109 {
1110 {"collections.group.parts.part.mouse", st_collections_group_parts_part_mouse},
1111 {"collections.group.parts.part.nomouse", st_collections_group_parts_part_nomouse},
1112 {"collections.group.parts.part.repeat", st_collections_group_parts_part_repeat},
1113 {"collections.group.parts.part.norepeat", st_collections_group_parts_part_norepeat},
1114 {"collections.group.parts.part.precise", st_collections_group_parts_part_precise},
1115 {"collections.group.parts.part.noprecise", st_collections_group_parts_part_noprecise},
1116 {"collections.group.parts.part.scale", st_collections_group_parts_part_scale},
1117 {"collections.group.parts.part.noscale", st_collections_group_parts_part_noscale},
1118 {"collections.group.parts.part.render", st_collections_group_parts_part_render},
1119 {"collections.group.parts.part.norender", st_collections_group_parts_part_no_render},
1120 {"collections.group.parts.part.required", st_collections_group_parts_part_required},
1121 {"collections.group.parts.part.norequired", st_collections_group_parts_part_norequired},
1122 {"collections.group.parts.part.description.vis", st_collections_group_parts_part_description_vis},
1123 {"collections.group.parts.part.description.hid", st_collections_group_parts_part_description_hid},
1124 {"collections.group.parts.part.description.offscale", st_collections_group_parts_part_description_offset_scale},
1125 {"collections.group.mouse", st_collections_group_mouse},
1126 {"collections.group.nomouse", st_collections_group_nomouse},
1127 {"collections.group.broadcast", st_collections_group_broadcast},
1128 {"collections.group.nobroadcast", st_collections_group_nobroadcast},
1129 {"collections.group.inherit_script", st_collections_group_inherit_script},
1130 {"collections.group.noinherit_script", st_collections_group_noinherit_script},
1131 {"collections.group.parts.part.description.inherit", st_collections_group_parts_part_description_inherit},
1132 };
1133
1134 /** @edcsubsection{lazedc_external_params,
1135 * LazEDC Group.Parts.External.Desc.Params} */
1136
1137 /**
1138 @page edcref
1139 @block
1140 params
1141 @context
1142 ...
1143 external {
1144 desc { "default";
1145 params {
1146 number: 10; -> int: "number" 10;
1147 number2: 1.1; -> double: "number2" 1.1;
1148 label: "OK"; -> string: "label" "OK";
1149 check: true; -> bool: "check" 1;
1150 check2: false; -> bool: "check2" 0;
1151 text_wrap: mixed; -> choice: "text_wrap" "mixed";
1152 }
1153 }
1154 }
1155 ...
1156 @description
1157 The name of parameter can be used as a statement keyword in params block.
1158 The type of parameter is determined automatically by the value,
1159 so it should follow the next rules.
1160 Number without decimal point is considered as an integer.
1161 Number with decimal point is considered as a double.
1162 Double-quoted string is considered as a string.
1163 'true' or 'false' without quotes is considred as a boolean.
1164 String without quotes except for 'true' or 'false' is considered as a choice.
1165 @since 1.18
1166 @endblock
1167 */
1168 static Edje_External_Param_Type
_parse_external_param_type(char * token)1169 _parse_external_param_type(char *token)
1170 {
1171 Eina_Bool num, point;
1172 char *s;
1173
1174 if (param_had_quote(0))
1175 return EDJE_EXTERNAL_PARAM_TYPE_STRING;
1176
1177 num = EINA_TRUE;
1178 point = EINA_FALSE;
1179 s = token;
1180
1181 while (*s)
1182 {
1183 if ((*s < '0') || (*s > '9'))
1184 {
1185 if ((!point) && (*s == '.'))
1186 {
1187 point = EINA_TRUE;
1188 }
1189 else
1190 {
1191 num = EINA_FALSE;
1192 break;
1193 }
1194 }
1195 s++;
1196 }
1197
1198 if (num)
1199 {
1200 if (!point)
1201 return EDJE_EXTERNAL_PARAM_TYPE_INT;
1202 else
1203 return EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1204 }
1205 else
1206 {
1207 if (!strcmp(token, "true") || !strcmp(token, "false"))
1208 return EDJE_EXTERNAL_PARAM_TYPE_BOOL;
1209 else
1210 return EDJE_EXTERNAL_PARAM_TYPE_CHOICE;
1211 }
1212 }
1213
1214 static void
st_collections_group_parts_part_description_params_smart(void)1215 st_collections_group_parts_part_description_params_smart(void)
1216 {
1217 Edje_Part_Description_External *ed;
1218 Edje_External_Param *param;
1219 Eina_List *l;
1220 char *last, *name, *token;
1221 int found = 0;
1222
1223 check_arg_count(1);
1224
1225 if (current_part->type != EDJE_PART_TYPE_EXTERNAL)
1226 {
1227 ERR("parse error %s:%i. params in non-EXTERNAL part.",
1228 file_in, line - 1);
1229 exit(-1);
1230 }
1231
1232 ed = (Edje_Part_Description_External *)current_desc;
1233
1234 last = eina_list_last_data_get(stack);
1235 if (!strncmp(last, "params.", strlen("params.")))
1236 name = strdup(last + strlen("params."));
1237 else
1238 name = strdup(last);
1239
1240 /* if a param with this name already exists, overwrite it */
1241 EINA_LIST_FOREACH(ed->external_params, l, param)
1242 {
1243 if (!strcmp(param->name, name))
1244 {
1245 found = 1;
1246 free(name);
1247 break;
1248 }
1249 }
1250
1251 if (!found)
1252 {
1253 param = mem_alloc(SZ(Edje_External_Param));
1254 param->name = name;
1255 }
1256
1257 token = parse_str(0);
1258
1259 param->type = _parse_external_param_type(token);
1260 param->i = 0;
1261 param->d = 0;
1262 param->s = NULL;
1263
1264 switch (param->type)
1265 {
1266 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
1267 if (!strcmp(token, "true"))
1268 param->i = 1;
1269 else if (!strcmp(token, "false"))
1270 param->i = 0;
1271 break;
1272
1273 case EDJE_EXTERNAL_PARAM_TYPE_INT:
1274 param->i = parse_int(0);
1275 break;
1276
1277 case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
1278 param->d = parse_float(0);
1279 break;
1280
1281 case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
1282 case EDJE_EXTERNAL_PARAM_TYPE_STRING:
1283 param->s = parse_str(0);
1284 break;
1285
1286 default:
1287 ERR("parse error %s:%i. Invalid param type.",
1288 file_in, line - 1);
1289 break;
1290 }
1291
1292 if (!found)
1293 ed->external_params = eina_list_append(ed->external_params, param);
1294
1295 free(token);
1296 }
1297
1298 #define PROGRAM_OBJECTS(PREFIX) \
1299 {PREFIX ".program", ob_collections_group_programs_program}, /* dup */ \
1300 {PREFIX ".program.script", ob_collections_group_programs_program_script}, /* dup */ \
1301 {PREFIX ".program.sequence.script", ob_collections_group_programs_program_script}, /* dup */ \
1302 {PREFIX ".program.sequence", ob_collections_group_programs_program_sequence}, /* dup */ \
1303 {PREFIX ".programs", NULL}, /* dup */ \
1304 {PREFIX ".programs.set", ob_images_set}, /* dup */ \
1305 {PREFIX ".programs.set.image", ob_images_set_image}, /* dup */ \
1306 {PREFIX ".programs.images", NULL}, /* dup */ \
1307 {PREFIX ".programs.images.set", ob_images_set}, /* dup */ \
1308 {PREFIX ".programs.images.set.image", ob_images_set_image}, /* dup */ \
1309 {PREFIX ".programs.fonts", NULL}, /* dup */ \
1310 {PREFIX ".programs.program", ob_collections_group_programs_program}, /* dup */ \
1311 {PREFIX ".programs.program.script", ob_collections_group_programs_program_script}, /* dup */ \
1312 {PREFIX ".programs.program.sequence", ob_collections_group_programs_program_sequence}, /* dup */ \
1313 {PREFIX ".programs.program.sequence.script", ob_collections_group_programs_program_script}, /* dup */ \
1314 {PREFIX ".programs.script", ob_collections_group_script}, /* dup */ \
1315 {PREFIX ".script", ob_collections_group_script}, /* dup */
1316
1317 New_Object_Handler object_handlers[] =
1318 {
1319 {"externals", NULL},
1320 {"images", NULL},
1321 {"images.set", ob_images_set},
1322 {"images.set.image", ob_images_set_image},
1323 {"fonts", NULL},
1324 {"data", NULL},
1325 {"styles", NULL},
1326 {"styles.style", ob_styles_style},
1327 {"color_tree", ob_color_tree},
1328 {"color_classes", NULL},
1329 {"color_classes.color_class", ob_color_class},
1330 {"text_classes", NULL},
1331 {"text_classes.text_class", ob_text_class},
1332 {"size_classes", NULL},
1333 {"size_classes.size_class", ob_size_class},
1334 {"spectra", NULL},
1335 {"filters", NULL},
1336 {"filters.filter", ob_filters_filter},
1337 {"filters.filter.script", ob_filters_filter_script},
1338 {"collections", ob_collections},
1339 {"collections.externals", NULL}, /* dup */
1340 {"collections.set", ob_images_set}, /* dup */
1341 {"collections.set.image", ob_images_set_image}, /* dup */
1342 {"collections.images", NULL}, /* dup */
1343 {"collections.images.set", ob_images_set}, /* dup */
1344 {"collections.images.set.image", ob_images_set_image}, /* dup */
1345 {"collections.fonts", NULL}, /* dup */
1346 {"collections.styles", NULL}, /* dup */
1347 {"collections.styles.style", ob_styles_style}, /* dup */
1348 {"collections.color_tree", ob_color_tree}, /* dup */
1349 {"collections.color_classes", NULL}, /* dup */
1350 {"collections.color_classes.color_class", ob_color_class}, /* dup */
1351 {"collections.text_classes", NULL},
1352 {"collections.text_classes.text_class", ob_text_class}, /* dup */
1353 {"collections.size_classes", NULL}, /* dup */
1354 {"collections.size_classes.size_class", ob_size_class}, /* dup */
1355 {"collections.sounds", NULL},
1356 {"collections.group.sounds", NULL}, /* dup */
1357 {"collections.sounds.sample", NULL},
1358 {"collections.translation", NULL},
1359 {"collections.translation.file", NULL},
1360 {"collections.group.translation", NULL}, /*dup*/
1361 {"collections.group.translation.file", NULL}, /*dup*/
1362 {"collections.group.sounds.sample", NULL}, /* dup */
1363 {"collections.vibrations", NULL},
1364 {"collections.group.vibrations", NULL}, /* dup */
1365 {"collections.vibrations.sample", NULL},
1366 {"collections.filters", NULL},
1367 {"collections.filters.filter", ob_filters_filter}, /* dup */
1368 {"collections.filters.filter.script", ob_filters_filter_script}, /* dup */
1369 {"collections.group.vibrations.sample", NULL}, /* dup */
1370 {"collections.group", ob_collections_group},
1371 {"collections.group.data", NULL},
1372 {"collections.group.limits", NULL},
1373 {"collections.group.script", ob_collections_group_script},
1374 {"collections.group.lua_script", ob_collections_group_lua_script},
1375 {"collections.group.externals", NULL}, /* dup */
1376 {"collections.group.set", ob_images_set}, /* dup */
1377 {"collections.group.set.image", ob_images_set_image}, /* dup */
1378 {"collections.group.images", NULL}, /* dup */
1379 {"collections.group.images.set", ob_images_set}, /* dup */
1380 {"collections.group.images.set.image", ob_images_set_image}, /* dup */
1381 {"collections.group.fonts", NULL}, /* dup */
1382 {"collections.group.styles", NULL}, /* dup */
1383 {"collections.group.styles.style", ob_styles_style}, /* dup */
1384 {"collections.group.color_tree", ob_color_tree}, /* dup */
1385 {"collections.group.color_classes", NULL}, /* dup */
1386 {"collections.group.color_classes.color_class", ob_color_class}, /* dup */
1387 {"collections.group.text_classes", NULL},
1388 {"collections.group.text_classes.text_class", ob_text_class}, /* dup */
1389 {"collections.group.size_classes", NULL}, /* dup */
1390 {"collections.group.size_classes.size_class", ob_size_class}, /* dup */
1391 {"collections.group.filters", NULL},
1392 {"collections.group.filters.filter", ob_filters_filter}, /* dup */
1393 {"collections.group.filters.filter.script", ob_filters_filter_script}, /* dup */
1394 {"collections.group.parts", NULL},
1395 {"collections.group.parts.set", ob_images_set}, /* dup */
1396 {"collections.group.parts.set.image", ob_images_set_image}, /* dup */
1397 {"collections.group.parts.images", NULL}, /* dup */
1398 {"collections.group.parts.images.set", ob_images_set}, /* dup */
1399 {"collections.group.parts.images.set.image", ob_images_set_image}, /* dup */
1400 {"collections.group.parts.fonts", NULL}, /* dup */
1401 {"collections.group.parts.styles", NULL}, /* dup */
1402 {"collections.group.parts.styles.style", ob_styles_style}, /* dup */
1403 {"collections.group.parts.color_classes", NULL}, /* dup */
1404 {"collections.group.parts.color_classes.color_class", ob_color_class}, /* dup */
1405 {"collections.group.parts.text_classes", NULL},
1406 {"collections.group.parts.text_classes.text_class", ob_text_class}, /* dup */
1407 {"collections.group.parts.size_classes", NULL}, /* dup */
1408 {"collections.group.parts.size_classes.size_class", ob_size_class}, /* dup */
1409 {"collections.group.parts.part", ob_collections_group_parts_part},
1410 {"collections.group.parts.part.dragable", NULL},
1411 {"collections.group.parts.part.set", ob_images_set}, /* dup */
1412 {"collections.group.parts.part.set.image", ob_images_set_image}, /* dup */
1413 {"collections.group.parts.part.images", NULL}, /* dup */
1414 {"collections.group.parts.part.images.set", ob_images_set}, /* dup */
1415 {"collections.group.parts.part.images.set.image", ob_images_set_image}, /* dup */
1416 {"collections.group.parts.part.fonts", NULL}, /* dup */
1417 {"collections.group.parts.part.styles", NULL}, /* dup */
1418 {"collections.group.parts.part.styles.style", ob_styles_style}, /* dup */
1419 {"collections.group.parts.part.color_classes", NULL}, /* dup */
1420 {"collections.group.parts.part.color_classes.color_class", ob_color_class}, /* dup */
1421 {"collections.group.parts.part.text_classes", NULL},
1422 {"collections.group.parts.part.text_classes.text_class", ob_text_class}, /* dup */
1423 {"collections.group.parts.part.size_classes", NULL}, /* dup */
1424 {"collections.group.parts.part.size_classes.size_class", ob_size_class}, /* dup */
1425 {"collections.group.parts.part.box", NULL},
1426 {"collections.group.parts.part.box.items", NULL},
1427 {"collections.group.parts.part.box.items.item", ob_collections_group_parts_part_box_items_item},
1428 {"collections.group.parts.part.table", NULL},
1429 {"collections.group.parts.part.table.items", NULL},
1430 {"collections.group.parts.part.table.items.item", ob_collections_group_parts_part_box_items_item}, /* dup */
1431 {"collections.group.parts.part.description", ob_collections_group_parts_part_description},
1432 {"collections.group.parts.part.description.link", ob_collections_group_parts_part_description_link},
1433 {"collections.group.parts.part.description.rel1", NULL},
1434 {"collections.group.parts.part.description.rel2", NULL},
1435 {"collections.group.parts.part.description.anchors", NULL},
1436 {"collections.group.parts.part.description.image", NULL}, /* dup */
1437 {"collections.group.parts.part.description.image.set", ob_images_set}, /* dup */
1438 {"collections.group.parts.part.description.image.set.image", ob_images_set_image}, /* dup */
1439 {"collections.group.parts.part.description.image.images", NULL}, /* dup */
1440 {"collections.group.parts.part.description.image.images.set", ob_images_set}, /* dup */
1441 {"collections.group.parts.part.description.image.images.set.image", ob_images_set_image}, /* dup */
1442 {"collections.group.parts.part.description.fill", NULL},
1443 {"collections.group.parts.part.description.fill.origin", NULL},
1444 {"collections.group.parts.part.description.fill.size", NULL},
1445 {"collections.group.parts.part.description.text", NULL},
1446 {"collections.group.parts.part.description.text.fonts", NULL}, /* dup */
1447 {"collections.group.parts.part.description.images", NULL}, /* dup */
1448 {"collections.group.parts.part.description.images.set", ob_images_set}, /* dup */
1449 {"collections.group.parts.part.description.images.set.image", ob_images_set_image}, /* dup */
1450 {"collections.group.parts.part.description.fonts", NULL}, /* dup */
1451 {"collections.group.parts.part.description.styles", NULL}, /* dup */
1452 {"collections.group.parts.part.description.styles.style", ob_styles_style}, /* dup */
1453 {"collections.group.parts.part.description.box", NULL},
1454 {"collections.group.parts.part.description.table", NULL},
1455 {"collections.group.parts.part.description.filter", NULL},
1456 {"collections.group.parts.part.description.proxy", NULL},
1457 #ifdef HAVE_EPHYSICS
1458 {"collections.group.parts.part.description.physics", NULL},
1459 {"collections.group.parts.part.description.physics.movement_freedom", NULL},
1460 {"collections.group.parts.part.description.physics.faces", NULL},
1461 {"collections.group.parts.part.description.physics.faces.face", st_collections_group_parts_part_description_physics_face},
1462 #endif
1463 {"collections.group.parts.part.description.map", NULL},
1464 {"collections.group.parts.part.description.map.rotation", NULL},
1465 {"collections.group.parts.part.description.map.zoom", NULL},
1466 {"collections.group.parts.part.description.perspective", NULL},
1467 {"collections.group.parts.part.description.params", NULL},
1468 {"collections.group.parts.part.description.vector", NULL},
1469 {"collections.group.parts.part.description.color_classes", NULL}, /* dup */
1470 {"collections.group.parts.part.description.color_classes.color_class", ob_color_class}, /* dup */
1471 {"collections.group.parts.part.description.text_classes", NULL}, /* dup */
1472 {"collections.group.parts.part.description.text_classes.text_class", ob_text_class}, /* dup */
1473 {"collections.group.parts.part.description.size_classes", NULL}, /* dup */
1474 {"collections.group.parts.part.description.size_classes.size_class", ob_size_class}, /* dup */
1475 #ifdef HAVE_EPHYSICS
1476 {"collections.group.physics", NULL},
1477 {"collections.group.physics.world", NULL},
1478 #endif
1479 PROGRAM_OBJECTS("collections.group.parts.part.description")
1480 PROGRAM_OBJECTS("collections.group.parts.part")
1481 PROGRAM_OBJECTS("collections.group.parts")
1482 PROGRAM_OBJECTS("collections.group")
1483 };
1484
1485 /** @edcsubsection{lazedc_blocks,
1486 * LazEDC Blocks} */
1487
1488 /**
1489 @page edcref
1490 @block
1491 Blocks
1492 @context
1493 parts {
1494 rect{}
1495 text{}
1496 image{}
1497 swallow{}
1498 textblock{}
1499 group{}
1500 box{}
1501 table{}
1502 external{}
1503 proxy{}
1504 spacer{}
1505 snapshot{}
1506 vector{}
1507 part {
1508 desc {
1509 }
1510 }
1511 }
1512
1513 @description
1514 Lowercase part types can be specified as blocks with the same effect as part { type: TYPE; }
1515 The "description" block can also be shortened to "desc".
1516
1517 @since 1.10
1518 @endblock
1519 */
1520 New_Object_Handler object_handlers_short[] =
1521 {
1522 {"collections.group.parts.rect", ob_collections_group_parts_part_short},
1523 {"collections.group.parts.text", ob_collections_group_parts_part_short},
1524 {"collections.group.parts.image", ob_collections_group_parts_part_short},
1525 {"collections.group.parts.swallow", ob_collections_group_parts_part_short},
1526 {"collections.group.parts.textblock", ob_collections_group_parts_part_short},
1527 {"collections.group.parts.group", ob_collections_group_parts_part_short},
1528 {"collections.group.parts.box", ob_collections_group_parts_part_short},
1529 {"collections.group.parts.table", ob_collections_group_parts_part_short},
1530 {"collections.group.parts.external", ob_collections_group_parts_part_short},
1531 {"collections.group.parts.proxy", ob_collections_group_parts_part_short},
1532 {"collections.group.parts.spacer", ob_collections_group_parts_part_short},
1533 {"collections.group.parts.snapshot", ob_collections_group_parts_part_short},
1534 {"collections.group.parts.part.desc", ob_collections_group_parts_part_desc},
1535 {"collections.group.parts.vector", ob_collections_group_parts_part_short},
1536 };
1537
1538 New_Nested_Handler nested_handlers[] = {
1539 {"collections.group.parts", "part", NULL, edje_cc_handlers_hierarchy_pop }
1540 };
1541
1542 New_Nested_Handler nested_handlers_short[] = {
1543 {"collections.group.parts", "rect", NULL, edje_cc_handlers_hierarchy_pop },
1544 {"collections.group.parts", "text", NULL, edje_cc_handlers_hierarchy_pop },
1545 {"collections.group.parts", "image", NULL, edje_cc_handlers_hierarchy_pop },
1546 {"collections.group.parts", "swallow", NULL, edje_cc_handlers_hierarchy_pop },
1547 {"collections.group.parts", "textblock", NULL, edje_cc_handlers_hierarchy_pop },
1548 {"collections.group.parts", "group", NULL, edje_cc_handlers_hierarchy_pop },
1549 {"collections.group.parts", "box", NULL, edje_cc_handlers_hierarchy_pop },
1550 {"collections.group.parts", "table", NULL, edje_cc_handlers_hierarchy_pop },
1551 {"collections.group.parts", "external", NULL, edje_cc_handlers_hierarchy_pop },
1552 {"collections.group.parts", "proxy", NULL, edje_cc_handlers_hierarchy_pop },
1553 {"collections.group.parts", "spacer", NULL, edje_cc_handlers_hierarchy_pop },
1554 {"collections.group.parts", "vector", NULL, edje_cc_handlers_hierarchy_pop },
1555 };
1556
1557 /*****/
1558
1559 int
object_handler_num(void)1560 object_handler_num(void)
1561 {
1562 return sizeof(object_handlers) / sizeof (New_Object_Handler);
1563 }
1564
1565 int
object_handler_short_num(void)1566 object_handler_short_num(void)
1567 {
1568 return sizeof(object_handlers_short) / sizeof (New_Object_Handler);
1569 }
1570
1571 int
statement_handler_num(void)1572 statement_handler_num(void)
1573 {
1574 return sizeof(statement_handlers) / sizeof (New_Object_Handler);
1575 }
1576
1577 int
statement_handler_short_num(void)1578 statement_handler_short_num(void)
1579 {
1580 return sizeof(statement_handlers_short) / sizeof (New_Object_Handler);
1581 }
1582
1583 int
statement_handler_short_single_num(void)1584 statement_handler_short_single_num(void)
1585 {
1586 return sizeof(statement_handlers_short_single) / sizeof (New_Object_Handler);
1587 }
1588
1589 int
nested_handler_num(void)1590 nested_handler_num(void)
1591 {
1592 return sizeof(nested_handlers) / sizeof (New_Nested_Handler);
1593 }
1594
1595 int
nested_handler_short_num(void)1596 nested_handler_short_num(void)
1597 {
1598 return sizeof(nested_handlers_short) / sizeof (New_Nested_Handler);
1599 }
1600
1601 static void
_edje_part_description_fill(Edje_Part_Description_Spec_Fill * fill)1602 _edje_part_description_fill(Edje_Part_Description_Spec_Fill *fill)
1603 {
1604 fill->smooth = 1;
1605 fill->pos_rel_x = FROM_DOUBLE(0.0);
1606 fill->pos_abs_x = 0;
1607 fill->rel_x = FROM_DOUBLE(1.0);
1608 fill->abs_x = 0;
1609 fill->pos_rel_y = FROM_DOUBLE(0.0);
1610 fill->pos_abs_y = 0;
1611 fill->rel_y = FROM_DOUBLE(1.0);
1612 fill->abs_y = 0;
1613 fill->type = EDJE_FILL_TYPE_SCALE;
1614 }
1615
1616 static void
_edje_part_description_image_remove(Edje_Part_Description_Image * ed)1617 _edje_part_description_image_remove(Edje_Part_Description_Image *ed)
1618 {
1619 unsigned int j;
1620
1621 if (!ed) return;
1622
1623 data_queue_image_remove(&(ed->image.id), &(ed->image.set));
1624
1625 for (j = 0; j < ed->image.tweens_count; ++j)
1626 data_queue_image_remove(&(ed->image.tweens[j]->id),
1627 &(ed->image.tweens[j]->set));
1628 }
1629
1630 void
part_description_image_cleanup(Edje_Part * ep)1631 part_description_image_cleanup(Edje_Part *ep)
1632 {
1633 Edje_Part_Description_Image *ed;
1634 unsigned int j;
1635
1636 if (ep->type != EDJE_PART_TYPE_IMAGE)
1637 return;
1638
1639 ed = (Edje_Part_Description_Image *)ep->default_desc;
1640 _edje_part_description_image_remove(ed);
1641
1642 for (j = 0; j < ep->other.desc_count; j++)
1643 {
1644 ed = (Edje_Part_Description_Image *)ep->other.desc[j];
1645 _edje_part_description_image_remove(ed);
1646 }
1647 }
1648
1649 static Edje_Part_Description_Common *
_edje_part_description_alloc(unsigned char type,const char * collection,const char * part)1650 _edje_part_description_alloc(unsigned char type, const char *collection, const char *part)
1651 {
1652 Edje_Part_Description_Common *result = NULL;
1653
1654 switch (type)
1655 {
1656 case EDJE_PART_TYPE_SPACER:
1657 case EDJE_PART_TYPE_RECTANGLE:
1658 case EDJE_PART_TYPE_SWALLOW:
1659 case EDJE_PART_TYPE_GROUP:
1660 result = mem_alloc(SZ(Edje_Part_Description_Common));
1661 break;
1662
1663 case EDJE_PART_TYPE_TEXT:
1664 case EDJE_PART_TYPE_TEXTBLOCK:
1665 {
1666 Edje_Part_Description_Text *ed;
1667
1668 ed = mem_alloc(SZ(Edje_Part_Description_Text));
1669
1670 ed->text.color3.r = 0;
1671 ed->text.color3.g = 0;
1672 ed->text.color3.b = 0;
1673 ed->text.color3.a = 128;
1674 ed->text.align.x = FROM_DOUBLE(0.5);
1675 ed->text.align.y = FROM_DOUBLE(0.5);
1676 ed->text.id_source = -1;
1677 ed->text.id_text_source = -1;
1678
1679 result = &ed->common;
1680 break;
1681 }
1682
1683 case EDJE_PART_TYPE_IMAGE:
1684 {
1685 Edje_Part_Description_Image *ed;
1686
1687 ed = mem_alloc(SZ(Edje_Part_Description_Image));
1688
1689 ed->image.id = -1;
1690
1691 _edje_part_description_fill(&ed->image.fill);
1692
1693 result = &ed->common;
1694 break;
1695 }
1696
1697 case EDJE_PART_TYPE_SNAPSHOT:
1698 {
1699 Edje_Part_Description_Snapshot *ed;
1700
1701 ed = mem_alloc(SZ(Edje_Part_Description_Snapshot));
1702
1703 result = &ed->common;
1704 break;
1705 }
1706
1707 case EDJE_PART_TYPE_PROXY:
1708 {
1709 Edje_Part_Description_Proxy *ed;
1710
1711 ed = mem_alloc(SZ(Edje_Part_Description_Proxy));
1712
1713 ed->proxy.id = -1;
1714 ed->proxy.source_visible = EINA_TRUE;
1715 ed->proxy.source_clip = EINA_TRUE;
1716 _edje_part_description_fill(&ed->proxy.fill);
1717
1718 result = &ed->common;
1719 break;
1720 }
1721
1722 case EDJE_PART_TYPE_BOX:
1723 {
1724 Edje_Part_Description_Box *ed;
1725
1726 ed = mem_alloc(SZ(Edje_Part_Description_Box));
1727
1728 ed->box.layout = NULL;
1729 ed->box.alt_layout = NULL;
1730 ed->box.align.x = FROM_DOUBLE(0.5);
1731 ed->box.align.y = FROM_DOUBLE(0.5);
1732 ed->box.padding.x = 0;
1733 ed->box.padding.y = 0;
1734
1735 result = &ed->common;
1736 break;
1737 }
1738
1739 case EDJE_PART_TYPE_TABLE:
1740 {
1741 Edje_Part_Description_Table *ed;
1742
1743 ed = mem_alloc(SZ(Edje_Part_Description_Table));
1744
1745 ed->table.homogeneous = EDJE_OBJECT_TABLE_HOMOGENEOUS_NONE;
1746 ed->table.align.x = FROM_DOUBLE(0.5);
1747 ed->table.align.y = FROM_DOUBLE(0.5);
1748 ed->table.padding.x = 0;
1749 ed->table.padding.y = 0;
1750
1751 result = &ed->common;
1752 break;
1753 }
1754
1755 case EDJE_PART_TYPE_EXTERNAL:
1756 {
1757 Edje_Part_Description_External *ed;
1758
1759 ed = mem_alloc(SZ(Edje_Part_Description_External));
1760
1761 ed->external_params = NULL;
1762
1763 result = &ed->common;
1764 break;
1765 }
1766
1767 case EDJE_PART_TYPE_VECTOR:
1768 {
1769 Edje_Part_Description_Vector *ed;
1770
1771 ed = mem_alloc(SZ(Edje_Part_Description_Vector));
1772
1773 result = &ed->common;
1774 break;
1775 }
1776 }
1777
1778 if (!result)
1779 {
1780 ERR("Unknown type %i of part %s in collection %s.",
1781 type, part, collection);
1782 exit(-1);
1783 }
1784
1785 #ifdef HAVE_EPHYSICS
1786 result->physics.mass = FROM_DOUBLE(1.0);
1787 result->physics.friction = FROM_DOUBLE(0.5);
1788 result->physics.sleep.linear = FROM_DOUBLE(24);
1789 result->physics.sleep.angular = FROM_DOUBLE(57.29);
1790 result->physics.hardness = FROM_DOUBLE(1.0);
1791 result->physics.ignore_part_pos = 1;
1792 result->physics.mov_freedom.lin.x = 1;
1793 result->physics.mov_freedom.lin.y = 1;
1794 result->physics.mov_freedom.ang.z = 1;
1795 result->physics.z = -15;
1796 result->physics.depth = 30;
1797 #endif
1798
1799 result->clip_to_id = -1;
1800 return result;
1801 }
1802
1803 static void
_edje_program_check(const char * name,Edje_Program * me,Edje_Program ** pgrms,unsigned int count)1804 _edje_program_check(const char *name, Edje_Program *me, Edje_Program **pgrms, unsigned int count)
1805 {
1806 Edje_Part_Collection *pc;
1807 unsigned int i;
1808 Edje_Program_Parser *epp;
1809
1810 pc = eina_list_data_get(eina_list_last(edje_collections));
1811
1812 for (i = 0; i < count; ++i)
1813 if (pgrms[i]->name)
1814 if (pgrms[i] != me && (!strcmp(name, pgrms[i]->name)))
1815 {
1816 epp = (Edje_Program_Parser *)pgrms[i];
1817 if (!epp->can_override)
1818 {
1819 ERR("parse error %s:%i. There is already a program of the name %s",
1820 file_in, line - 1, name);
1821 exit(-1);
1822 }
1823 else
1824 {
1825 _edje_program_remove(pc, me);
1826 current_program = pgrms[i];
1827 if (pgrms[i]->action == EDJE_ACTION_TYPE_SCRIPT)
1828 copied_program_anonymous_lookup_delete(pc, &pgrms[i]->id);
1829 epp->can_override = EINA_FALSE;
1830 return;
1831 }
1832 }
1833 }
1834
1835 static void
_edje_program_copy(Edje_Program * ep,Edje_Program * ep2)1836 _edje_program_copy(Edje_Program *ep, Edje_Program *ep2)
1837 {
1838 Edje_Part_Collection *pc;
1839 Edje_Program_Target *et, *et2;
1840 Edje_Program_After *pa, *pa2;
1841 Edje_Program_Parser *epp;
1842 Eina_List *l;
1843 char *name;
1844 char *copy;
1845
1846 pc = eina_list_data_get(eina_list_last(edje_collections));
1847
1848 ep->name = STRDUP(ep2->name);
1849
1850 _edje_program_remove(pc, current_program);
1851 ep->signal = STRDUP(ep2->signal);
1852 ep->source = STRDUP(ep2->source);
1853 _edje_program_insert(pc, current_program);
1854
1855 ep->filter.part = STRDUP(ep2->filter.part);
1856 ep->filter.state = STRDUP(ep2->filter.state);
1857 ep->in.from = ep2->in.from;
1858 ep->in.range = ep2->in.range;
1859 ep->action = ep2->action;
1860 ep->seat = STRDUP(ep2->seat);
1861 ep->state = STRDUP(ep2->state);
1862 ep->state2 = STRDUP(ep2->state2);
1863 ep->value = ep2->value;
1864 ep->value2 = ep2->value2;
1865 ep->tween.mode = ep2->tween.mode;
1866 ep->tween.time = ep2->tween.time;
1867 ep->tween.v1 = ep2->tween.v1;
1868 ep->tween.v2 = ep2->tween.v2;
1869 ep->tween.v3 = ep2->tween.v3;
1870 ep->tween.v4 = ep2->tween.v4;
1871 ep->tween.use_duration_factor = ep2->tween.use_duration_factor;
1872 ep->sample_name = STRDUP(ep2->sample_name);
1873 ep->tone_name = STRDUP(ep2->tone_name);
1874 ep->duration = ep2->duration;
1875 ep->speed = ep2->speed;
1876 ep->channel = ep2->channel;
1877
1878 EINA_LIST_FOREACH(ep2->targets, l, et2)
1879 {
1880 name = (char *)(et2 + 1);
1881 et = mem_alloc(SZ(Edje_Program_Target) + strlen(name) + 1);
1882 ep->targets = eina_list_append(ep->targets, et);
1883 copy = (char *)(et + 1);
1884
1885 memcpy(copy, name, strlen(name) + 1);
1886
1887 switch (ep2->action)
1888 {
1889 case EDJE_ACTION_TYPE_STATE_SET:
1890 case EDJE_ACTION_TYPE_SIGNAL_EMIT:
1891 case EDJE_ACTION_TYPE_DRAG_VAL_SET:
1892 case EDJE_ACTION_TYPE_DRAG_VAL_STEP:
1893 case EDJE_ACTION_TYPE_DRAG_VAL_PAGE:
1894 case EDJE_ACTION_TYPE_FOCUS_SET:
1895 case EDJE_ACTION_TYPE_FOCUS_OBJECT:
1896 if (current_group_inherit)
1897 data_queue_part_lookup(pc, name, &et->id);
1898 else
1899 data_queue_copied_part_lookup(pc, &(et2->id), &(et->id));
1900 break;
1901
1902 case EDJE_ACTION_TYPE_ACTION_STOP:
1903 case EDJE_ACTION_TYPE_SCRIPT:
1904 if (current_group_inherit)
1905 data_queue_program_lookup(pc, name, &et->id);
1906 else
1907 data_queue_copied_program_lookup(pc, &(et2->id), &(et->id));
1908 break;
1909
1910 default:
1911 ERR("parse error %s:%i. target may only be used after action",
1912 file_in, line - 1);
1913 exit(-1);
1914 }
1915 }
1916
1917 EINA_LIST_FOREACH(ep2->after, l, pa2)
1918 {
1919 name = (char *)(pa2 + 1);
1920 pa = mem_alloc(SZ(Edje_Program_After) + strlen(name) + 1);
1921 ep->after = eina_list_append(ep->after, pa);
1922 copy = (char *)(pa + 1);
1923 memcpy(copy, name, strlen(name) + 1);
1924 if (!data_queue_copied_program_lookup(pc, &(pa2->id), &(pa->id)))
1925 data_queue_program_lookup(pc, copy, &(pa->id));
1926 }
1927
1928 ep->api.name = STRDUP(ep2->api.name);
1929 ep->api.description = STRDUP(ep2->api.description);
1930 data_queue_copied_part_lookup(pc, &(ep2->param.src), &(ep->param.src));
1931 data_queue_copied_part_lookup(pc, &(ep2->param.dst), &(ep->param.dst));
1932
1933 epp = (Edje_Program_Parser *)ep;
1934 epp->can_override = EINA_TRUE;
1935 }
1936
1937 /*****/
1938
1939 /** @edcsection{toplevel,Top-Level blocks} */
1940
1941 /** @edcsubsection{toplevel_efl_version,
1942 * Efl_version} */
1943
1944 /**
1945 @page edcref
1946
1947 @property
1948 efl_version
1949 @parameters
1950 [major] [minor]
1951 @effect
1952 Used to show which version of EFL is used for developing a edje file.
1953 @endproperty
1954 */
1955 static void
st_efl_version(void)1956 st_efl_version(void)
1957 {
1958 check_arg_count(2);
1959
1960 edje_file->efl_version.major = parse_int(0);
1961 edje_file->efl_version.minor = parse_int(1);
1962 }
1963
1964 /** @edcsubsection{toplevel_id,
1965 * id} */
1966
1967 /**
1968 @page edcref
1969
1970 @property
1971 id
1972 @parameters
1973 [name]
1974 @effect
1975 A string which is used to identify the edje file.
1976 @since 1.21
1977 @endproperty
1978 */
1979 static void
st_id(void)1980 st_id(void)
1981 {
1982 Eina_Array_Iterator it;
1983 unsigned int i;
1984 char *str, *id;
1985
1986 check_arg_count(1);
1987 id = parse_str(0);
1988
1989 EINA_ARRAY_ITER_NEXT(requires, i, str, it)
1990 if (eina_streq(str, id))
1991 error_and_abort(NULL, "Cannot use same id for file as one of its required files!");
1992 free((void*)edje_file->id);
1993 edje_file->id = id;
1994 }
1995
1996 /** @edcsubsection{toplevel_requires,
1997 * requires} */
1998
1999 /**
2000 @page edcref
2001
2002 @property
2003 requires
2004 @parameters
2005 [name]
2006 @effect
2007 Specifying this property informs edje not to close the
2008 file with the corresponding id property for as long as this
2009 file is open. Multiple requires properties can be individually specified.
2010 @since 1.21
2011 @endproperty
2012 */
2013 static void
st_requires(void)2014 st_requires(void)
2015 {
2016 char *str;
2017 check_arg_count(1);
2018
2019 str = parse_str(0);
2020 if (eina_streq(str, edje_file->id))
2021 error_and_abort(NULL, "Cannot require the current file!");
2022 eina_array_push(requires, str);
2023 }
2024
2025 /** @edcsubsection{toplevel_externals,
2026 * Externals} */
2027
2028 /**
2029 @page edcref
2030
2031 @block
2032 externals
2033 @context
2034 externals {
2035 external: "name";
2036 }
2037 @description
2038 The "externals" block is used to list each external module file that will be used in others
2039 programs.
2040 @endblock
2041
2042 @property
2043 external
2044 @parameters
2045 [external filename]
2046 @effect
2047 Used to add a file to the externals list.
2048 @endproperty
2049 */
2050 static void
st_externals_external(void)2051 st_externals_external(void)
2052 {
2053 External *ex;
2054
2055 check_arg_count(1);
2056
2057 if (!edje_file->external_dir)
2058 edje_file->external_dir = mem_alloc(SZ(Edje_External_Directory));
2059
2060 ex = mem_alloc(SZ(External));
2061 ex->name = parse_str(0);
2062 {
2063 Eina_List *l;
2064 External *lex;
2065
2066 EINA_LIST_FOREACH(externals, l, lex)
2067 {
2068 if (!strcmp(lex->name, ex->name))
2069 {
2070 free(ex->name);
2071 free(ex);
2072 return;
2073 }
2074 }
2075 }
2076 externals = eina_list_append(externals, ex);
2077
2078 if (edje_file->external_dir)
2079 {
2080 Edje_External_Directory_Entry *entries;
2081
2082 edje_file->external_dir->entries_count++;
2083 entries = realloc(edje_file->external_dir->entries,
2084 sizeof (Edje_External_Directory_Entry) * edje_file->external_dir->entries_count);
2085 if (!entries)
2086 {
2087 ERR("not enough memory");
2088 exit(-1);
2089 }
2090 edje_file->external_dir->entries = entries;
2091 memset(edje_file->external_dir->entries + edje_file->external_dir->entries_count - 1,
2092 0, sizeof (Edje_External_Directory_Entry));
2093
2094 edje_file->external_dir->entries[edje_file->external_dir->entries_count - 1].entry = mem_strdup(ex->name);
2095 }
2096 }
2097
2098 /** @edcsubsection{toplevel_images,
2099 * Images} */
2100
2101 /**
2102 @page edcref
2103
2104 @block
2105 images
2106 @context
2107 images {
2108 image: "filename1.ext" COMP;
2109 image: "filename2.ext" LOSSY 99;
2110 image: "filename2.ext" LOSSY_ETC1 50;
2111 set { }
2112 set { }
2113 ..
2114 }
2115 @description
2116 The "images" block is used to list each image file that will be used in
2117 the theme along with its compression method (if any).
2118 Besides the document's root, additional "images" blocks can be
2119 included inside other blocks, normally "collections", "group" and
2120 "part", easing maintenance of the file list when the theme is split
2121 among multiple files.
2122 @note if svg file use as image, not vector, it will be converted to bitmap
2123 and '.png' will be add to file name.
2124 @endblock
2125
2126 @property
2127 image
2128 @parameters
2129 [image file] [compression method] (compression level)(edje file id)
2130 @effect
2131 Used to include each image file. The full path to the directory holding
2132 the images can be defined later with edje_cc's "-id" option.
2133 Compression methods:
2134 @li RAW: Uncompressed.
2135 @li COMP: Lossless compression.
2136 @li LOSSY [0-100]: JPEG lossy compression with quality from 0 to 100.
2137 @li LOSSY_ETC1 [0-100]: ETC1 lossy texture compression with quality from 0 to 100.
2138 @li LOSSY_ETC2 [0-100]: ETC2 lossy texture compression with quality from 0 to 100 (supports alpha).
2139 @li USER: Do not embed the file, refer to the external file instead.
2140 @li EXTERNAL: The file exists in the edje file with the specified id.
2141
2142 Defaults: compression level for lossy methods is 90.
2143 @endproperty
2144 */
2145 static void
st_images_image(void)2146 st_images_image(void)
2147 {
2148 /* NOTE: if you implement any changes with image_id mechanic don't forget
2149 * to update following functions: edje_edit_image_replace,
2150 * edje_edit_image_usage_list_get, edje_edit_image_del, _data_image_id_update
2151 */
2152 Edje_Image_Directory_Entry *img;
2153 const char *tmp;
2154 unsigned int i;
2155 int v;
2156
2157 check_min_arg_count(2);
2158
2159 if (!edje_file->image_dir)
2160 edje_file->image_dir = mem_alloc(SZ(Edje_Image_Directory));
2161
2162 tmp = parse_str(0);
2163
2164 for (i = 0; i < edje_file->image_dir->entries_count; ++i)
2165 if (!strcmp(edje_file->image_dir->entries[i].entry, tmp))
2166 {
2167 free((char *)tmp);
2168 return;
2169 }
2170
2171 edje_file->image_dir->entries_count++;
2172 img = realloc(edje_file->image_dir->entries,
2173 sizeof (Edje_Image_Directory_Entry) * edje_file->image_dir->entries_count);
2174 if (!img)
2175 {
2176 ERR("No enough memory.");
2177 exit(-1);
2178 }
2179 edje_file->image_dir->entries = img;
2180 memset(edje_file->image_dir->entries + edje_file->image_dir->entries_count - 1,
2181 0, sizeof (Edje_Image_Directory_Entry));
2182
2183 img = edje_file->image_dir->entries + edje_file->image_dir->entries_count - 1;
2184
2185 img->entry = tmp;
2186 img->id = edje_file->image_dir->entries_count - 1;
2187 v = parse_enum(1,
2188 "RAW", 0,
2189 "COMP", 1,
2190 "LOSSY", 2,
2191 "LOSSY_ETC1", 3,
2192 "LOSSY_ETC2", 4,
2193 "USER", 5,
2194 "EXTERNAL", 6,
2195 NULL);
2196 if (v == 0)
2197 {
2198 img->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_PERFECT;
2199 img->source_param = 0;
2200 }
2201 else if (v == 1)
2202 {
2203 img->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_PERFECT;
2204 img->source_param = 1;
2205 }
2206 else if (v == 2)
2207 {
2208 img->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY;
2209 img->source_param = 0;
2210 }
2211 else if (v == 3)
2212 {
2213 img->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY_ETC1;
2214 img->source_param = 0;
2215 }
2216 else if (v == 4)
2217 {
2218 img->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY_ETC2;
2219 img->source_param = 0;
2220 }
2221 else if (v == 5)
2222 {
2223 img->source_type = EDJE_IMAGE_SOURCE_TYPE_USER;
2224 img->source_param = 0;
2225 }
2226 else if (v == 6)
2227 {
2228 img->source_type = EDJE_IMAGE_SOURCE_TYPE_EXTERNAL;
2229 img->source_param = 0;
2230 img->external_id = parse_str(2);
2231 }
2232 if ((img->source_type < EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY) ||
2233 (img->source_type == EDJE_IMAGE_SOURCE_TYPE_USER))
2234 check_arg_count(2);
2235 else if (img->source_type != EDJE_IMAGE_SOURCE_TYPE_EXTERNAL)
2236 {
2237 if (check_range_arg_count(2, 3) > 2)
2238 img->source_param = parse_int_range(2, 0, 100);
2239 else
2240 img->source_param = 90;
2241 }
2242 if (!edje_file->image_id_hash)
2243 edje_file->image_id_hash = eina_hash_string_superfast_new(free);
2244 {
2245 Edje_Image_Hash *eih = mem_alloc(SZ(Edje_Image_Hash));
2246 eih->id = img->id;
2247 eina_hash_add(edje_file->image_id_hash, tmp, eih);
2248 }
2249 }
2250
2251 static void
_handle_vector_image(void)2252 _handle_vector_image(void)
2253 {
2254 Edje_Part_Description_Vector *ed;
2255 unsigned int i = 0;
2256 char *name;
2257
2258 ed = (Edje_Part_Description_Vector *)current_desc;
2259
2260 name = parse_str(0);
2261
2262 ed->vg.id = -1;
2263
2264 for (i = 0; i < edje_file->image_dir->vectors_count; ++i)
2265 {
2266 if (!strcmp(edje_file->image_dir->vectors[i].entry, name))
2267 {
2268 ed->vg.set = EINA_TRUE;
2269 ed->vg.id = edje_file->image_dir->vectors[i].id;
2270 ed->vg.type = edje_file->image_dir->vectors[i].type;
2271 break;
2272 }
2273 }
2274
2275 if (ed->vg.id < 0)
2276 error_and_abort(NULL, "Failed to find the vector resource :%s", name);
2277
2278 free(name);
2279 }
2280
2281 /** @edcsubsection{toplevel_images2,
2282 * Images} */
2283
2284 /**
2285 @page edcref
2286
2287 @block
2288 images
2289 @context
2290 images {
2291 vector: "filename1.svg";
2292 vector: "filename2.svg";
2293 vector: "filename3.svg";
2294 ..
2295 }
2296 @description
2297 The "vector" context in the "images" block is used to list each svg image file that will be used in
2298 the theme.
2299 @endblock
2300
2301 @property
2302 vector
2303 @parameters
2304 [image file]
2305 @endproperty
2306 */
2307 static void
st_images_vector(void)2308 st_images_vector(void)
2309 {
2310 Edje_Vector_Directory_Entry *vector;
2311 const char *tmp;
2312 unsigned int i;
2313 size_t entry_len;
2314
2315 check_min_arg_count(1);
2316
2317 if (!edje_file->image_dir)
2318 edje_file->image_dir = mem_alloc(SZ(Edje_Image_Directory));
2319
2320 tmp = parse_str(0);
2321
2322 for (i = 0; i < edje_file->image_dir->vectors_count; ++i)
2323 if (!strcmp(edje_file->image_dir->vectors[i].entry, tmp))
2324 {
2325 free((char *)tmp);
2326 return;
2327 }
2328
2329 edje_file->image_dir->vectors_count++;
2330 vector = realloc(edje_file->image_dir->vectors,
2331 sizeof (Edje_Vector_Directory_Entry) * edje_file->image_dir->vectors_count);
2332 if (!vector)
2333 {
2334 ERR("No enough memory.");
2335 exit(-1);
2336 }
2337 edje_file->image_dir->vectors = vector;
2338 memset(edje_file->image_dir->vectors + edje_file->image_dir->vectors_count - 1,
2339 0, sizeof (Edje_Vector_Directory_Entry));
2340
2341 vector = edje_file->image_dir->vectors + edje_file->image_dir->vectors_count - 1;
2342
2343 vector->entry = tmp;
2344 vector->id = edje_file->image_dir->vectors_count - 1;
2345
2346 entry_len = strlen(vector->entry);
2347 if ((entry_len > 5) && !strncmp(vector->entry + entry_len - 5, ".json", 5))
2348 {
2349 vector->type = EDJE_VECTOR_FILE_TYPE_LOTTIE;
2350 }
2351 else
2352 {
2353 vector->type = EDJE_VECTOR_FILE_TYPE_SVG;
2354 }
2355 }
2356
2357 /** @edcsubsection{toplevel_images_set,
2358 * Images.Set} */
2359
2360 /**
2361 @page edcref
2362
2363 @block
2364 set
2365 @context
2366 images {
2367 ..
2368 set {
2369 name: "image_name_used";
2370 image { }
2371 image { }
2372 ...
2373 }
2374 }
2375 @description
2376 The "set" block is used to define an image with different content
2377 depending on their size. Besides the document's root, additional
2378 "set" blocks can be included inside other blocks, normally
2379 "collections", "group" and "part", easing maintenance of the file
2380 list when the theme is split among multiple files.
2381 @endblock
2382 */
2383 static void
ob_images_set(void)2384 ob_images_set(void)
2385 {
2386 Edje_Image_Directory_Set *sets;
2387
2388 if (!edje_file->image_dir)
2389 edje_file->image_dir = mem_alloc(SZ(Edje_Image_Directory));
2390
2391 edje_file->image_dir->sets_count++;
2392 sets = realloc(edje_file->image_dir->sets,
2393 sizeof (Edje_Image_Directory_Set) * edje_file->image_dir->sets_count);
2394 if (!sets)
2395 {
2396 ERR("Not enough memory.");
2397 exit(-1);
2398 }
2399 edje_file->image_dir->sets = sets;
2400 memset(edje_file->image_dir->sets + edje_file->image_dir->sets_count - 1,
2401 0, sizeof (Edje_Image_Directory_Set));
2402
2403 edje_file->image_dir->sets[edje_file->image_dir->sets_count - 1].id = edje_file->image_dir->sets_count - 1;
2404 }
2405
2406 /**
2407 @page edcref
2408
2409 @property
2410 name
2411 @parameters
2412 [image name]
2413 @effect
2414 Define the name that refer to this image description.
2415 @endproperty
2416 */
2417 static void
st_images_set_name(void)2418 st_images_set_name(void)
2419 {
2420 check_arg_count(1);
2421
2422 edje_file->image_dir->sets[edje_file->image_dir->sets_count - 1].name = parse_str(0);
2423 }
2424
2425 /** @edcsubsection{toplevel_images_set_image,
2426 * Images.Set.Image} */
2427
2428 /**
2429 @page edcref
2430
2431 @block
2432 image
2433 @context
2434 images {
2435 ..
2436 set {
2437 ..
2438 image {
2439 image: "filename4.ext" COMP;
2440 size: 51 51 200 200;
2441 border: 0 0 0 0;
2442 border_scale_by: 0.0;
2443 }
2444 ..
2445 }
2446 }
2447 @description
2448 The "image" block inside a "set" block define the characteristic of an image.
2449 Every block will describe one image and the size rule to use it.
2450 @endblock
2451 **/
2452 static void
ob_images_set_image(void)2453 ob_images_set_image(void)
2454 {
2455 Edje_Image_Directory_Set_Entry *entry;
2456 Edje_Image_Directory_Set *set;
2457
2458 set = edje_file->image_dir->sets + edje_file->image_dir->sets_count - 1;
2459
2460 entry = mem_alloc(SZ(Edje_Image_Directory_Set_Entry));
2461
2462 set->entries = eina_list_append(set->entries, entry);
2463 }
2464
2465 /**
2466 @page edcref
2467
2468 @property
2469 image
2470 @parameters
2471 [image file] [compression method] (compression level)(edje file id)
2472 @effect
2473 Used to include each image file. The full path to the directory holding
2474 the images can be defined later with edje_cc's "-id" option.
2475 Compression methods:
2476 @li RAW: Uncompressed.
2477 @li COMP: Lossless compression.
2478 @li LOSSY [0-100]: JPEG lossy compression with quality from 0 to 100.
2479 @li LOSSY_ETC1 [0-100]: ETC1 lossy texture compression with quality from 0 to 100.
2480 @li LOSSY_ETC2 [0-100]: ETC2 lossy texture compression with quality from 0 to 100 (supports alpha).
2481 @li USER: Do not embed the file, refer to the external file instead.
2482 @li EXTERNAL: The file exists in the edje file with the specified id.
2483
2484 Defaults: compression level for lossy methods is 90.
2485 @endproperty
2486 **/
2487 static void
st_images_set_image_image(void)2488 st_images_set_image_image(void)
2489 {
2490 Edje_Image_Directory_Set_Entry *entry;
2491 Edje_Image_Directory_Set *set;
2492 unsigned int i;
2493
2494 set = edje_file->image_dir->sets + edje_file->image_dir->sets_count - 1;
2495 entry = eina_list_data_get(eina_list_last(set->entries));
2496
2497 /* Add the image to the global pool with the same syntax. */
2498 st_images_image();
2499
2500 entry->name = parse_str(0);
2501
2502 for (i = 0; i < edje_file->image_dir->entries_count; ++i)
2503 if (!strcmp(edje_file->image_dir->entries[i].entry, entry->name))
2504 {
2505 entry->id = i;
2506 return;
2507 }
2508 }
2509
2510 /**
2511 @page edcref
2512
2513 @property
2514 size
2515 @parameters
2516 [minw] [minh] [maxw] [maxh]
2517 @effect
2518 Define the minimal and maximal size that will select the specified image.
2519
2520 Defaults: 0 0 0 0
2521 @endproperty
2522 */
2523 static void
st_images_set_image_size(void)2524 st_images_set_image_size(void)
2525 {
2526 Edje_Image_Directory_Set_Entry *entry;
2527 Edje_Image_Directory_Set *set;
2528
2529 set = edje_file->image_dir->sets + edje_file->image_dir->sets_count - 1;
2530 entry = eina_list_data_get(eina_list_last(set->entries));
2531
2532 entry->size.min.w = parse_int(0);
2533 entry->size.min.h = parse_int(1);
2534 entry->size.max.w = parse_int(2);
2535 entry->size.max.h = parse_int(3);
2536
2537 if (entry->size.min.w > entry->size.max.w
2538 || entry->size.min.h > entry->size.max.h)
2539 {
2540 ERR("parse error %s:%i. Image min and max size are not in the right order ([%i, %i] < [%i, %i])",
2541 file_in, line - 1,
2542 entry->size.min.w, entry->size.min.h,
2543 entry->size.max.w, entry->size.max.h);
2544 exit(-1);
2545 }
2546 }
2547
2548 /**
2549 @page edcref
2550 @property
2551 border
2552 @parameters
2553 [left] [right] [top] [bottom]
2554 @effect
2555 If set, the area (in pixels) of each side of the image will be
2556 displayed as a fixed size border, from the side -> inwards, preventing
2557 the corners from being changed on a resize.
2558
2559 Defaults: 0 0 0 0
2560 @since 1.8
2561 @endproperty
2562 */
2563 static void
st_images_set_image_border(void)2564 st_images_set_image_border(void)
2565 {
2566 Edje_Image_Directory_Set_Entry *entry;
2567 Edje_Image_Directory_Set *set;
2568
2569 set = edje_file->image_dir->sets + edje_file->image_dir->sets_count - 1;
2570 entry = eina_list_data_get(eina_list_last(set->entries));
2571
2572 entry->border.l = parse_int_range(0, 0, 0x7fffffff);
2573 entry->border.r = parse_int_range(1, 0, 0x7fffffff);
2574 entry->border.t = parse_int_range(2, 0, 0x7fffffff);
2575 entry->border.b = parse_int_range(3, 0, 0x7fffffff);
2576 }
2577
2578 /**
2579 @page edcref
2580 @property
2581 border_scale_by
2582 @parameters
2583 [value]
2584 @effect
2585 If border scaling is enabled then normally the OUTPUT border sizes
2586 (e.g. if 3 pixels on the left edge are set as a border, then normally
2587 at scale 1.0, those 3 columns will always be the exact 3 columns of
2588 output, or at scale 2.0 they will be 6 columns, or 0.33 they will merge
2589 into a single column). This property multiplies the input scale
2590 factor by this multiplier, allowing the creation of "supersampled"
2591 borders to make much higher resolution outputs possible by always using
2592 the highest resolution artwork and then runtime scaling it down.
2593
2594 Valid values are: 0.0 or bigger (0.0 or 1.0 to turn it off)
2595
2596 Defaults: 0.0
2597 @since 1.8
2598 @endproperty
2599 */
2600 static void
st_images_set_image_border_scale_by(void)2601 st_images_set_image_border_scale_by(void)
2602 {
2603 Edje_Part_Description_Image *ed;
2604
2605 check_arg_count(1);
2606
2607 if (current_part->type != EDJE_PART_TYPE_IMAGE)
2608 {
2609 ERR("parse error %s:%i. image attributes in non-IMAGE part.",
2610 file_in, line - 1);
2611 exit(-1);
2612 }
2613
2614 ed = (Edje_Part_Description_Image *)current_desc;
2615
2616 ed->image.border.scale_by = FROM_DOUBLE(parse_float_range(0, 0.0, 999999999.0));
2617 }
2618
2619 /** @edcsubsection{toplevel_fonts,
2620 * Fonts} */
2621
2622 /**
2623 @page edcref
2624
2625 @block
2626 fonts
2627 @context
2628 fonts {
2629 font: "filename1.ext" "fontname";
2630 font: "filename2.ext" "otherfontname";
2631 ..
2632 }
2633 @description
2634 The "fonts" block is used to list each font file with an alias used later
2635 in the theme. As with the "images" block, additional "fonts" blocks can
2636 be included inside other blocks.
2637 @endblock
2638
2639 @property
2640 font
2641 @parameters
2642 [font filename] [font alias]
2643 @effect
2644 Defines each font "file" and "alias", the full path to the directory
2645 holding the font files can be defined with edje_cc's "-fd" option.
2646 @endproperty
2647 */
2648 static void
st_fonts_font(void)2649 st_fonts_font(void)
2650 {
2651 Edje_Font *fn;
2652
2653 check_arg_count(2);
2654
2655 if (!edje_file->fonts)
2656 edje_file->fonts = eina_hash_string_small_new(free);
2657
2658 fn = mem_alloc(SZ(Edje_Font));
2659 fn->file = parse_str(0);
2660 fn->name = parse_str(1);
2661
2662 if (eina_hash_find(edje_file->fonts, fn->name))
2663 {
2664 free(fn->file);
2665 free(fn->name);
2666 free(fn);
2667 return;
2668 }
2669
2670 eina_hash_direct_add(edje_file->fonts, fn->name, fn);
2671 }
2672
2673 /** @edcsubsection{toplevel_data,
2674 * Data} */
2675
2676 /**
2677 @page edcref
2678 @block
2679 data
2680 @context
2681 data {
2682 item: "key" "value";
2683 file: "otherkey" "filename.ext";
2684 ..
2685 }
2686 @description
2687 The "data" block is used to pass arbitrary parameters from the theme to
2688 the application. Unlike the "images" and "fonts" blocks, additional
2689 "data" blocks can only be included inside the "group" block.
2690 @endblock
2691
2692 @property
2693 item
2694 @parameters
2695 [parameter name] [parameter value]
2696 @effect
2697 Defines a new parameter, the value will be the string specified next to
2698 it.
2699 @endproperty
2700 */
2701 static void
st_data_item(void)2702 st_data_item(void)
2703 {
2704 Edje_String *es;
2705 char *key;
2706
2707 check_arg_count(2);
2708
2709 key = parse_str(0);
2710
2711 es = mem_alloc(SZ(Edje_String));
2712 es->str = parse_str(1);
2713
2714 if (!edje_file->data)
2715 edje_file->data = eina_hash_string_small_new(free);
2716 else
2717 {
2718 if (eina_hash_find(edje_file->data, key))
2719 {
2720 ERR("parse error %s:%i. There is already a data.item of the name %s",
2721 file_in, line - 1, key);
2722 exit(-1);
2723 }
2724 }
2725
2726 eina_hash_direct_add(edje_file->data, key, es);
2727 }
2728
2729 /**
2730 @page edcref
2731 @property
2732 file
2733 @parameters
2734 [parameter name] [parameter filename]
2735 @effect
2736 Defines a new parameter, the value will be the contents of the
2737 specified file formatted as a single string of text. This property only
2738 works with plain text files.
2739 @endproperty
2740 */
2741 static void
st_data_file(void)2742 st_data_file(void)
2743 {
2744 const char *data;
2745 const char *over;
2746 Edje_String *es;
2747 char *filename;
2748 char *value;
2749 char *key;
2750 int fd;
2751 int i;
2752 struct stat buf;
2753
2754 check_arg_count(2);
2755
2756 key = parse_str(0);
2757
2758 es = mem_alloc(SZ(Edje_String));
2759 filename = parse_str(1);
2760
2761 fd = open(filename, O_RDONLY | O_BINARY, S_IRUSR | S_IWUSR);
2762 if (fd < 0)
2763 {
2764 char path[PATH_MAX], *dir;
2765 Eina_List *l;
2766 EINA_LIST_FOREACH(data_dirs, l, dir)
2767 {
2768 snprintf(path, sizeof(path), "%s/%s", dir, filename);
2769 fd = open(path, O_RDONLY | O_BINARY, S_IRUSR | S_IWUSR);
2770 if (fd >= 0)
2771 break;
2772 }
2773
2774 if (fd < 0)
2775 {
2776 ERR("%s:%i when opening file \"%s\": \"%s\"",
2777 file_in, line, filename, strerror(errno));
2778 exit(-1);
2779 }
2780 }
2781
2782 if (fstat(fd, &buf))
2783 {
2784 ERR("%s:%i when stating file \"%s\": \"%s\"",
2785 file_in, line, filename, strerror(errno));
2786 exit(-1);
2787 }
2788
2789 data = mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
2790 if (data == MAP_FAILED)
2791 {
2792 ERR("%s:%i when mapping file \"%s\": \"%s\"",
2793 file_in, line, filename, strerror(errno));
2794 exit(-1);
2795 }
2796
2797 over = data;
2798 for (i = 0; i < buf.st_size; ++i, ++over)
2799 if (*over == '\0')
2800 {
2801 ERR("%s:%i file \"%s\" is a binary file.", file_in, line, filename);
2802 exit(-1);
2803 }
2804
2805 value = malloc(sizeof (char) * buf.st_size + 1);
2806 snprintf(value, buf.st_size + 1, "%s", data);
2807
2808 munmap((void *)data, buf.st_size);
2809 close(fd);
2810
2811 es->str = value;
2812
2813 if (!edje_file->data)
2814 edje_file->data = eina_hash_string_small_new(free);
2815
2816 eina_hash_direct_add(edje_file->data, key, es);
2817
2818 free(filename);
2819 }
2820
2821 /** @edcsubsection{toplevel_color_tree,
2822 * Color Tree} */
2823
2824 /**
2825 @page edcref
2826 @block
2827 color_tree
2828 @context
2829 color_tree {
2830 "color_class_0" {
2831 "color_class_3";
2832 "color_class_4" {
2833 "color_class_5";
2834 "color_class_6";
2835 }
2836 }
2837 "color_class_1";
2838 "color_class_2";
2839 ..
2840 }
2841 @description
2842 The "color_tree" block contains color tree node blocks.
2843 Each node block begins with the name of color class and enclosed with braces.
2844 Node block can be placed within another node block.
2845 @endblock
2846 */
2847 static void
ob_color_tree(void)2848 ob_color_tree(void)
2849 {
2850 if (!is_verbatim()) track_verbatim(1);
2851 else
2852 {
2853 char *s;
2854
2855 s = get_verbatim();
2856 if (s)
2857 {
2858 process_color_tree(s, file_in, get_verbatim_line1());
2859 set_verbatim(NULL, 0, 0);
2860 }
2861 }
2862 }
2863
2864 /** @edcsubsection{toplevel_color_classes,
2865 * Color Classes} */
2866
2867 /**
2868 @page edcref
2869 @block
2870 color_classes
2871 @context
2872 color_classes {
2873 color_class {
2874 name: "colorclassname";
2875 color: 255 0 0 255;
2876 color2: "#0F0F";
2877 color3: "#0000FFFF";
2878 }
2879 ..
2880 }
2881 @description
2882 The "color_classes" block contains a list of one or more "color_class"
2883 blocks. Each "color_class" allows the designer to name an arbitrary
2884 group of colors to be used in the theme, the application can use that
2885 name to alter the color values at runtime.
2886 @endblock
2887 */
2888 static void
ob_color_class(void)2889 ob_color_class(void)
2890 {
2891 Edje_Color_Class *cc;
2892
2893 cc = mem_alloc(SZ(Edje_Color_Class));
2894 edje_file->color_classes = eina_list_append(edje_file->color_classes, cc);
2895
2896 cc->r = 0;
2897 cc->g = 0;
2898 cc->b = 0;
2899 cc->a = 0;
2900 cc->r2 = 0;
2901 cc->g2 = 0;
2902 cc->b2 = 0;
2903 cc->a2 = 0;
2904 cc->r3 = 0;
2905 cc->g3 = 0;
2906 cc->b3 = 0;
2907 cc->a3 = 0;
2908 }
2909
2910 static void
_color_class_name(char * name)2911 _color_class_name(char *name)
2912 {
2913 Edje_Color_Class *cc, *tcc;
2914 Eina_List *l;
2915
2916 cc = eina_list_data_get(eina_list_last(edje_file->color_classes));
2917 cc->name = name;
2918 EINA_LIST_FOREACH(edje_file->color_classes, l, tcc)
2919 {
2920 if ((cc != tcc) && (!strcmp(cc->name, tcc->name)))
2921 {
2922 ERR("parse error %s:%i. There is already a color class named \"%s\"",
2923 file_in, line - 1, cc->name);
2924 exit(-1);
2925 }
2926 }
2927 }
2928
2929 /**
2930 @page edcref
2931
2932 @property
2933 name
2934 @parameters
2935 [color class name]
2936 @effect
2937 Sets the name for the color class, used as reference by both the theme
2938 and the application.
2939 @endproperty
2940 */
2941 static void
st_color_class_name(void)2942 st_color_class_name(void)
2943 {
2944 Edje_Color_Class *cc, *tcc;
2945 Eina_List *l;
2946
2947 cc = eina_list_data_get(eina_list_last(edje_file->color_classes));
2948 cc->name = parse_str(0);
2949 EINA_LIST_FOREACH(edje_file->color_classes, l, tcc)
2950 {
2951 if ((cc != tcc) && (!strcmp(cc->name, tcc->name)))
2952 {
2953 ERR("parse error %s:%i. There is already a color class named \"%s\"",
2954 file_in, line - 1, cc->name);
2955 exit(-1);
2956 }
2957 }
2958 }
2959
2960 static void
parse_color(unsigned int first_arg,void * base)2961 parse_color(unsigned int first_arg, void *base)
2962 {
2963 Edje_Color *color = (Edje_Color *)base;
2964 int r, g, b, a;
2965 char *str;
2966
2967 switch (get_arg_count() - first_arg)
2968 {
2969 case 1:
2970 str = parse_str(first_arg);
2971 convert_color_code(str, &r, &g, &b, &a);
2972 color->r = r;
2973 color->g = g;
2974 color->b = b;
2975 color->a = a;
2976 break;
2977
2978 case 4:
2979 color->r = parse_int_range(first_arg + 0, 0, 255);
2980 color->g = parse_int_range(first_arg + 1, 0, 255);
2981 color->b = parse_int_range(first_arg + 2, 0, 255);
2982 color->a = parse_int_range(first_arg + 3, 0, 255);
2983 break;
2984
2985 default:
2986 ERR("%s:%i. color code should be a string or a set of 4 integers.",
2987 file_in, line - 1);
2988 exit(-1);
2989 }
2990 }
2991
2992 /**
2993 @page edcref
2994 @property
2995 color
2996 @parameters
2997 [red] [green] [blue] [alpha] or "#[RR][GG][BB](AA)" or "#[R][G][B](A)"
2998 @effect
2999 The main color.
3000
3001 Format:
3002 @li [red] [green] [blue] [alpha]: one integer [0-255] for each
3003 RGBA channel, i.e. 255 0 0 255
3004 @li "#[RR][GG][BB](AA)": string with two hex values per RGBA channel,
3005 i.e "#FF0000FF" or "#FF0000"
3006 @li "#[R][G][B](A)": string with one hex value per RGBA channel,
3007 i.e "#F00F" or "#F00".\n
3008 In string format you can omit alpha channel and it will be set to FF.
3009
3010 Defaults: 0 0 0 0
3011 @endproperty
3012 */
3013 static void
st_color_class_color(void)3014 st_color_class_color(void)
3015 {
3016 Edje_Color_Class *cc;
3017
3018 cc = eina_list_data_get(eina_list_last(edje_file->color_classes));
3019
3020 parse_color(0, &(cc->r));
3021 }
3022
3023 /**
3024 @page edcref
3025 @property
3026 color2
3027 @parameters
3028 [red] [green] [blue] [alpha] or "#[RR][GG][BB](AA)" or "#[R][G][B](A)"
3029 @effect
3030 Used as outline in text and textblock parts.
3031
3032 Format:
3033 @li [red] [green] [blue] [alpha]: one integer [0-255] for each
3034 RGBA channel, i.e. 255 0 0 255
3035 @li "#[RR][GG][BB](AA)": string with two hex values per RGBA channel,
3036 i.e "#FF0000FF" or "#FF0000"
3037 @li "#[R][G][B](A)": string with one hex value per RGBA channel,
3038 i.e "#F00F" or "#F00".\n
3039 In string format you can omit alpha channel and it will be set to FF.
3040
3041 Defaults: 0 0 0 0
3042 @endproperty
3043 */
3044 static void
st_color_class_color2(void)3045 st_color_class_color2(void)
3046 {
3047 Edje_Color_Class *cc;
3048
3049 cc = eina_list_data_get(eina_list_last(edje_file->color_classes));
3050
3051 parse_color(0, &(cc->r2));
3052 }
3053
3054 /**
3055 @page edcref
3056 @property
3057 color3
3058 @parameters
3059 [red] [green] [blue] [alpha] or "#[RR][GG][BB](AA)" or "#[R][G][B](A)"
3060 @effect
3061 Used as shadow in text and textblock parts.
3062
3063 Format:
3064 @li [red] [green] [blue] [alpha]: one integer [0-255] for each
3065 RGBA channel, i.e. 255 0 0 255
3066 @li "#[RR][GG][BB](AA)": string with two hex values per RGBA channel,
3067 i.e "#FF0000FF" or "#FF0000"
3068 @li "#[R][G][B](A)": string with one hex value per RGBA channel,
3069 i.e "#F00F" or "#F00".\n
3070 In string format you can omit alpha channel and it will be set to FF.
3071
3072 Defaults: 0 0 0 0
3073 @endproperty
3074 */
3075 static void
st_color_class_color3(void)3076 st_color_class_color3(void)
3077 {
3078 Edje_Color_Class *cc;
3079
3080 cc = eina_list_data_get(eina_list_last(edje_file->color_classes));
3081
3082 parse_color(0, &(cc->r3));
3083 }
3084
3085 /**
3086 @page edcref
3087 @property
3088 description
3089 @parameters
3090 [color class description]
3091 @effect
3092 Provides a descriptive name for the effect of the color class
3093 @since 1.14
3094 @endproperty
3095 */
3096 static void
st_color_class_desc(void)3097 st_color_class_desc(void)
3098 {
3099 Edje_Color_Class *cc;
3100
3101 check_arg_count(1);
3102
3103 cc = eina_list_data_get(eina_list_last(edje_file->color_classes));
3104 cc->desc = parse_str(0);
3105 }
3106
3107 /** @edcsubsection{toplevel_styles,
3108 * Styles} */
3109
3110 /**
3111 @page edcref
3112 @block
3113 styles
3114 @context
3115 styles {
3116 style {
3117 name: "stylename";
3118 base: "..default style properties..";
3119
3120 tag: "tagname" "..style properties..";
3121 ..
3122 }
3123 ..
3124 }
3125 @description
3126 The "styles" block contains a list of one or more "style" blocks. A
3127 "style" block is used to create style \<tags\> for advanced TEXTBLOCK
3128 formatting.
3129 @endblock
3130 */
3131 static void
ob_styles_style(void)3132 ob_styles_style(void)
3133 {
3134 Edje_Style *stl;
3135
3136 stl = mem_alloc(SZ(Edje_Style));
3137 edje_file->styles = eina_list_append(edje_file->styles, stl);
3138 }
3139
3140 static void
_style_name(char * name)3141 _style_name(char *name)
3142 {
3143 Edje_Style *stl, *tstl;
3144 Eina_List *l;
3145
3146 stl = eina_list_last_data_get(edje_file->styles);
3147 free(stl->name);
3148 stl->name = name;
3149 EINA_LIST_FOREACH(edje_file->styles, l, tstl)
3150 {
3151 if (stl->name && tstl->name && (stl != tstl) && (!strcmp(stl->name, tstl->name)))
3152 {
3153 ERR("parse error %s:%i. There is already a style named \"%s\"",
3154 file_in, line - 1, stl->name);
3155 exit(-1);
3156 }
3157 }
3158 }
3159
3160 /**
3161 @page edcref
3162 @property
3163 name
3164 @parameters
3165 [style name]
3166 @effect
3167 The name of the style to be used as reference later in the theme.
3168 @endproperty
3169 */
3170 static void
st_styles_style_name(void)3171 st_styles_style_name(void)
3172 {
3173 _style_name(parse_str(0));
3174 }
3175
3176 /**
3177 @page edcref
3178 @property
3179 base
3180 @parameters
3181 [style properties string]
3182 @effect
3183 The default style properties that will be applied to the complete
3184 text.
3185 @endproperty
3186 */
3187 static void
st_styles_style_base(void)3188 st_styles_style_base(void)
3189 {
3190 Edje_Style *stl;
3191 Edje_Style_Tag *tag;
3192
3193 stl = eina_list_data_get(eina_list_last(edje_file->styles));
3194 if (stl->tags)
3195 {
3196 ERR("parse error %s:%i. There is already a basic format for the style",
3197 file_in, line - 1);
3198 exit(-1);
3199 }
3200 tag = mem_alloc(SZ(Edje_Style_Tag));
3201 tag->key = mem_strdup("DEFAULT");
3202 tag->value = parse_str(0);
3203 stl->tags = eina_list_append(stl->tags, tag);
3204 }
3205
3206 /**
3207 @page edcref
3208 @property
3209 tag
3210 @parameters
3211 [tag name] [style properties string]
3212 @effect
3213 Style to be applied only to text between style \<tags\>..\</tags\>.
3214 When creating "paired" tags, like \<bold\>\</bold\>, A '+' should be added at the start of the style properties of the first part (\<bold\>).
3215 If the second part (\</bold\>) is also defined, a '-' should be prepended to it's style properties.
3216 This only applies to paired tags; Single tags, like \<tab\>, must not include a starting '+'.
3217 @endproperty
3218 */
3219 static void
st_styles_style_tag(void)3220 st_styles_style_tag(void)
3221 {
3222 Edje_Style *stl;
3223 Edje_Style_Tag *tag;
3224
3225 stl = eina_list_data_get(eina_list_last(edje_file->styles));
3226 tag = mem_alloc(SZ(Edje_Style_Tag));
3227 tag->key = parse_str(0);
3228 tag->value = parse_str(1);
3229 stl->tags = eina_list_append(stl->tags, tag);
3230 }
3231
3232 /** @edcsubsection{toplevel_text_classes,
3233 * Text Classes} */
3234
3235 /**
3236 @page edcref
3237 @block
3238 text_classes
3239 @context
3240 text_classes {
3241 text_class {
3242 name: "text_class name";
3243 font: "font name";
3244 size: SIZE";
3245 }
3246 ..
3247 }
3248 @description
3249 The "text_classes" block contains a list of one or more "text_class"
3250 blocks. Each "text_class" allows the designer to name an arbitrary
3251 group of font and size to be used in the theme, the application can
3252 use that name to alter the font and its size at runtime.
3253 @endblock
3254 */
3255 static void
ob_text_class(void)3256 ob_text_class(void)
3257 {
3258 Edje_Text_Class *tc;
3259
3260 tc = mem_alloc(SZ(Edje_Text_Class));
3261 edje_file->text_classes = eina_list_append(edje_file->text_classes, tc);
3262
3263 tc->font = NULL;
3264 tc->size = 0;
3265 }
3266
3267 static void
_text_class_name(char * name)3268 _text_class_name(char *name)
3269 {
3270 Edje_Text_Class *tc, *ttc;
3271 Eina_List *l;
3272
3273 tc = eina_list_data_get(eina_list_last(edje_file->text_classes));
3274 tc->name = name;
3275 EINA_LIST_FOREACH(edje_file->text_classes, l, ttc)
3276 {
3277 if ((tc != ttc) && (!strcmp(tc->name, ttc->name)))
3278 {
3279 ERR("parse error %s:%i. There is already a text class named \"%s\"",
3280 file_in, line - 1, tc->name);
3281 exit(-1);
3282 }
3283 }
3284 }
3285
3286 /**
3287 @page edcref
3288
3289 @property
3290 name
3291 @parameters
3292 [text class name]
3293 @effect
3294 Sets the name for the text class, used as reference by both the theme
3295 and the application.
3296 @endproperty
3297 */
3298 static void
st_text_class_name(void)3299 st_text_class_name(void)
3300 {
3301 Edje_Text_Class *tc, *ttc;
3302 Eina_List *l;
3303
3304 tc = eina_list_data_get(eina_list_last(edje_file->text_classes));
3305 tc->name = parse_str(0);
3306 EINA_LIST_FOREACH(edje_file->text_classes, l, ttc)
3307 {
3308 if ((tc != ttc) && (!strcmp(tc->name, ttc->name)))
3309 {
3310 ERR("parse error %s:%i. There is already a text class named \"%s\"",
3311 file_in, line - 1, tc->name);
3312 exit(-1);
3313 }
3314 }
3315 }
3316
3317 /**
3318 @page edcref
3319
3320 @property
3321 font
3322 @parameters
3323 [font name]
3324 @effect
3325 Sets the font family for the text class.
3326 @endproperty
3327 */
3328 static void
st_text_class_font(void)3329 st_text_class_font(void)
3330 {
3331 Edje_Text_Class *tc;
3332
3333 check_arg_count(1);
3334
3335 tc = eina_list_data_get(eina_list_last(edje_file->text_classes));
3336 tc->font = parse_str(0);
3337 }
3338
3339 /**
3340 @page edcref
3341
3342 @property
3343 size
3344 @parameters
3345 [font size in points (pt)]
3346 @effect
3347 Sets the font size for the text class.
3348
3349 Defaults: 0
3350 @endproperty
3351 */
3352 static void
st_text_class_size(void)3353 st_text_class_size(void)
3354 {
3355 Edje_Text_Class *tc;
3356
3357 check_arg_count(1);
3358
3359 tc = eina_list_data_get(eina_list_last(edje_file->text_classes));
3360 tc->size = parse_int_range(0, 0, 255);
3361 }
3362
3363 /** @edcsubsection{toplevel_size_classes,
3364 * Size Classes} */
3365
3366 /**
3367 @page edcref
3368 @block
3369 size_classes
3370 @context
3371 size_classes {
3372 size_class {
3373 name: "sizeclassname";
3374 min: width height;
3375 max: width height;
3376 }
3377 ..
3378 }
3379 @description
3380 The "size_classes" block contains a list of one or more "size_class"
3381 blocks. Each "size_class" allows the designer to name an arbitrary
3382 group of size to be used in the theme, the application can use that
3383 name to alter the min and max size values at runtime.
3384 @endblock
3385 */
3386 static void
ob_size_class(void)3387 ob_size_class(void)
3388 {
3389 Edje_Size_Class *sc;
3390
3391 sc = mem_alloc(SZ(Edje_Size_Class));
3392 edje_file->size_classes = eina_list_append(edje_file->size_classes, sc);
3393
3394 sc->minw = 0;
3395 sc->minh = 0;
3396 sc->maxw = -1;
3397 sc->maxh = -1;
3398 }
3399
3400 static void
_size_class_name(char * name)3401 _size_class_name(char *name)
3402 {
3403 Edje_Size_Class *sc, *tsc;
3404 Eina_List *l;
3405
3406 sc = eina_list_data_get(eina_list_last(edje_file->size_classes));
3407 sc->name = name;
3408 EINA_LIST_FOREACH(edje_file->size_classes, l, tsc)
3409 {
3410 if ((sc != tsc) && (!strcmp(sc->name, tsc->name)))
3411 {
3412 ERR("parse error %s:%i. There is already a size class named \"%s\"",
3413 file_in, line - 1, sc->name);
3414 exit(-1);
3415 }
3416 }
3417 }
3418
3419 /**
3420 @page edcref
3421
3422 @property
3423 name
3424 @parameters
3425 [size class name]
3426 @effect
3427 Sets the name for the size class, used as reference by both the theme
3428 and the application.
3429 @endproperty
3430 */
3431 static void
st_size_class_name(void)3432 st_size_class_name(void)
3433 {
3434 Edje_Size_Class *sc, *tsc;
3435 Eina_List *l;
3436
3437 sc = eina_list_data_get(eina_list_last(edje_file->size_classes));
3438 sc->name = parse_str(0);
3439 EINA_LIST_FOREACH(edje_file->size_classes, l, tsc)
3440 {
3441 if ((sc != tsc) && (!strcmp(sc->name, tsc->name)))
3442 {
3443 ERR("parse error %s:%i. There is already a size class named \"%s\"",
3444 file_in, line - 1, sc->name);
3445 exit(-1);
3446 }
3447 }
3448 }
3449
3450 /**
3451 @page edcref
3452 @property
3453 min
3454 @parameters
3455 [width] [height]
3456 @effect
3457 The minimum size.
3458
3459 Defaults: 0 0
3460 @endproperty
3461 */
3462 static void
st_size_class_min(void)3463 st_size_class_min(void)
3464 {
3465 Edje_Size_Class *sc;
3466
3467 check_arg_count(2);
3468
3469 sc = eina_list_data_get(eina_list_last(edje_file->size_classes));
3470 sc->minw = parse_int_range(0, 0, 0x7fffffff);
3471 sc->minh = parse_int_range(1, 0, 0x7fffffff);
3472 }
3473
3474 /**
3475 @page edcref
3476 @property
3477 max
3478 @parameters
3479 [width] [height]
3480 @effect
3481 The maximum size.
3482
3483 Defaults: -1 -1
3484 @endproperty
3485 */
3486 static void
st_size_class_max(void)3487 st_size_class_max(void)
3488 {
3489 Edje_Size_Class *sc;
3490
3491 check_arg_count(2);
3492
3493 sc = eina_list_data_get(eina_list_last(edje_file->size_classes));
3494 sc->maxw = parse_int_range(0, -1, 0x7fffffff);
3495 sc->maxh = parse_int_range(1, -1, 0x7fffffff);
3496 }
3497
3498 /** @edcsection{collections,Collections Blocks} */
3499
3500 /** @edcsubsection{sub_collections,
3501 * Collections} */
3502
3503 /**
3504 @page edcref
3505 @block
3506 collections
3507 @context
3508 collections {
3509 base_scale: 1.2;
3510 sounds { }
3511 vibrations { }
3512 group { }
3513 group { }
3514 ..
3515 }
3516 @description
3517 The "collections" block is used to list the groups that compose the
3518 theme. Additional "collections" blocks do not prevent overriding group
3519 names. The "sounds" block comprises of all sound definitions. The "vibrations"
3520 block compriese all vibration definitions.
3521 @endblock
3522 */
3523 static void
ob_collections(void)3524 ob_collections(void)
3525 {
3526 if (!edje_file->collection)
3527 {
3528 edje_file->collection = eina_hash_string_small_new(NULL);
3529 edje_collections_lookup = eina_hash_int32_new(NULL);
3530 desc_hash = eina_hash_pointer_new(NULL);
3531 }
3532 }
3533
3534 /**
3535 @page edcref
3536 @property
3537 base_scale
3538 @parameters
3539 [scale val]
3540 @effect
3541 The base_scale is the standard scale value of the collection.
3542 The default base_scale is 1.0. It means the collection is made in the environment
3543 which is same with a desktop(The monitor has 96 dpi).
3544 If you make a collection in another environment(ex: 115 dpi), you have to
3545 set the base_scale(ex: 1.2). Then it will be shown same size in the desktop.
3546
3547 Defaults: 1.0
3548 @since 1.11
3549 @endproperty
3550 */
3551 static void
st_collections_base_scale(void)3552 st_collections_base_scale(void)
3553 {
3554 check_min_arg_count(1);
3555
3556 edje_file->base_scale = FROM_DOUBLE(parse_float_range(0, 0.0, 999999999.0));
3557 if (EQ(edje_file->base_scale, ZERO))
3558 {
3559 ERR("The base_scale is 0.0. The value should be bigger than 0.0.");
3560 exit(-1);
3561 }
3562 }
3563
3564 /** @edcsubsection{collections_sounds,
3565 * Sounds} */
3566
3567 /**
3568 @page edcref
3569 @block
3570 sounds
3571 @context
3572 sounds {
3573 tone: "tone-1" 2300;
3574 tone: "tone-2" 2300;
3575 sample { }
3576 sample { }
3577 ..
3578 }
3579 @description
3580 The "sounds" block contains a list of one or more sound sample and tones items.
3581 @endblock
3582 */
3583
3584 /**
3585 @page edcref
3586 @property
3587 tone
3588 @parameters
3589 [tone name] [frequency]
3590 @effect
3591 sound of specific frequency
3592 @since 1.1
3593 @endproperty
3594 */
3595 static void
st_collections_group_sound_tone(void)3596 st_collections_group_sound_tone(void)
3597 {
3598 Edje_Sound_Tone *tone;
3599 const char *tmp;
3600 unsigned int i;
3601 int value;
3602
3603 check_arg_count(2);
3604
3605 if (!edje_file->sound_dir)
3606 edje_file->sound_dir = mem_alloc(SZ(Edje_Sound_Directory));
3607
3608 tmp = parse_str(0);
3609 /* Audible range 20 to 20KHz */
3610 value = parse_int_range(1, 20, 20000);
3611
3612 /* Check for Tone duplication */
3613 for (i = 0; i < edje_file->sound_dir->tones_count; i++)
3614 {
3615 if (!strcmp(edje_file->sound_dir->tones[i].name, tmp))
3616 {
3617 ERR("Tone name: %s already exist.", tmp);
3618 free((char *)tmp);
3619 exit(-1);
3620 }
3621 if (edje_file->sound_dir->tones[i].value == value)
3622 {
3623 ERR("Tone name %s with same frequency %d exist.",
3624 edje_file->sound_dir->tones[i].name, value);
3625 exit(-1);
3626 }
3627 }
3628 edje_file->sound_dir->tones_count++;
3629 tone = realloc(edje_file->sound_dir->tones,
3630 sizeof (Edje_Sound_Tone) *
3631 edje_file->sound_dir->tones_count);
3632 if (!tone)
3633 {
3634 ERR("No enough memory.");
3635 exit(-1);
3636 }
3637 edje_file->sound_dir->tones = tone;
3638
3639 tone = edje_file->sound_dir->tones + edje_file->sound_dir->tones_count - 1;
3640 memset(tone, 0, sizeof (Edje_Sound_Tone));
3641
3642 tone->name = tmp;
3643 tone->value = value;
3644 tone->id = edje_file->sound_dir->tones_count - 1;
3645 }
3646
3647 /** @edcsubsection{collections_sounds_sample,
3648 * Sounds.Sample} */
3649
3650 /**
3651 @page edcref
3652 @block
3653 sample
3654 @context
3655 sounds {
3656 ..
3657 sample {
3658 name: "sound_file1" RAW;
3659 source: "sound_file1.wav";
3660 }
3661 sample {
3662 name: "sound_file2" LOSSY 0.5;
3663 source: "sound_file2.wav";
3664 }
3665 }
3666 @description
3667 The sample block defines the sound sample.
3668 @endblock
3669 @property
3670 name
3671 @parameters
3672 [sample name] [compression type] (quality)
3673 @effect
3674 Used to include each sound file. The full path to the directory holding
3675 the sounds can be defined later with edje_cc's "-sd" option.
3676 Valid types are:
3677 @li RAW: Uncompressed.
3678 @li COMP: Lossless compression.
3679 @li LOSSY [45.0 - 1000.0]: Lossy compression with quality from 45.0 to 1000.0.
3680 @li AS_IS: Check for re-encoding, no compression/encoding, just write the file information as it is.
3681
3682 @since 1.1
3683 @endproperty
3684 */
3685 static void
st_collections_group_sound_sample_name(void)3686 st_collections_group_sound_sample_name(void)
3687 {
3688 Edje_Sound_Sample *sample;
3689 const char *tmp;
3690 unsigned int i;
3691
3692 if (!edje_file->sound_dir)
3693 edje_file->sound_dir = mem_alloc(SZ(Edje_Sound_Directory));
3694
3695 tmp = parse_str(0);
3696
3697 for (i = 0; i < edje_file->sound_dir->samples_count; i++)
3698 {
3699 if (!strcmp(edje_file->sound_dir->samples[i].name, tmp))
3700 {
3701 free((char *)tmp);
3702 return;
3703 }
3704 }
3705
3706 edje_file->sound_dir->samples_count++;
3707 sample = realloc(edje_file->sound_dir->samples,
3708 sizeof(Edje_Sound_Sample) *
3709 edje_file->sound_dir->samples_count);
3710 if (!sample)
3711 {
3712 ERR("No enough memory.");
3713 exit(-1);
3714 }
3715 edje_file->sound_dir->samples = sample;
3716
3717 sample =
3718 edje_file->sound_dir->samples +
3719 edje_file->sound_dir->samples_count - 1;
3720 memset(sample, 0, sizeof (Edje_Sound_Sample));
3721
3722 sample->name = tmp;
3723 sample->id = edje_file->sound_dir->samples_count - 1;
3724 sample->compression = parse_enum(1,
3725 "RAW", EDJE_SOUND_SOURCE_TYPE_INLINE_RAW,
3726 "COMP", EDJE_SOUND_SOURCE_TYPE_INLINE_COMP,
3727 "LOSSY", EDJE_SOUND_SOURCE_TYPE_INLINE_LOSSY,
3728 "AS_IS", EDJE_SOUND_SOURCE_TYPE_INLINE_AS_IS,
3729 NULL);
3730
3731 if (sample->compression == EDJE_SOUND_SOURCE_TYPE_INLINE_LOSSY)
3732 {
3733 sample->quality = parse_float_range(2, 45.0, 1000.0);
3734 check_arg_count(3);
3735 }
3736 else
3737 check_arg_count(2);
3738 }
3739
3740 /**
3741 @page edcref
3742 @property
3743 source
3744 @parameters
3745 [sound file name]
3746 @effect
3747 The Sound source file name (Source can be mono/stereo WAV file.
3748 Only files with 44.1 KHz sample rate supported now)
3749 @since 1.1
3750 @endproperty
3751 */
3752 static void
st_collections_group_sound_sample_source(void)3753 st_collections_group_sound_sample_source(void)
3754 {
3755 Edje_Sound_Sample *sample;
3756
3757 if (!edje_file->sound_dir->samples)
3758 {
3759 ERR("Invalid sound sample source definition.");
3760 exit(-1);
3761 }
3762
3763 sample =
3764 edje_file->sound_dir->samples +
3765 edje_file->sound_dir->samples_count - 1;
3766 sample->snd_src = parse_str(0);
3767 check_arg_count(1);
3768 }
3769
3770 /** @edcsubsection{collections_vibrations,
3771 * Vibrations} */
3772
3773 /**
3774 @page edcref
3775 @block
3776 vibrations
3777 @context
3778 vibrations {
3779 sample { }
3780 sample { }
3781 ..
3782 }
3783
3784 @description
3785 The "vibrations" block contains a list of one or more vibration sample.
3786 @since 1.10
3787 @endblock
3788 */
3789
3790 /** @edcsubsection{collections_vibrations_sample,
3791 * Vibrations.Sample} */
3792
3793 /**
3794 @page edcref
3795 @block
3796 sample
3797 @context
3798 vibrations {
3799 sample {
3800 name: "vibration_file1";
3801 source: "vibration_file1.xxx";
3802 }
3803 ..
3804 }
3805 @description
3806 The sample block defines the vibration sample.
3807 @endblock
3808 @property
3809 name
3810 @parameters
3811 [sample name]
3812 @effect
3813 Used to include each vibration file. The full path to the directory holding
3814 the vibrations can be defined later with edje_cc's "-vd" option.
3815 @since 1.10
3816 @endproperty
3817 */
3818 static void
st_collections_group_vibration_sample_name(void)3819 st_collections_group_vibration_sample_name(void)
3820 {
3821 Edje_Vibration_Sample *sample;
3822 const char *tmp;
3823 unsigned int i;
3824
3825 if (!edje_file->vibration_dir)
3826 edje_file->vibration_dir = mem_alloc(SZ(Edje_Vibration_Directory));
3827
3828 tmp = parse_str(0);
3829
3830 for (i = 0; i < edje_file->vibration_dir->samples_count; i++)
3831 {
3832 if (!strcmp(edje_file->vibration_dir->samples[i].name, tmp))
3833 {
3834 free((char *)tmp);
3835 return;
3836 }
3837 }
3838
3839 edje_file->vibration_dir->samples_count++;
3840 sample = realloc(edje_file->vibration_dir->samples,
3841 sizeof(Edje_Vibration_Sample) *
3842 edje_file->vibration_dir->samples_count);
3843 if (!sample)
3844 {
3845 ERR("No enough memory.");
3846 exit(-1);
3847 }
3848 edje_file->vibration_dir->samples = sample;
3849
3850 sample =
3851 edje_file->vibration_dir->samples +
3852 edje_file->vibration_dir->samples_count - 1;
3853 memset(sample, 0, sizeof(Edje_Vibration_Sample));
3854
3855 sample->name = tmp;
3856 sample->id = edje_file->vibration_dir->samples_count - 1;
3857
3858 check_arg_count(1);
3859 }
3860
3861 /**
3862 @page edcref
3863 @property
3864 source
3865 @parameters
3866 [vibration file name]
3867 @effect
3868 The Vibration source file name
3869 @since 1.10
3870 @endproperty
3871 */
3872 static void
st_collections_group_vibration_sample_source(void)3873 st_collections_group_vibration_sample_source(void)
3874 {
3875 Edje_Vibration_Sample *sample;
3876
3877 if (!edje_file->vibration_dir->samples)
3878 {
3879 ERR("Invalid vibration sample source definition.");
3880 exit(-1);
3881 }
3882
3883 sample =
3884 edje_file->vibration_dir->samples +
3885 edje_file->vibration_dir->samples_count - 1;
3886 sample->src = parse_str(0);
3887 check_arg_count(1);
3888 }
3889
3890 /** @edcsubsection{collections_translation_file,
3891 * translation.file} */
3892
3893 /**
3894 @page edcref
3895 @block
3896 file
3897 @context
3898 translation {
3899 ..
3900 file {
3901 locale: "en_IN";
3902 source: "domain_name.po";
3903 }
3904 file {
3905 locale: "en_US";
3906 source: "domain_name.po";
3907 }
3908 }
3909 @description
3910 The file block defines the po or mo file.
3911 @endblock
3912 @property
3913 name
3914 @parameters
3915 [locale name]
3916 @effect
3917 Used to include each po or mo file. The full path to the directory holding
3918 the po or mo file can be defined later with edje_cc's "-md" option.
3919
3920 @since 1.15
3921 @endproperty
3922 */
3923 static void
st_collections_group_translation_file_locale(void)3924 st_collections_group_translation_file_locale(void)
3925 {
3926 Edje_Mo *mo_entry;
3927 const char *tmp;
3928 unsigned int i;
3929
3930 check_arg_count(1);
3931
3932 if (!edje_file->mo_dir)
3933 edje_file->mo_dir = mem_alloc(SZ(Edje_Mo_Directory));
3934
3935 tmp = parse_str(0);
3936
3937 for (i = 0; i < edje_file->mo_dir->mo_entries_count; i++)
3938 {
3939 if (!strcmp(edje_file->mo_dir->mo_entries[i].locale, tmp))
3940 {
3941 free((char *)tmp);
3942 return;
3943 }
3944 }
3945
3946 edje_file->mo_dir->mo_entries_count++;
3947 mo_entry = realloc(edje_file->mo_dir->mo_entries, sizeof(Edje_Mo) * edje_file->mo_dir->mo_entries_count);
3948
3949 if (!mo_entry)
3950 {
3951 ERR("No enough memory.");
3952 exit(-1);
3953 }
3954 edje_file->mo_dir->mo_entries = mo_entry;
3955
3956 mo_entry = edje_file->mo_dir->mo_entries + edje_file->mo_dir->mo_entries_count - 1;
3957 memset(mo_entry, 0, sizeof (Edje_Mo));
3958
3959 mo_entry->locale = tmp;
3960 mo_entry->id = edje_file->mo_dir->mo_entries_count - 1;
3961 }
3962
3963 /**
3964 @page edcref
3965 @property
3966 source
3967 @parameters
3968 [po file name or Mo file name]
3969 @effect
3970 The po or mo source file name (Source should be a valid po or mo file.
3971 Only po or mo files are supported now)
3972 @since 1.15
3973 @endproperty
3974 */
3975
3976 static void
st_collections_group_translation_file_source(void)3977 st_collections_group_translation_file_source(void)
3978 {
3979 Edje_Mo *mo_entry;
3980
3981 check_arg_count(1);
3982
3983 if (!edje_file->mo_dir->mo_entries)
3984 {
3985 ERR("Invalid mo source definition.");
3986 exit(-1);
3987 }
3988
3989 mo_entry = edje_file->mo_dir->mo_entries + edje_file->mo_dir->mo_entries_count - 1;
3990 mo_entry->mo_src = parse_str(0);
3991 }
3992
3993 static void
_link_combine(void)3994 _link_combine(void)
3995 {
3996 Edje_Part_Collection *pc;
3997 Edje_Part_Collection_Parser *pcp;
3998 Eina_Iterator *it;
3999 Eina_Hash_Tuple *tup;
4000
4001 pc = eina_list_last_data_get(edje_collections);
4002 pcp = eina_list_last_data_get(edje_collections);
4003
4004 if (!pcp->link_hash) return;
4005 it = eina_hash_iterator_tuple_new(pcp->link_hash);
4006 EINA_ITERATOR_FOREACH(it, tup)
4007 {
4008 while (tup->data)
4009 {
4010 Edje_Part_Description_Link *el, *ell;
4011 Eina_List *l, *ll, *combine = NULL;
4012
4013 el = eina_list_data_get(tup->data);
4014 tup->data = eina_list_remove_list(tup->data, tup->data);
4015 EINA_LIST_FOREACH_SAFE(tup->data, l, ll, ell)
4016 {
4017 if (ell->pr->tween.mode != el->pr->tween.mode) continue;
4018 if (!EQ(ell->pr->tween.time, el->pr->tween.time)) continue;
4019 if (!EQ(ell->pr->tween.v1, el->pr->tween.v1)) continue;
4020 if (!EQ(ell->pr->tween.v2, el->pr->tween.v2)) continue;
4021 if (!EQ(ell->pr->tween.v3, el->pr->tween.v3)) continue;
4022 if (!EQ(ell->pr->tween.v4, el->pr->tween.v4)) continue;
4023 if (!EQ(ell->ed->state.value, el->ed->state.value)) continue;
4024 if ((!!ell->ed->state.name) != (!!el->ed->state.name))
4025 {
4026 if (((!!ell->ed->state.name) && strcmp(ell->ed->state.name, "default")) ||
4027 ((!!el->ed->state.name) && strcmp(el->ed->state.name, "default")))
4028 continue;
4029 }
4030 else if (ell->ed->state.name && strcmp(ell->ed->state.name, el->ed->state.name))
4031 continue;
4032 eina_list_move_list(&combine, (Eina_List **)&tup->data, l);
4033 }
4034 current_program = el->pr;
4035 if (!el->epp->common.name)
4036 {
4037 ERR("A part without a name was detected.");
4038 exit(-1);
4039 }
4040 _program_target_add(strdup(el->epp->common.name));
4041 EINA_LIST_FREE(combine, ell)
4042 {
4043 char *name;
4044
4045 _program_target_add(strdup(ell->epp->common.name));
4046 EINA_LIST_FOREACH(ell->pr->after, l, name)
4047 _program_after(name);
4048 _program_free(ell->pr);
4049 free(ell);
4050 }
4051 _edje_program_insert(pc, current_program);
4052 }
4053 }
4054 eina_iterator_free(it);
4055 eina_hash_free(pcp->link_hash);
4056 pcp->links = eina_list_free(pcp->links);
4057 current_program = NULL;
4058 }
4059
4060 /** @edcsubsection{collections_group,
4061 * Group} */
4062
4063 /**
4064 @page edcref
4065 @block
4066 group
4067 @context
4068 collections {
4069 ..
4070 group {
4071 name: "nameusedbytheapplication";
4072 alias: "anothername";
4073 min: width height;
4074 max: width height;
4075
4076 script { }
4077 limits { }
4078 data { }
4079 parts { }
4080 programs { }
4081 }
4082 ..
4083 }
4084 @description
4085 A "group" block contains the list of parts and programs that compose a
4086 given Edje Object.
4087 @endblock
4088 */
4089 static void
ob_collections_group(void)4090 ob_collections_group(void)
4091 {
4092 Edje_Part_Collection *pc;
4093 Edje_Part_Collection_Parser *pcp;
4094 Code *cd;
4095
4096 if (current_de && !current_de->entry)
4097 {
4098 ERR("A collection without a name was detected, that's not allowed.");
4099 exit(-1);
4100 }
4101 current_program = NULL;
4102 current_part = NULL;
4103 current_desc = NULL;
4104
4105 current_group_inherit = EINA_FALSE;
4106 script_is_replaceable = EINA_FALSE;
4107
4108 current_de = mem_alloc(SZ(Edje_Part_Collection_Directory_Entry));
4109 current_de->id = eina_list_count(edje_collections);
4110
4111 if (!edje_collections_lookup)
4112 ob_collections();
4113 eina_hash_add(edje_collections_lookup, ¤t_de->id, current_de);
4114
4115 pc = mem_alloc(SZ(Edje_Part_Collection_Parser));
4116 edje_collections = eina_list_append(edje_collections, pc);
4117 pc->id = current_de->id;
4118 pc->broadcast_signal = EINA_TRUE; /* This was the behaviour by default in Edje 1.1 */
4119
4120 cd = mem_alloc(SZ(Code));
4121 codes = eina_list_append(codes, cd);
4122
4123 pcp = (Edje_Part_Collection_Parser *)pc;
4124 pcp->default_mouse_events = 1;
4125 pcp->inherit_script = EINA_FALSE;
4126
4127 #ifdef HAVE_EPHYSICS
4128 pc->physics.world.gravity.x = 0;
4129 pc->physics.world.gravity.y = 294;
4130 pc->physics.world.gravity.z = 0;
4131 pc->physics.world.depth = 100;
4132 pc->physics.world.z = -50;
4133 pc->physics.world.rate = FROM_DOUBLE(30);
4134 #endif
4135 }
4136
4137 static void
_group_name(char * name)4138 _group_name(char *name)
4139 {
4140 Edje_Part_Collection_Directory_Entry *alias;
4141 Edje_Part_Collection_Directory_Entry *older;
4142 Edje_Part_Collection *current_pc;
4143 Eina_List *l = NULL;
4144
4145 current_pc = eina_list_data_get(eina_list_last(edje_collections));
4146
4147 if (current_de->entry)
4148 goto double_named_group;
4149
4150 current_de->entry = name;
4151 current_pc->part = current_de->entry;
4152
4153 older = eina_hash_find(edje_file->collection, current_de->entry);
4154 if (older) eina_hash_del(edje_file->collection, current_de->entry, older);
4155 eina_hash_direct_add(edje_file->collection, current_de->entry, current_de);
4156 if (!older) return;
4157
4158 EINA_LIST_FOREACH(aliases, l, alias)
4159 if (strcmp(alias->entry, current_de->entry) == 0)
4160 {
4161 Edje_Part_Collection *pc;
4162
4163 pc = eina_list_nth(edje_collections, older->id);
4164 INF("overriding alias ('%s' => '%s') by group '%s'",
4165 alias->entry, pc->part,
4166 current_de->entry);
4167 aliases = eina_list_remove_list(aliases, l);
4168 free(alias);
4169 break;
4170 }
4171
4172 double_named_group:
4173 ERR("Invalid group '%s', only a single name statement is valid for group,"
4174 "use alias instead.", current_de->entry);
4175 exit(-1);
4176 }
4177
4178 /**
4179 @page edcref
4180 @property
4181 name
4182 @parameters
4183 [group name]
4184 @effect
4185 The name that will be used by the application to load the resulting
4186 Edje object and to identify the group to swallow in a GROUP part. If
4187 group with the same name exists already, it won't be compiled.
4188 Only a single name statement is valid for group, use alias instead if
4189 you want to give additional names.
4190 @endproperty
4191 */
4192 static void
st_collections_group_name(void)4193 st_collections_group_name(void)
4194 {
4195 check_arg_count(1);
4196 _group_name(parse_str(0));
4197 }
4198
4199 /**
4200 @page edcref
4201 @property
4202 skip_namespace_validation
4203 @parameters
4204 [1 or 0]
4205 @effect
4206 This disables namespace validation for the current group if validation has
4207 been enabled with edje_cc's -N option.
4208 This property can be inherited.
4209 Defaults: 0
4210
4211 @warning Your edc file should always wrap this keyword with <tt>\#ifdef HAVE_SKIP_NAMESPACE_VALIDATION</tt>
4212 @since 1.21
4213 @endproperty
4214 */
4215 static void
st_collections_group_skip_namespace_validation(void)4216 st_collections_group_skip_namespace_validation(void)
4217 {
4218 Edje_Part_Collection_Parser *pcp = eina_list_last_data_get(edje_collections);
4219 check_arg_count(1);
4220 pcp->skip_namespace_validation = parse_bool(0);
4221 }
4222
4223 typedef struct _Edje_List_Foreach_Data Edje_List_Foreach_Data;
4224 struct _Edje_List_Foreach_Data
4225 {
4226 Eina_List *list;
4227 };
4228
4229 static Eina_Bool
_edje_data_item_list_foreach(const Eina_Hash * hash EINA_UNUSED,const void * key,void * data EINA_UNUSED,void * fdata)4230 _edje_data_item_list_foreach(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data EINA_UNUSED, void *fdata)
4231 {
4232 Edje_List_Foreach_Data *fd;
4233
4234 fd = fdata;
4235 fd->list = eina_list_append(fd->list, strdup(key));
4236
4237 return EINA_TRUE;
4238 }
4239
4240 static void
_filter_copy(Edje_Part_Description_Spec_Filter * ed,const Edje_Part_Description_Spec_Filter * parent)4241 _filter_copy(Edje_Part_Description_Spec_Filter *ed, const Edje_Part_Description_Spec_Filter *parent)
4242 {
4243 ed->code = STRDUP(parent->code);
4244 if (ed->code)
4245 {
4246 const char *name;
4247 Eina_List *l;
4248 unsigned k;
4249
4250 ed->name = STRDUP(parent->name);
4251 ed->sources = NULL;
4252 EINA_LIST_FOREACH(parent->sources, l, name)
4253 ed->sources = eina_list_append(ed->sources, STRDUP(name));
4254 ed->data = NULL;
4255 ed->data_count = 0;
4256 if (parent->data)
4257 {
4258 ed->data = mem_alloc(parent->data_count * sizeof(*parent->data));
4259 ed->data_count = parent->data_count;
4260 for (k = 0; k < parent->data_count; k++)
4261 {
4262 ed->data[k].name = STRDUP(parent->data[k].name);
4263 ed->data[k].value = STRDUP(parent->data[k].value);
4264 }
4265 }
4266 }
4267 else memset(ed, 0, sizeof(*ed));
4268 }
4269
4270 static void
_parts_count_update(unsigned int type,int inc)4271 _parts_count_update(unsigned int type, int inc)
4272 {
4273 switch (type)
4274 {
4275 case EDJE_PART_TYPE_RECTANGLE:
4276 current_de->count.RECTANGLE += inc;
4277 break;
4278
4279 case EDJE_PART_TYPE_TEXT:
4280 current_de->count.TEXT += inc;
4281 break;
4282
4283 case EDJE_PART_TYPE_IMAGE:
4284 current_de->count.IMAGE += inc;
4285 break;
4286
4287 case EDJE_PART_TYPE_SWALLOW:
4288 current_de->count.SWALLOW += inc;
4289 break;
4290
4291 case EDJE_PART_TYPE_TEXTBLOCK:
4292 current_de->count.TEXTBLOCK += inc;
4293 break;
4294
4295 case EDJE_PART_TYPE_GROUP:
4296 current_de->count.GROUP += inc;
4297 break;
4298
4299 case EDJE_PART_TYPE_BOX:
4300 current_de->count.BOX += inc;
4301 break;
4302
4303 case EDJE_PART_TYPE_TABLE:
4304 current_de->count.TABLE += inc;
4305 break;
4306
4307 case EDJE_PART_TYPE_EXTERNAL:
4308 current_de->count.EXTERNAL += inc;
4309 break;
4310
4311 case EDJE_PART_TYPE_PROXY:
4312 current_de->count.PROXY += inc;
4313 break;
4314
4315 case EDJE_PART_TYPE_SPACER:
4316 current_de->count.SPACER += inc;
4317 break;
4318
4319 case EDJE_PART_TYPE_SNAPSHOT:
4320 current_de->count.SNAPSHOT += inc;
4321 break;
4322
4323 case EDJE_PART_TYPE_VECTOR:
4324 current_de->count.VECTOR += inc;
4325 break;
4326 }
4327 current_de->count.part += inc;
4328 }
4329
4330 static void
_part_copy(Edje_Part * ep,Edje_Part * ep2)4331 _part_copy(Edje_Part *ep, Edje_Part *ep2)
4332 {
4333 Edje_Part_Collection *pc;
4334 Edje_Part_Parser *epp, *epp2;
4335 Edje_Pack_Element *item, *item2;
4336 Edje_Pack_Element_Parser *pitem;
4337 Edje_Part_Description_Common *ed, *ed2;
4338 unsigned int j;
4339
4340 pc = eina_list_last_data_get(edje_collections);
4341
4342 ep->name = STRDUP(ep2->name);
4343 ep->source = STRDUP(ep2->source);
4344 ep->source2 = STRDUP(ep2->source2);
4345 ep->source3 = STRDUP(ep2->source3);
4346 ep->source4 = STRDUP(ep2->source4);
4347 ep->source5 = STRDUP(ep2->source5);
4348 ep->source6 = STRDUP(ep2->source6);
4349
4350 data_queue_copied_part_lookup(pc, &(ep2->clip_to_id), &(ep->clip_to_id));
4351
4352 ep->type = ep2->type;
4353 ep->mouse_events = ep2->mouse_events;
4354 ep->anti_alias = ep2->anti_alias;
4355 ep->repeat_events = ep2->repeat_events;
4356 ep->ignore_flags = ep2->ignore_flags;
4357 ep->mask_flags = ep2->mask_flags;
4358 ep->scale = ep2->scale;
4359 ep->pointer_mode = ep2->pointer_mode;
4360 ep->precise_is_inside = ep2->precise_is_inside;
4361 ep->use_alternate_font_metrics = ep2->use_alternate_font_metrics;
4362 ep->effect = ep2->effect;
4363 ep->entry_mode = ep2->entry_mode;
4364 ep->select_mode = ep2->select_mode;
4365 ep->cursor_mode = ep2->cursor_mode;
4366 ep->multiline = ep2->multiline;
4367 ep->access = ep2->access;
4368 ep->no_render = ep2->no_render;
4369 ep->required = ep2->required;
4370 ep->dragable.x = ep2->dragable.x;
4371 ep->dragable.step_x = ep2->dragable.step_x;
4372 ep->dragable.count_x = ep2->dragable.count_x;
4373 ep->dragable.y = ep2->dragable.y;
4374 ep->dragable.step_y = ep2->dragable.step_y;
4375 ep->dragable.count_y = ep2->dragable.count_y;
4376 ep->nested_children_count = ep2->nested_children_count;
4377
4378 if (ep2->allowed_seats)
4379 {
4380 Edje_Part_Allowed_Seat *seat;
4381 unsigned int s;
4382
4383 ep->allowed_seats_count = ep2->allowed_seats_count;
4384 ep->allowed_seats = calloc(ep2->allowed_seats_count,
4385 sizeof(Edje_Part_Allowed_Seat *));
4386 if (!ep->allowed_seats)
4387 {
4388 ERR("Not enough memory.");
4389 exit(-1);
4390 }
4391
4392 for (s = 0; s < ep->allowed_seats_count; s++)
4393 {
4394 seat = mem_alloc(SZ(Edje_Part_Allowed_Seat));
4395 if (ep2->allowed_seats[s]->name)
4396 {
4397 seat->name = strdup(ep2->allowed_seats[s]->name);
4398 if (!seat->name)
4399 {
4400 ERR("Not enough memory.");
4401 exit(-1);
4402 }
4403 }
4404 ep->allowed_seats[s] = seat;
4405 }
4406 }
4407
4408 data_queue_copied_part_lookup(pc, &(ep2->dragable.confine_id), &(ep->dragable.confine_id));
4409 data_queue_copied_part_lookup(pc, &(ep2->dragable.threshold_id), &(ep->dragable.threshold_id));
4410 data_queue_copied_part_lookup(pc, &(ep2->dragable.event_id), &(ep->dragable.event_id));
4411
4412 epp = (Edje_Part_Parser *)ep;
4413 epp2 = (Edje_Part_Parser *)ep2;
4414 epp->reorder.insert_before = STRDUP(epp2->reorder.insert_before);
4415 epp->reorder.insert_after = STRDUP(epp2->reorder.insert_after);
4416 epp->can_override = EINA_TRUE;
4417
4418 for (j = 0; j < ep2->items_count; j++)
4419 {
4420 ob_collections_group_parts_part_box_items_item();
4421 item = ep->items[j];
4422 item2 = ep2->items[j];
4423 item->type = item2->type;
4424 item->name = STRDUP(item2->name);
4425 item->source = STRDUP(item2->source);
4426 item->min.w = item2->min.w;
4427 item->min.h = item2->min.h;
4428 item->prefer.w = item2->prefer.w;
4429 item->prefer.h = item2->prefer.h;
4430 item->max.w = item2->max.w;
4431 item->max.h = item2->max.h;
4432 item->padding.l = item2->padding.l;
4433 item->padding.r = item2->padding.r;
4434 item->padding.t = item2->padding.t;
4435 item->padding.b = item2->padding.b;
4436 item->align.x = item2->align.x;
4437 item->align.y = item2->align.y;
4438 item->weight.x = item2->weight.x;
4439 item->weight.y = item2->weight.y;
4440 item->aspect.w = item2->aspect.w;
4441 item->aspect.h = item2->aspect.h;
4442 item->aspect.mode = item2->aspect.mode;
4443 item->options = STRDUP(item2->options);
4444 item->col = item2->col;
4445 item->row = item2->row;
4446 item->colspan = item2->colspan;
4447 item->rowspan = item2->rowspan;
4448 item->spread.w = item2->spread.w;
4449 item->spread.h = item2->spread.h;
4450
4451 pitem = (Edje_Pack_Element_Parser *)item;
4452 pitem->can_override = EINA_TRUE;
4453
4454 _parts_count_update(item->type, 1);
4455 }
4456
4457 ep->api.name = STRDUP(ep2->api.name);
4458 if (ep2->api.description) ep->api.description = STRDUP(ep2->api.description);
4459
4460 // copy default description
4461 ob_collections_group_parts_part_description();
4462 ed = ep->default_desc;
4463 parent_desc = ed2 = ep2->default_desc;
4464 free((void *)ed->state.name);
4465 ed->state.name = STRDUP(ed2->state.name);
4466 ed->state.value = ed2->state.value;
4467 st_collections_group_parts_part_description_inherit();
4468 parent_desc = NULL;
4469
4470 // copy other description
4471 for (j = 0; j < ep2->other.desc_count; j++)
4472 {
4473 ob_collections_group_parts_part_description();
4474 ed = ep->other.desc[j];
4475 parent_desc = ed2 = ep2->other.desc[j];
4476 ed->state.name = STRDUP(ed2->state.name);
4477 ed->state.value = ed2->state.value;
4478 st_collections_group_parts_part_description_inherit();
4479 parent_desc = NULL;
4480 }
4481 }
4482
4483 /**
4484 @page edcref
4485 @property
4486 inherit_only
4487 @parameters
4488 [1 or 0]
4489 @effect
4490 This flags a group as being used only for inheriting, which
4491 will inhibit edje_cc resolving of programs and parts that may
4492 not exist in this group, but are located in the group which is inheriting
4493 this group.
4494
4495 Defaults: 0
4496 @since 1.10
4497 @endproperty
4498 */
4499 static void
st_collections_group_inherit_only(void)4500 st_collections_group_inherit_only(void)
4501 {
4502 Edje_Part_Collection_Parser *pcp;
4503
4504 check_arg_count(1);
4505
4506 pcp = eina_list_data_get(eina_list_last(edje_collections));
4507 pcp->inherit_only = parse_bool(0);
4508 }
4509
4510 /**
4511 @page edcref
4512 @property
4513 use_custom_seat_names
4514 @parameters
4515 [1 or 0]
4516 @effect
4517 This flags a group as designed to listen for multiseat signals
4518 following a custom naming instead of default Edje naming.
4519 Seats are named on Edje as "seat1", "seat2", etc, in an incremental
4520 way and never are changed.
4521
4522 But on Evas, names may be set on different places
4523 (Evas, Ecore Evas backends, the application itself)
4524 and name changes are allowed.
4525 So custom names come from system at first, but can be overriden with
4526 evas_device_name_set().
4527 Also Evas seat names don't need to follow any pattern.
4528
4529 It's useful for cases where there is control of the
4530 system, as seat names, or when the application
4531 sets the devices names to guarantee they'll match
4532 seat names on EDC.
4533
4534 Defaults: 0
4535 @since 1.19
4536 @endproperty
4537 */
4538 static void
st_collections_group_use_custom_seat_names(void)4539 st_collections_group_use_custom_seat_names(void)
4540 {
4541 Edje_Part_Collection *pc;
4542
4543 check_arg_count(1);
4544
4545 pc = eina_list_data_get(eina_list_last(edje_collections));
4546 pc->use_custom_seat_names = parse_bool(0);
4547 }
4548
4549 /**
4550 @page edcref
4551 @property
4552 part_remove
4553 @parameters
4554 [part name] (part name) (part name) ...
4555 @effect
4556 Removes the listed parts from an inherited group. Removing nonexistent
4557 parts is not allowed.
4558 @since 1.10
4559 @endproperty
4560 */
4561 static void
st_collections_group_part_remove(void)4562 st_collections_group_part_remove(void)
4563 {
4564 unsigned int n, argc, orig_count, part_type;
4565 Edje_Part_Collection *pc;
4566
4567 check_min_arg_count(1);
4568
4569 if (!current_group_inherit)
4570 {
4571 ERR("Cannot remove parts from non-inherited group '%s'", current_de->entry);
4572 exit(-1);
4573 }
4574
4575 pc = eina_list_last_data_get(edje_collections);
4576 orig_count = pc->parts_count;
4577
4578 for (n = 0, argc = get_arg_count(); n < argc; n++)
4579 {
4580 char *name;
4581 unsigned int j, cur_count = pc->parts_count;
4582
4583 name = parse_str(n);
4584
4585 for (j = 0; j < pc->parts_count; j++)
4586 {
4587 unsigned int i;
4588
4589 if (strcmp(pc->parts[j]->name, name)) continue;
4590
4591 part_type = pc->parts[j]->type;
4592 pc->parts[j] = _part_free(pc, pc->parts[j]);
4593 for (i = j; i < pc->parts_count - 1; i++)
4594 {
4595 if (!pc->parts[i + 1]) break;
4596 pc->parts[i] = pc->parts[i + 1];
4597 }
4598 pc->parts_count--;
4599 _parts_count_update(part_type, -1);
4600 break;
4601 }
4602 if (cur_count == pc->parts_count)
4603 {
4604 ERR("Attempted removal of nonexistent part '%s' in group '%s'.",
4605 name, current_de->entry);
4606 exit(-1);
4607 }
4608 free(name);
4609 }
4610 if (orig_count == pc->parts_count) return;
4611 if (pc->parts_count)
4612 pc->parts = realloc(pc->parts, pc->parts_count * sizeof(Edje_Part *));
4613 else
4614 {
4615 free(pc->parts);
4616 pc->parts = NULL;
4617 }
4618 }
4619
4620 /**
4621 @page edcref
4622 @property
4623 program_remove
4624 @parameters
4625 [program name] (program name) (program name) ...
4626 @effect
4627 Removes the listed programs from an inherited group. Removing nonexistent
4628 programs is not allowed.
4629 This will break program sequences if a program in the middle of the sequence is removed.
4630 @since 1.10
4631 @endproperty
4632 */
4633 static void
st_collections_group_program_remove(void)4634 st_collections_group_program_remove(void)
4635 {
4636 unsigned int n, argc;
4637 Edje_Part_Collection *pc;
4638
4639 check_min_arg_count(1);
4640
4641 if (!current_group_inherit)
4642 {
4643 ERR("Cannot remove programs from non-inherited group '%s'", current_de->entry);
4644 exit(-1);
4645 }
4646
4647 pc = eina_list_last_data_get(edje_collections);
4648
4649 for (n = 0, argc = get_arg_count(); n < argc; n++)
4650 {
4651 char *name;
4652 Eina_Bool success = EINA_FALSE;
4653
4654 name = parse_str(n);
4655
4656 success |= _program_remove(name, pc->programs.fnmatch, pc->programs.fnmatch_count);
4657 success |= _program_remove(name, pc->programs.strcmp, pc->programs.strcmp_count);
4658 success |= _program_remove(name, pc->programs.strncmp, pc->programs.strncmp_count);
4659 success |= _program_remove(name, pc->programs.strrncmp, pc->programs.strrncmp_count);
4660 success |= _program_remove(name, pc->programs.nocmp, pc->programs.nocmp_count);
4661
4662 if (anonymous_delete)
4663 {
4664 copied_program_anonymous_lookup_delete(pc, anonymous_delete);
4665 anonymous_delete = NULL;
4666 }
4667 if (!success)
4668 {
4669 ERR("Attempted removal of nonexistent program '%s' in group '%s'.",
4670 name, current_de->entry);
4671 exit(-1);
4672 }
4673 free(name);
4674 }
4675 }
4676
4677 /**
4678 @page edcref
4679 @property
4680 target_group
4681 @parameters
4682 [name] [part or program] (part or program) (part or program) ...
4683 @effect
4684 This creates a group of parts/programs which can then be referenced
4685 by a single 'groups' or 'target_groups' statement inside a program.
4686 The resulting program will have all of the parts/programs within the specified
4687 group added as targets.
4688 @since 1.10
4689 @endproperty
4690 */
4691 static void
st_collections_group_target_group(void)4692 st_collections_group_target_group(void)
4693 {
4694 int n, argc;
4695 Edje_Part_Collection_Parser *pc;
4696 char *name;
4697 Eina_List *l;
4698 Edje_Target_Group *tg;
4699
4700 check_min_arg_count(2);
4701
4702 pc = eina_list_last_data_get(edje_collections);
4703 name = parse_str(0);
4704 EINA_LIST_FOREACH(pc->target_groups, l, tg)
4705 if (!strcmp(tg->name, name))
4706 {
4707 ERR("parse error %s:%i. There is already a target_group with the name '%s'",
4708 file_in, line - 1, name);
4709 exit(-1);
4710 }
4711 tg = malloc(sizeof(Edje_Target_Group));
4712 pc->target_groups = eina_list_append(pc->target_groups, tg);
4713 tg->name = name;
4714 argc = get_arg_count();
4715 tg->targets = calloc(argc, sizeof(char *));
4716
4717 for (n = 1; n < argc; n++)
4718 tg->targets[n - 1] = parse_str(n);
4719 }
4720
4721 /**
4722 @page edcref
4723 @property
4724 inherit
4725 @parameters
4726 [parent group name]
4727 @effect
4728 Parent group name for inheritance.
4729 Group "inherit" is used to inherit any predefined group and change
4730 some property which belongs to "part", "description", "items" or "program".
4731 The child group has the same property as parent group. If you specify the
4732 type again in an inherited part, it will cause an error (unless you plan
4733 to fix that).
4734 @warning When inheriting any parts, descriptions without state names are NOT
4735 allowed.
4736 @since 1.10
4737 @endproperty
4738 */
4739 static void
st_collections_group_inherit(void)4740 st_collections_group_inherit(void)
4741 {
4742 Edje_Part_Collection_Directory_Entry *alias;
4743 Edje_Part_Collection *pc, *pc2 = NULL;
4744 Edje_Part_Collection_Parser *pcp, *pcp2;
4745 Edje_Part *ep, *ep2;
4746 Edje_List_Foreach_Data fdata;
4747 Eina_List *l;
4748 char *parent_name;
4749 unsigned int i, j, offset;
4750
4751 check_arg_count(1);
4752
4753 pc = eina_list_data_get(eina_list_last(edje_collections));
4754
4755 parent_name = parse_str(0);
4756
4757 EINA_LIST_FOREACH(aliases, l, alias)
4758 {
4759 if (alias->group_alias &&
4760 !strcmp(alias->entry, parent_name))
4761 {
4762 free(parent_name);
4763 pc2 = eina_list_nth(edje_collections, alias->id);
4764 parent_name = strdup(pc2->part);
4765 break;
4766 }
4767 }
4768
4769 if (!pc2)
4770 {
4771 EINA_LIST_FOREACH(edje_collections, l, pc2)
4772 {
4773 if (!strcmp(parent_name, pc2->part))
4774 break;
4775 }
4776 }
4777
4778 if (!pc2)
4779 {
4780 ERR("parse error %s:%i. There isn't a group with the name %s",
4781 file_in, line - 1, parent_name);
4782 exit(-1);
4783 }
4784
4785 if (pc2 == pc)
4786 {
4787 ERR("parse error %s:%i. You are trying to inherit '%s' from itself. That's not possible."
4788 "If there is another group of the same name, you want to inherit from that group and have the"
4789 "same name as that group, there is a trick ! Just put the inherit before the directive that set"
4790 "the name !", file_in, line - 1, parent_name);
4791 exit(-1);
4792 }
4793 current_group_inherit = EINA_TRUE;
4794
4795 if (pc2->data)
4796 {
4797 char *key, *data;
4798
4799 memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
4800 eina_hash_foreach(pc2->data,
4801 _edje_data_item_list_foreach, &fdata);
4802
4803 if (!pc->data) pc->data = eina_hash_string_small_new(free);
4804 EINA_LIST_FREE(fdata.list, key)
4805 {
4806 data = eina_hash_find(pc2->data, key);
4807 eina_hash_direct_add(pc->data, key, data);
4808 }
4809 }
4810
4811 if (pc2->alias)
4812 {
4813 char *key;
4814
4815 memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
4816 eina_hash_foreach(pc2->alias,
4817 _edje_data_item_list_foreach, &fdata);
4818 if (!pc->alias) pc->alias = eina_hash_string_small_new(free);
4819 EINA_LIST_FREE(fdata.list, key)
4820 {
4821 char *tmp;
4822 tmp = eina_hash_find(pc2->alias, key);
4823 eina_hash_direct_add(pc->alias, key, tmp);
4824 }
4825 }
4826 if (pc2->aliased)
4827 {
4828 char *key, *aliased;
4829
4830 memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
4831 eina_hash_foreach(pc2->aliased,
4832 _edje_data_item_list_foreach, &fdata);
4833 if (!pc->aliased) pc->aliased = eina_hash_string_small_new(free);
4834 EINA_LIST_FREE(fdata.list, key)
4835 {
4836 aliased = eina_hash_find(pc2->aliased, key);
4837 eina_hash_direct_add(pc->aliased, key, aliased);
4838 }
4839 }
4840
4841 #ifdef HAVE_EPHYSICS
4842 pc->physics.world.gravity.x = pc2->physics.world.gravity.x;
4843 pc->physics.world.gravity.y = pc2->physics.world.gravity.y;
4844 pc->physics.world.gravity.z = pc2->physics.world.gravity.z;
4845 pc->physics.world.depth = pc2->physics.world.depth;
4846 pc->physics.world.z = pc2->physics.world.z;
4847 pc->physics.world.rate = pc2->physics.world.rate;
4848 #endif
4849
4850 pc->prop.min.w = pc2->prop.min.w;
4851 pc->prop.min.h = pc2->prop.min.h;
4852 pc->prop.orientation = pc2->prop.orientation;
4853
4854 pc->lua_script_only = pc2->lua_script_only;
4855 pc->use_custom_seat_names = pc2->use_custom_seat_names;
4856
4857 pcp = (Edje_Part_Collection_Parser *)pc;
4858 pcp2 = (Edje_Part_Collection_Parser *)pc2;
4859 pcp->default_mouse_events = pcp2->default_mouse_events;
4860 pcp->skip_namespace_validation = pcp2->skip_namespace_validation;
4861 if (pcp2->inherit_script)
4862 pcp->inherit_script = pcp2->inherit_script;
4863
4864 /* as of 7 April 2014, target groups cannot be modified and are not freed.
4865 * this code will break if that ever changes.
4866 *
4867 * BORKER CERTIFICATION: BRONZE
4868 */
4869 if (pcp2->target_groups)
4870 pcp->target_groups = eina_list_clone(pcp2->target_groups);
4871
4872 if (pcp2->default_source)
4873 {
4874 free(pcp->default_source);
4875 pcp->default_source = strdup(pcp2->default_source);
4876 }
4877
4878 if (pc2->limits.vertical_count || pc2->limits.horizontal_count)
4879 {
4880 Edje_Limit **elp;
4881
4882 if (pc2->limits.vertical_count)
4883 {
4884 elp = realloc(pc->limits.vertical,
4885 pc->limits.vertical_count + pc2->limits.vertical_count * sizeof(Edje_Limit *));
4886 if (!elp)
4887 {
4888 ERR("Not enough memory.");
4889 exit(-1);
4890 }
4891 pc->limits.vertical = elp;
4892 offset = pc->limits.vertical_count;
4893 for (i = 0; i < pc2->limits.vertical_count; i++)
4894 {
4895 Edje_Limit *el;
4896
4897 el = mem_alloc(SZ(Edje_Limit));
4898 if (!el)
4899 {
4900 ERR("Not enough memory.");
4901 exit(-1);
4902 }
4903
4904 pc->limits.vertical[i + offset] = el;
4905
4906 el->name = STRDUP(pc2->limits.vertical[i]->name);
4907 el->value = pc2->limits.vertical[i]->value;
4908 pc->limits.vertical_count++;
4909 }
4910 }
4911
4912 if (pc2->limits.horizontal_count)
4913 {
4914 elp = realloc(pc->limits.horizontal,
4915 pc->limits.horizontal_count + pc2->limits.horizontal_count * sizeof(Edje_Limit *));
4916 if (!elp)
4917 {
4918 ERR("Not enough memory.");
4919 exit(-1);
4920 }
4921 pc->limits.horizontal = elp;
4922 offset = pc->limits.horizontal_count;
4923 for (i = 0; i < pc2->limits.horizontal_count; i++)
4924 {
4925 Edje_Limit *el;
4926
4927 el = mem_alloc(SZ(Edje_Limit));
4928 if (!el)
4929 {
4930 ERR("Not enough memory.");
4931 exit(-1);
4932 }
4933
4934 pc->limits.horizontal[i + offset] = el;
4935
4936 el->name = STRDUP(pc2->limits.horizontal[i]->name);
4937 el->value = pc2->limits.horizontal[i]->value;
4938 pc->limits.horizontal_count++;
4939 }
4940 }
4941 }
4942
4943 offset = pc->parts_count;
4944 for (i = 0; i < pc2->parts_count; i++)
4945 {
4946 // copy the part
4947 edje_cc_handlers_part_make(-1);
4948 ep = pc->parts[i + offset];
4949 ep2 = pc2->parts[i];
4950 _part_copy(ep, ep2);
4951 }
4952
4953 //copy programs
4954 for (j = 0; j < pc2->programs.fnmatch_count; j++)
4955 {
4956 ob_collections_group_programs_program();
4957 _edje_program_copy(current_program, pc2->programs.fnmatch[j]);
4958 }
4959 for (j = 0; j < pc2->programs.strcmp_count; j++)
4960 {
4961 ob_collections_group_programs_program();
4962 _edje_program_copy(current_program, pc2->programs.strcmp[j]);
4963 }
4964 for (j = 0; j < pc2->programs.strncmp_count; j++)
4965 {
4966 ob_collections_group_programs_program();
4967 _edje_program_copy(current_program, pc2->programs.strncmp[j]);
4968 }
4969 for (j = 0; j < pc2->programs.strrncmp_count; j++)
4970 {
4971 ob_collections_group_programs_program();
4972 _edje_program_copy(current_program, pc2->programs.strrncmp[j]);
4973 }
4974 for (j = 0; j < pc2->programs.nocmp_count; j++)
4975 {
4976 ob_collections_group_programs_program();
4977 _edje_program_copy(current_program, pc2->programs.nocmp[j]);
4978 }
4979
4980 Code *cd, *cd2;
4981 Code_Program *cp, *cp2;
4982 Edje_Part_Collection_Directory_Entry *de;
4983
4984 de = eina_hash_find(edje_file->collection, pc2->part);
4985 cd2 = eina_list_nth(codes, de->id);
4986 cd = eina_list_data_get(eina_list_last(codes));
4987
4988 cd->is_lua = cd2->is_lua;
4989 if (!cd2->is_lua)
4990 pcp->base_codes = eina_list_append(pcp->base_codes, cd2);
4991
4992 if (cd2->shared)
4993 {
4994 if (cd->shared)
4995 {
4996 WRN("%s:%i. script block in group \"%s\" will be overwritten by inheriting "
4997 "from group \"%s\".", file_in, line - 1, pc->part, pc2->part);
4998 free(cd->shared);
4999 }
5000 if (cd->original)
5001 free(cd->original);
5002
5003 cd->shared = STRDUP(cd2->shared);
5004 cd->original = STRDUP(cd2->original);
5005
5006 script_is_replaceable = EINA_TRUE;
5007 }
5008
5009 EINA_LIST_FOREACH(cd2->programs, l, cp2)
5010 {
5011 cp = mem_alloc(SZ(Code_Program));
5012
5013 cp->l1 = cp2->l1;
5014 cp->l2 = cp2->l2;
5015 cp->script = STRDUP(cp2->script);
5016 cp->original = STRDUP(cp2->original);
5017 cd->programs = eina_list_append(cd->programs, cp);
5018 data_queue_copied_anonymous_lookup(pc, &(cp2->id), &(cp->id));
5019 }
5020
5021 free(parent_name);
5022 }
5023
5024 /**
5025 @page edcref
5026 @property
5027 lua_script_only
5028 @parameters
5029 [on/off]
5030 @effect
5031 The flag (on/off) as to if this group is defined ONLY by script
5032 callbacks such as init(), resize() and shutdown()
5033
5034 Defaults: off
5035 @endproperty
5036 */
5037 static void
st_collections_group_lua_script_only(void)5038 st_collections_group_lua_script_only(void)
5039 {
5040 Edje_Part_Collection *pc;
5041
5042 check_arg_count(1);
5043
5044 pc = eina_list_data_get(eina_list_last(edje_collections));
5045 pc->lua_script_only = parse_bool(0);
5046 }
5047
5048 /**
5049 @page edcref
5050 @property
5051 script_recursion
5052 @parameters
5053 [1/0]
5054 @effect
5055 This flag (1/0) determines whether to error on unsafe calls when
5056 recursively running Embryo programs.
5057 For example, running an Embryo script which calls EDC which has a
5058 script{} block is unsafe, and the outer-most (first) Embryo stack is GUARANTEED
5059 to be corrupted. Only use this flag if you are sure that you know what you are doing.
5060
5061 Defaults: 0
5062 @since 1.10
5063 @endproperty
5064 */
5065 static void
st_collections_group_script_recursion(void)5066 st_collections_group_script_recursion(void)
5067 {
5068 Edje_Part_Collection *pc;
5069
5070 check_arg_count(1);
5071
5072 pc = eina_list_data_get(eina_list_last(edje_collections));
5073 pc->script_recursion = parse_bool(0);
5074 }
5075
5076 /**
5077 @page edcref
5078 @property
5079 alias
5080 @parameters
5081 [aditional group name]
5082 @effect
5083 Additional name to serve as identifier. Defining multiple aliases is
5084 supported.
5085 @endproperty
5086 */
5087 static void
st_collections_group_alias(void)5088 st_collections_group_alias(void)
5089 {
5090 Edje_Part_Collection_Directory_Entry *alias;
5091 Edje_Part_Collection_Directory_Entry *tmp;
5092 Eina_List *l;
5093
5094 check_arg_count(1);
5095
5096 alias = mem_alloc(SZ(Edje_Part_Collection_Directory_Entry));
5097 alias->id = current_de->id;
5098 alias->entry = parse_str(0);
5099 alias->group_alias = EINA_TRUE;
5100
5101 EINA_LIST_FOREACH(aliases, l, tmp)
5102 if (strcmp(alias->entry, tmp->entry) == 0)
5103 {
5104 Edje_Part_Collection *pc;
5105
5106 pc = eina_list_nth(edje_collections, tmp->id);
5107 INF("overriding alias ('%s' => '%s') to ('%s' => '%s')",
5108 tmp->entry, pc->part,
5109 alias->entry, current_de->entry);
5110 aliases = eina_list_remove_list(aliases, l);
5111 free(tmp);
5112 break;
5113 }
5114
5115 aliases = eina_list_append(aliases, alias);
5116 }
5117
5118 /**
5119 @page edcref
5120 @property
5121 min
5122 @parameters
5123 [width] [height]
5124 @effect
5125 The minimum size for the container defined by the composition of the
5126 parts. It is not enforced.
5127
5128 Defaults: 0 0
5129 @endproperty
5130 */
5131 static void
st_collections_group_min(void)5132 st_collections_group_min(void)
5133 {
5134 Edje_Part_Collection *pc;
5135
5136 check_arg_count(2);
5137
5138 pc = eina_list_data_get(eina_list_last(edje_collections));
5139 pc->prop.min.w = parse_int_range(0, 0, 0x7fffffff);
5140 pc->prop.min.h = parse_int_range(1, 0, 0x7fffffff);
5141 }
5142
5143 /**
5144 @page edcref
5145 @property
5146 max
5147 @parameters
5148 [width] [height]
5149 @effect
5150 The maximum size for the container defined by the totality of the
5151 parts. It is not enforced.
5152
5153 Defaults: 0 0
5154 @endproperty
5155 */
5156 static void
st_collections_group_max(void)5157 st_collections_group_max(void)
5158 {
5159 Edje_Part_Collection *pc;
5160
5161 check_arg_count(2);
5162
5163 pc = eina_list_data_get(eina_list_last(edje_collections));
5164 pc->prop.max.w = parse_int_range(0, 0, 0x7fffffff);
5165 pc->prop.max.h = parse_int_range(1, 0, 0x7fffffff);
5166 }
5167
5168 /**
5169 @page edcref
5170 @property
5171 broadcast_signal
5172 @parameters
5173 [on/off]
5174 @effect
5175 Signal got automatically broadcasted to all sub group part.
5176
5177 Defaults: true
5178 @since 1.1
5179 @endproperty
5180 */
5181 static void
st_collections_group_broadcast_signal(void)5182 st_collections_group_broadcast_signal(void)
5183 {
5184 Edje_Part_Collection *pc;
5185
5186 check_arg_count(1);
5187
5188 pc = eina_list_data_get(eina_list_last(edje_collections));
5189 pc->broadcast_signal = parse_bool(0);
5190 }
5191
5192 static void
st_collections_group_broadcast(void)5193 st_collections_group_broadcast(void)
5194 {
5195 Edje_Part_Collection *pc;
5196
5197 check_arg_count(0);
5198
5199 pc = eina_list_data_get(eina_list_last(edje_collections));
5200 pc->broadcast_signal = 1;
5201 }
5202
5203 static void
st_collections_group_nobroadcast(void)5204 st_collections_group_nobroadcast(void)
5205 {
5206 Edje_Part_Collection *pc;
5207
5208 check_arg_count(0);
5209
5210 pc = eina_list_data_get(eina_list_last(edje_collections));
5211 pc->broadcast_signal = 0;
5212 }
5213
5214 /**
5215 @page edcref
5216 @property
5217 orientation
5218 @parameters
5219 [AUTO/LTR/RTL]
5220 @effect
5221 This defines GROUP orientation.
5222 This is useful if you want match interface orientation with language.
5223 @li AUTO - Follow system defs.
5224 @li LTR - suitable for Left To Right Languages (latin)
5225 @li RTL - suitable for Right To Left Languages (Hebrew, Arabic interface)
5226
5227 Defaults: AUTO
5228 @endproperty
5229 */
5230 static void
st_collections_group_orientation(void)5231 st_collections_group_orientation(void)
5232 {
5233 Edje_Part_Collection *pc;
5234
5235 check_arg_count(1);
5236
5237 pc = eina_list_data_get(eina_list_last(edje_collections));
5238 pc->prop.orientation = parse_enum(0,
5239 "AUTO", EDJE_ORIENTATION_AUTO,
5240 "LTR", EDJE_ORIENTATION_LTR,
5241 "RTL", EDJE_ORIENTATION_RTL,
5242 NULL);
5243 }
5244
5245 /**
5246 @page edcref
5247 @property
5248 mouse_events
5249 @parameters
5250 [1 or 0]
5251 @effect
5252 Change the default value of mouse_events for every part in this group.
5253
5254 Defaults: 1 (to maintain compatibility)
5255 @endproperty
5256 */
5257 static void
st_collections_group_mouse_events(void)5258 st_collections_group_mouse_events(void)
5259 {
5260 Edje_Part_Collection_Parser *pcp;
5261
5262 check_arg_count(1);
5263
5264 pcp = eina_list_data_get(eina_list_last(edje_collections));
5265 pcp->default_mouse_events = parse_bool(0);
5266 }
5267
5268 static void
st_collections_group_mouse(void)5269 st_collections_group_mouse(void)
5270 {
5271 Edje_Part_Collection_Parser *pcp;
5272
5273 check_arg_count(0);
5274
5275 pcp = eina_list_data_get(eina_list_last(edje_collections));
5276 pcp->default_mouse_events = 1;
5277 }
5278
5279 static void
st_collections_group_nomouse(void)5280 st_collections_group_nomouse(void)
5281 {
5282 Edje_Part_Collection_Parser *pcp;
5283
5284 check_arg_count(0);
5285
5286 pcp = eina_list_data_get(eina_list_last(edje_collections));
5287 pcp->default_mouse_events = 0;
5288 }
5289
5290 /**
5291 @page edcref
5292 @property
5293 inherit_script
5294 @parameters
5295 [1 or 0]
5296 @effect
5297 Determine whether to inherit script block from parent group.
5298 If it is set to 0, script from parent group will be replaced with
5299 new script block.
5300 Defaults to 0 if not set, to maintain compatibility.
5301 @endproperty
5302 */
5303 static void
st_collections_group_inherit_script(void)5304 st_collections_group_inherit_script(void)
5305 {
5306 Edje_Part_Collection_Parser *pcp;
5307
5308 pcp = eina_list_last_data_get(edje_collections);
5309
5310 if (get_arg_count() == 1)
5311 pcp->inherit_script = parse_bool(0);
5312 else
5313 pcp->inherit_script = EINA_TRUE;
5314 }
5315
5316 static void
st_collections_group_noinherit_script(void)5317 st_collections_group_noinherit_script(void)
5318 {
5319 Edje_Part_Collection_Parser *pcp;
5320
5321 check_arg_count(0);
5322
5323 pcp = eina_list_last_data_get(edje_collections);
5324 pcp->inherit_script = EINA_FALSE;
5325 }
5326
5327 static void
_script_flush(void)5328 _script_flush(void)
5329 {
5330 Edje_Part_Collection_Parser *pcp;
5331 Code *code;
5332
5333 pcp = eina_list_last_data_get(edje_collections);
5334 code = eina_list_last_data_get(codes);
5335
5336 if (!pcp->inherit_script || code->is_lua) return;
5337
5338 // If script is replaceable and overridable, code->shared will be inherited
5339 // script. Free it to avoid duplication.
5340 if (script_is_replaceable)
5341 {
5342 if (code->shared)
5343 {
5344 free(code->shared);
5345 code->shared = NULL;
5346 }
5347 if (code->original)
5348 {
5349 free(code->original);
5350 code->original = NULL;
5351 }
5352 }
5353
5354 script_rewrite(code);
5355
5356 eina_list_free(pcp->base_codes);
5357 }
5358
5359 /**
5360 @page edcref
5361 @property
5362 program_source
5363 @parameters
5364 [source name]
5365 @effect
5366 Change the default value of source for every program in the current group
5367 which is declared after this value is set.
5368
5369 Defaults: an unset value (to maintain compatibility)
5370 @since 1.10
5371 @endproperty
5372 */
5373 static void
st_collections_group_program_source(void)5374 st_collections_group_program_source(void)
5375 {
5376 Edje_Part_Collection_Parser *pcp;
5377
5378 check_arg_count(1);
5379
5380 pcp = eina_list_last_data_get(edje_collections);
5381 free(pcp->default_source);
5382 pcp->default_source = parse_str(0);
5383 }
5384
5385 /** @edcsubsection{collections_group_script,
5386 * Group.Script} */
5387
5388 /**
5389 @page edcref
5390 @block
5391 script
5392 @context
5393 ..
5394 group {
5395 script {
5396 //embryo script
5397 }
5398 ..
5399 program {
5400 script {
5401 //embryo script
5402 }
5403 }
5404 ..
5405 }
5406 ..
5407 @description
5408 This block is used to "inject" embryo scripts to a given Edje theme and
5409 it functions in two modalities. When it's included inside a "program"
5410 block, the script will be executed every time the program is run, on
5411 the other hand, when included directly into a "group", "part" or
5412 "description" block, it will be executed once at load time, in the
5413 load order.
5414 @endblock
5415 */
5416 static void
ob_collections_group_script(void)5417 ob_collections_group_script(void)
5418 {
5419 Code *cd;
5420
5421 cd = eina_list_data_get(eina_list_last(codes));
5422
5423 if (!is_verbatim()) track_verbatim(1);
5424 else
5425 {
5426 char *s;
5427
5428 s = get_verbatim();
5429 if (s)
5430 {
5431 cd->l1 = get_verbatim_line1();
5432 cd->l2 = get_verbatim_line2();
5433 if (cd->shared)
5434 {
5435 if (script_is_replaceable)
5436 {
5437 free(cd->shared);
5438 free(cd->original);
5439 script_is_replaceable = EINA_FALSE;
5440 }
5441 else
5442 {
5443 ERR("parse error %s:%i. There is already an existing script section for the group",
5444 file_in, line - 1);
5445 exit(-1);
5446 }
5447 }
5448 cd->shared = s;
5449 cd->original = strdup(s);
5450 cd->is_lua = 0;
5451 set_verbatim(NULL, 0, 0);
5452 }
5453 }
5454 }
5455
5456 static void
ob_collections_group_lua_script(void)5457 ob_collections_group_lua_script(void)
5458 {
5459 Code *cd;
5460
5461 cd = eina_list_data_get(eina_list_last(codes));
5462
5463 if (!is_verbatim()) track_verbatim(1);
5464 else
5465 {
5466 char *s;
5467
5468 s = get_verbatim();
5469 if (s)
5470 {
5471 cd->l1 = get_verbatim_line1();
5472 cd->l2 = get_verbatim_line2();
5473 if (cd->shared)
5474 {
5475 ERR("parse error %s:%i. There is already an existing script section for the group",
5476 file_in, line - 1);
5477 exit(-1);
5478 }
5479 cd->shared = s;
5480 cd->is_lua = 1;
5481 set_verbatim(NULL, 0, 0);
5482 }
5483 }
5484 }
5485
5486 /** @edcsubsection{collections_group_data,
5487 * Group.Data} */
5488
5489 /**
5490 @page edcref
5491 @block
5492 data
5493 @context
5494 data {
5495 item: "key" "value";
5496 ..
5497 }
5498 @description
5499 The "data" block is used to pass arbitrary parameters from the theme to
5500 the application. Unlike the toplevel data block, this block Group.Data
5501 can only store inline items (not files).
5502 See also the toplevel @ref sec_toplevel_data "Data" section.
5503 @endblock
5504
5505 @property
5506 item
5507 @parameters
5508 [parameter name] [parameter value]
5509 @effect
5510 Defines a new parameter, the value will be the string specified next to
5511 it.
5512 @endproperty
5513 */
5514
5515 static void
st_collections_group_data_item(void)5516 st_collections_group_data_item(void)
5517 {
5518 Edje_Part_Collection *pc;
5519 Edje_String *es;
5520 char *key;
5521
5522 check_arg_count(2);
5523
5524 pc = eina_list_data_get(eina_list_last(edje_collections));
5525
5526 if (!pc->data)
5527 pc->data = eina_hash_string_small_new(free);
5528
5529 key = parse_str(0);
5530
5531 es = mem_alloc(SZ(Edje_String));
5532 es->str = parse_str(1);
5533
5534 if (eina_hash_find(pc->data, key))
5535 eina_hash_modify(pc->data, key, es);
5536 else
5537 eina_hash_direct_add(pc->data, key, es);
5538 }
5539
5540 /** @edcsubsection{collections_group_filters,
5541 * Group.Filters} */
5542
5543 /**
5544 @page edcref
5545 @block
5546 filters
5547 @context
5548 // (toplevel)
5549 // collections
5550 // collections.group
5551 filters {
5552 // Inline as script block:
5553 filter {
5554 name: "myfilter1";
5555 script {
5556 -- Some Lua code here, eg:
5557 blend { color = 'red' }
5558 }
5559 // Imported from an external file:
5560 filter {
5561 name: "myfilter2";
5562 file: "filename.lua";
5563 }
5564 }
5565 @description
5566 The "filter" block lets you embed filter scripts into an EDC group,
5567 that can then be referred to in the
5568 @ref sec_collections_group_parts_description_filter "Text.Filter"
5569 or @ref sec_collections_group_parts_description_filter "Image.Filter"
5570 statements.
5571
5572 In a similar way to the toplevel @ref sec_toplevel_data "Data" section,
5573 it is possible to embed filters from a external file inside the final EDJ.
5574
5575 Note that filters are defined globally, even if they appear inside a
5576 specific group (as of EFL 1.19).
5577
5578 Please also refer to @ref evasfiltersref "Evas filters reference".
5579 @endblock
5580
5581 @property
5582 name
5583 @parameters
5584 [name]
5585 @effect
5586 Creates a new named filter. This filter can then be used in image, text
5587 or textblock parts by name.
5588 @endproperty
5589
5590 @property
5591 script
5592 @parameters
5593 [Lua script]
5594 @effect
5595 A block of Lua code contained inside {}. Example: script { blur{5} }
5596 @endproperty
5597
5598 @property
5599 file
5600 @parameters
5601 [Path to Lua file]
5602 @effect
5603 Includes an external file to define a new Lua script used for filtering.
5604 The file must be in the data path passed to edje_cc (-dd argument).
5605 @endproperty
5606 */
5607
5608 static Edje_Gfx_Filter *current_filter = NULL;
5609
5610 static void
_filters_filter_sort(void)5611 _filters_filter_sort(void)
5612 {
5613 Edje_Gfx_Filter *array, current;
5614 int new_pos, i, cur_pos;
5615
5616 if (!current_filter)
5617 return;
5618
5619 if (!current_filter->name)
5620 {
5621 ERR("parse error %s:%i. Filter has no name.",
5622 file_in, line - 1);
5623 exit(-1);
5624 }
5625
5626 array = edje_file->filter_dir->filters;
5627 cur_pos = (current_filter - array);
5628
5629 // find position in sorted array
5630 for (new_pos = 0; new_pos < edje_file->filter_dir->filters_count - 1; new_pos++)
5631 {
5632 int cmp;
5633 if (cur_pos == new_pos)
5634 continue;
5635 cmp = strcmp(current_filter->name, array[new_pos].name);
5636 if (cmp == 0)
5637 {
5638 ERR("parse error %s:%i. Another filter named '%s' already exists.",
5639 file_in, line - 1, array[new_pos].name);
5640 exit(-1);
5641 }
5642 else if (cmp < 0)
5643 break;
5644 }
5645
5646 if (new_pos > cur_pos)
5647 new_pos--;
5648
5649 if (cur_pos == new_pos)
5650 return;
5651
5652 current = *current_filter;
5653
5654 // move up
5655 for (i = cur_pos - 1; i >= new_pos; i--)
5656 array[i + 1] = array[i];
5657
5658 // move down
5659 for (i = cur_pos; i < new_pos; i++)
5660 array[i] = array[i + 1];
5661
5662 array[new_pos] = current;
5663 current_filter = &array[new_pos];
5664 }
5665
5666 static void
ob_filters_filter(void)5667 ob_filters_filter(void)
5668 {
5669 Edje_Gfx_Filter *array;
5670
5671 _filters_filter_sort();
5672 if (!edje_file->filter_dir)
5673 edje_file->filter_dir = mem_alloc(sizeof(Edje_Gfx_Filter_Directory));
5674
5675 array = realloc(edje_file->filter_dir->filters,
5676 sizeof(Edje_Gfx_Filter) * (edje_file->filter_dir->filters_count + 1));
5677 if (!array)
5678 {
5679 ERR("Memory allocation failed (array grow)");
5680 exit(-1);
5681 }
5682
5683 current_filter = &array[edje_file->filter_dir->filters_count];
5684 memset(current_filter, 0, sizeof(Edje_Gfx_Filter));
5685 edje_file->filter_dir->filters_count++;
5686 edje_file->filter_dir->filters = array;
5687 }
5688
5689 static void
ob_filters_filter_script(void)5690 ob_filters_filter_script(void)
5691 {
5692 char *script;
5693
5694 if (!current_filter)
5695 ob_filters_filter();
5696
5697 if (!current_filter->name)
5698 {
5699 ERR("parse error %s:%i. Name for inline filter must be specified first.",
5700 file_in, line - 1);
5701 exit(-1);
5702 }
5703
5704 if (current_filter->script)
5705 {
5706 ERR("parse error %s:%i. Script for filter '%s' is already defined.",
5707 file_in, line - 1, current_filter->name);
5708 exit(-1);
5709 }
5710
5711 if (!is_verbatim())
5712 track_verbatim(1);
5713 else
5714 {
5715 script = get_verbatim();
5716 if (script)
5717 {
5718 //current_filter->verb_l1 = get_verbatim_line1();
5719 //current_filter->verb_l2 = get_verbatim_line2();
5720 current_filter->script = strdup(script);
5721 set_verbatim(NULL, 0, 0);
5722 _filters_filter_sort();
5723 current_filter = NULL;
5724 }
5725 }
5726 }
5727
5728 static void
st_filters_filter_file(void)5729 st_filters_filter_file(void)
5730 {
5731 char *file, *script;
5732 Eina_File *f;
5733 size_t sz;
5734
5735 if (!current_filter)
5736 ob_filters_filter();
5737
5738 if (current_filter->script)
5739 {
5740 ERR("parse error %s:%i. Script for filter '%s' is already defined.",
5741 file_in, line - 1, current_filter->name);
5742 exit(-1);
5743 }
5744
5745 check_arg_count(1);
5746
5747 file = parse_str(0);
5748 f = eina_file_open(file, EINA_FALSE);
5749 if (!f)
5750 {
5751 char path[PATH_MAX], *dir;
5752 Eina_List *l;
5753 // TODO: Introduce special filters_dir? needs new edje_cc argument :(
5754 EINA_LIST_FOREACH(data_dirs, l, dir)
5755 {
5756 snprintf(path, sizeof(path), "%s/%s", dir, file);
5757 f = eina_file_open(path, EINA_FALSE);
5758 if (f) break;
5759 }
5760 if (!f)
5761 {
5762 ERR("parse error %s:%i. Could not open filter script file '%s'",
5763 file_in, line - 1, file);
5764 exit(-1);
5765 }
5766 }
5767
5768 script = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
5769 if (!script)
5770 {
5771 ERR("parse error %s:%i. Could not read filter script file %s",
5772 file_in, line - 1, file);
5773 exit(-1);
5774 }
5775
5776 sz = eina_file_size_get(f);
5777 if (sz > (10 * 1024 * 1024))
5778 {
5779 ERR("parse error %s:%i. Filter file '%s' is unreasonably large, abort.",
5780 file_in, line - 1, file);
5781 exit(-1);
5782 }
5783
5784 current_filter->script = (char *)eina_memdup((unsigned char *)script, sz, 1);
5785 eina_file_map_free(f, script);
5786 eina_file_close(f);
5787
5788 if (!current_filter->name)
5789 {
5790 current_filter->name = file;
5791 _filters_filter_sort();
5792 }
5793 else
5794 {
5795 free(file);
5796 _filters_filter_sort();
5797 current_filter = NULL;
5798 }
5799 }
5800
5801 static void
st_filters_filter_name(void)5802 st_filters_filter_name(void)
5803 {
5804 if (!current_filter)
5805 ob_filters_filter();
5806
5807 check_arg_count(1);
5808
5809 current_filter->name = parse_str(0);
5810
5811 _filters_filter_sort();
5812 }
5813
5814 /** @edcsubsection{collections_group_limits,
5815 * Group.Limits} */
5816
5817 /**
5818 @page edcref
5819 @block
5820 limits
5821 @context
5822 group {
5823 limits {
5824 vertical: "limit_name" height_barrier;
5825 horizontal: "limit_name" width_barrier;
5826 ..
5827 }
5828 ..
5829 }
5830 ..
5831 @description
5832 This block is used to trigger some signal when the Edje object is resized.
5833 @endblock
5834
5835 @page edcref
5836 @property
5837 vertical
5838 @parameters
5839 [name] [height barrier]
5840 @effect
5841 It will send a signal: "limit,name,over" when the object is resized and pass
5842 the limit by growing over it. And it will send: "limit,name,below" when
5843 it pass below that limit.
5844 This limit will be applied on the y absis and is expressed in pixels.
5845 @endproperty
5846 */
5847 static void
st_collections_group_limits_vertical(void)5848 st_collections_group_limits_vertical(void)
5849 {
5850 Edje_Part_Collection *pc;
5851 Edje_Limit *el, **elp;
5852
5853 check_arg_count(2);
5854
5855 pc = eina_list_data_get(eina_list_last(edje_collections));
5856 pc->limits.vertical_count++;
5857 elp = realloc(pc->limits.vertical,
5858 pc->limits.vertical_count * sizeof (Edje_Limit *));
5859 if (!elp)
5860 {
5861 ERR("Not enough memory.");
5862 exit(-1);
5863 }
5864 pc->limits.vertical = elp;
5865
5866 el = mem_alloc(SZ(Edje_Limit));
5867 if (!el)
5868 {
5869 ERR("Not enough memory.");
5870 exit(-1);
5871 }
5872
5873 pc->limits.vertical[pc->limits.vertical_count - 1] = el;
5874
5875 el->name = parse_str(0);
5876 el->value = parse_int_range(1, 1, 0xffff);
5877 }
5878
5879 /**
5880 @page edcref
5881 @property
5882 horizontal
5883 @parameters
5884 [name] [width barrier]
5885 @effect
5886 It will send a signal: "limit,name,over" when the object is resized and pass
5887 the limit by growing over it. And it will send: "limit,name,below" when
5888 it pass below that limit.
5889 This limit will be applied on the x axis and is expressed in pixels.
5890 @endproperty
5891 */
5892 static void
st_collections_group_limits_horizontal(void)5893 st_collections_group_limits_horizontal(void)
5894 {
5895 Edje_Part_Collection *pc;
5896 Edje_Limit *el;
5897
5898 check_arg_count(2);
5899
5900 el = mem_alloc(SZ(Edje_Limit));
5901
5902 pc = eina_list_data_get(eina_list_last(edje_collections));
5903 pc->limits.horizontal_count++;
5904 pc->limits.horizontal = realloc(pc->limits.horizontal, pc->limits.horizontal_count * sizeof (Edje_Limit *));
5905 if (!pc->limits.horizontal || !el)
5906 {
5907 ERR("Not enough memory.");
5908 exit(-1);
5909 }
5910
5911 pc->limits.horizontal[pc->limits.horizontal_count - 1] = el;
5912
5913 el->name = parse_str(0);
5914 el->value = parse_int_range(1, 1, 0xffff);
5915 }
5916
5917 /** @edcsubsection{collections_group_parts,
5918 * Group.Parts} */
5919
5920 /**
5921 @page edcref
5922 @block
5923 parts
5924 @context
5925 group {
5926 parts {
5927 alias: "theme_part_path" "somegroup:real_part_path";
5928 part { "theme_part_path"; }
5929 part { }
5930 ..
5931 }
5932 }
5933 @description
5934 The parts block is the container for all the parts in the group.
5935
5936 @property
5937 alias
5938 @parameters
5939 [alias name] [other_group:part name]
5940 @effect
5941 Allows for a part to be referenced externally as though
5942 it had the name of the alias.
5943 In the above example, swallowing an object into part "theme_part_path"
5944 will result in the object actually being swallowed into the part
5945 "real_part_path" in the "somegroup" group.
5946 @endproperty
5947 @endblock
5948 */
5949 static void
st_collections_group_parts_alias(void)5950 st_collections_group_parts_alias(void)
5951 {
5952 Edje_Part_Collection *pc;
5953 const char *alias;
5954 const char *aliased;
5955
5956 check_arg_count(2);
5957
5958 pc = eina_list_data_get(eina_list_last(edje_collections));
5959
5960 alias = parse_str(0);
5961 aliased = parse_str(1);
5962
5963 if (!pc->alias) pc->alias = eina_hash_string_small_new(NULL);
5964 eina_hash_add(pc->alias, alias, aliased);
5965
5966 if (!pc->aliased) pc->aliased = eina_hash_string_small_new(NULL);
5967 eina_hash_add(pc->aliased, aliased, alias);
5968 }
5969
5970 /** @edcsubsection{collections_group_parts_part,
5971 * Group.Parts.Part} */
5972
5973 /**
5974 @page edcref
5975 @block
5976 part
5977 @context
5978 group {
5979 parts {
5980 ..
5981 part {
5982 name: "partname";
5983 type: IMAGE;
5984 mouse_events: 1;
5985 repeat_events: 0;
5986 ignore_flags: NONE;
5987 mask_flags: NONE;
5988 clip_to: "anotherpart";
5989 source: "groupname";
5990 pointer_mode: AUTOGRAB;
5991 use_alternate_font_metrics: 0;
5992 no_render: 0;
5993
5994 dragable { }
5995 items { }
5996 description { }
5997 }
5998 ..
5999 }
6000 }
6001 @description
6002 Parts are used to represent the most basic design elements of the
6003 theme, for example, a part can represent a line in a border or a label
6004 on a button.
6005 @endblock
6006 */
6007 static Edje_Part *
edje_cc_handlers_part_make(int id)6008 edje_cc_handlers_part_make(int id)
6009 { /* Doing ob_collections_group_parts_part() job, without hierarchy */
6010 Edje_Part_Collection *pc;
6011 Edje_Part_Collection_Parser *pcp;
6012 Edje_Part *ep;
6013 Edje_Part_Parser *epp;
6014
6015 ep = mem_alloc(SZ(Edje_Part_Parser));
6016
6017 pc = eina_list_data_get(eina_list_last(edje_collections));
6018 if (id < 0)
6019 {
6020 pc->parts_count++;
6021 pc->parts = realloc(pc->parts, pc->parts_count * sizeof (Edje_Part *));
6022 if (!pc->parts)
6023 {
6024 ERR("Not enough memory.");
6025 exit(-1);
6026 }
6027 id = pc->parts_count - 1;
6028 }
6029
6030 current_part = pc->parts[id] = ep;
6031 pcp = (Edje_Part_Collection_Parser *)pc;
6032
6033 ep->id = id;
6034 ep->type = EDJE_PART_TYPE_IMAGE;
6035 ep->mouse_events = pcp->default_mouse_events;
6036 ep->anti_alias = 1;
6037 ep->repeat_events = 0;
6038 ep->ignore_flags = EVAS_EVENT_FLAG_NONE;
6039 ep->mask_flags = EVAS_EVENT_FLAG_NONE;
6040 ep->scale = 0;
6041 ep->pointer_mode = EVAS_OBJECT_POINTER_MODE_AUTOGRAB;
6042 ep->precise_is_inside = 0;
6043 ep->use_alternate_font_metrics = 0;
6044 ep->access = 0;
6045 ep->clip_to_id = -1;
6046 ep->no_render = 0;
6047 ep->required = 0;
6048 ep->dragable.confine_id = -1;
6049 ep->dragable.threshold_id = -1;
6050 ep->dragable.event_id = -1;
6051 ep->items = NULL;
6052 ep->nested_children_count = 0;
6053
6054 ep->allowed_seats = NULL;
6055 ep->allowed_seats_count = 0;
6056
6057 epp = (Edje_Part_Parser *)ep;
6058 epp->reorder.insert_before = NULL;
6059 epp->reorder.insert_after = NULL;
6060 epp->reorder.before = NULL;
6061 epp->reorder.after = NULL;
6062 epp->reorder.linked_prev = 0;
6063 epp->reorder.linked_next = 0;
6064 epp->reorder.done = EINA_FALSE;
6065 epp->can_override = EINA_FALSE;
6066
6067 return ep;
6068 }
6069
6070 static void *
_part_desc_free(Edje_Part_Collection * pc,Edje_Part * ep,Edje_Part_Description_Common * ed)6071 _part_desc_free(Edje_Part_Collection *pc,
6072 Edje_Part *ep,
6073 Edje_Part_Description_Common *ed)
6074 {
6075 if (!ed) return NULL;
6076
6077 eina_hash_del_by_key(desc_hash, &ed);
6078
6079 part_lookup_del(pc, &(ed->rel1.id_x));
6080 part_lookup_del(pc, &(ed->rel1.id_y));
6081 part_lookup_del(pc, &(ed->rel2.id_x));
6082 part_lookup_del(pc, &(ed->rel2.id_y));
6083 part_lookup_del(pc, &(ed->clip_to_id));
6084 part_lookup_del(pc, &(ed->map.id_persp));
6085 part_lookup_del(pc, &(ed->map.id_light));
6086 part_lookup_del(pc, &(ed->map.rot.id_center));
6087 part_lookup_del(pc, &(ed->map.zoom.id_center));
6088
6089 switch (ep->type)
6090 {
6091 case EDJE_PART_TYPE_SPACER:
6092 case EDJE_PART_TYPE_RECTANGLE:
6093 case EDJE_PART_TYPE_SWALLOW:
6094 case EDJE_PART_TYPE_GROUP:
6095 /* Nothing todo, this part only have a common description. */
6096 break;
6097
6098 case EDJE_PART_TYPE_BOX:
6099 case EDJE_PART_TYPE_TABLE:
6100 case EDJE_PART_TYPE_IMAGE:
6101 case EDJE_PART_TYPE_SNAPSHOT:
6102 case EDJE_PART_TYPE_VECTOR:
6103 /* Nothing todo here */
6104 break;
6105
6106 case EDJE_PART_TYPE_TEXT:
6107 case EDJE_PART_TYPE_TEXTBLOCK:
6108 {
6109 Edje_Part_Description_Text *ted = (Edje_Part_Description_Text *)ed;
6110
6111 part_lookup_del(pc, &(ted->text.id_source));
6112 part_lookup_del(pc, &(ted->text.id_text_source));
6113 break;
6114 }
6115
6116 case EDJE_PART_TYPE_PROXY:
6117 {
6118 Edje_Part_Description_Proxy *ped = (Edje_Part_Description_Proxy *)ed;
6119
6120 part_lookup_del(pc, &(ped->proxy.id));
6121 break;
6122 }
6123 }
6124
6125 free((void *)ed->state.name);
6126 free(ed);
6127 return NULL;
6128 }
6129
6130 static void
_part_type_set(unsigned int type)6131 _part_type_set(unsigned int type)
6132 {
6133 /* handle type change of inherited part */
6134 if (type != current_part->type)
6135 {
6136 Edje_Part_Description_Common *new, *previous, *cur;
6137 Edje_Part_Collection *pc;
6138 Edje_Part *ep, *dummy;
6139 unsigned int i;
6140
6141 /* we don't free old part as we don't remove all reference to them */
6142 part_description_image_cleanup(current_part);
6143 current_part->type = type;
6144
6145 pc = eina_list_data_get(eina_list_last(edje_collections));
6146 ep = current_part;
6147
6148 previous = ep->default_desc;
6149 cur = current_desc;
6150 dummy = mem_alloc(SZ(Edje_Part));
6151 /* ensure type is incompatible with new type */
6152 dummy->type = ep->type + 2;
6153 if (previous)
6154 {
6155 new = _edje_part_description_alloc(type, pc->part, ep->name);
6156 eina_hash_add(desc_hash, &new, ep);
6157 eina_hash_set(desc_hash, &previous, dummy);
6158 parent_desc = previous;
6159 current_desc = new;
6160 new->state.name = strdup(previous->state.name);
6161 new->state.value = previous->state.value;
6162 st_collections_group_parts_part_description_inherit();
6163 parent_desc = NULL;
6164 _part_desc_free(pc, ep, previous);
6165
6166 ep->default_desc = new;
6167 }
6168
6169 for (i = 0; i < ep->other.desc_count; i++)
6170 {
6171 previous = ep->other.desc[i];
6172 new = _edje_part_description_alloc(type, pc->part, ep->name);
6173 eina_hash_add(desc_hash, &new, ep);
6174 eina_hash_set(desc_hash, &previous, dummy);
6175 parent_desc = previous;
6176 current_desc = new;
6177 new->state.name = strdup(previous->state.name);
6178 new->state.value = previous->state.value;
6179 st_collections_group_parts_part_description_inherit();
6180 parent_desc = NULL;
6181 _part_desc_free(pc, ep, previous);
6182 ep->other.desc[i] = new;
6183 }
6184 free(dummy);
6185 current_desc = cur;
6186 }
6187
6188 _parts_count_update(current_part->type, 1);
6189 }
6190
6191 static void
_part_create(void)6192 _part_create(void)
6193 {
6194 Edje_Part *cp = current_part; /* Save to restore on pop */
6195 Edje_Part *ep = edje_cc_handlers_part_make(-1); /* This changes current_part */
6196 Edje_Part *prnt;
6197
6198 /* Add this new part to hierarchy stack (removed part finished parse) */
6199 edje_cc_handlers_hierarchy_push(ep, cp);
6200
6201 prnt = edje_cc_handlers_hierarchy_parent_get();
6202 if (prnt) /* This is the child of parent in stack */
6203 prnt->nested_children_count++;
6204 }
6205
6206 static void
ob_collections_group_parts_part_short(void)6207 ob_collections_group_parts_part_short(void)
6208 {
6209 unsigned int type;
6210
6211 type = parse_enum(-1,
6212 "none", EDJE_PART_TYPE_NONE,
6213 "rect", EDJE_PART_TYPE_RECTANGLE,
6214 "text", EDJE_PART_TYPE_TEXT,
6215 "image", EDJE_PART_TYPE_IMAGE,
6216 "swallow", EDJE_PART_TYPE_SWALLOW,
6217 "textblock", EDJE_PART_TYPE_TEXTBLOCK,
6218 "group", EDJE_PART_TYPE_GROUP,
6219 "box", EDJE_PART_TYPE_BOX,
6220 "table", EDJE_PART_TYPE_TABLE,
6221 "external", EDJE_PART_TYPE_EXTERNAL,
6222 "proxy", EDJE_PART_TYPE_PROXY,
6223 "spacer", EDJE_PART_TYPE_SPACER,
6224 "snapshot", EDJE_PART_TYPE_SNAPSHOT,
6225 "vector", EDJE_PART_TYPE_VECTOR,
6226 NULL);
6227
6228 stack_replace_quick("part");
6229 _part_create();
6230 _part_type_set(type);
6231 }
6232
6233 static void
ob_collections_group_parts_part(void)6234 ob_collections_group_parts_part(void)
6235 {
6236 _part_create();
6237 }
6238
6239 static void *
_part_free(Edje_Part_Collection * pc,Edje_Part * ep)6240 _part_free(Edje_Part_Collection *pc, Edje_Part *ep)
6241 {
6242 Edje_Part_Parser *epp = (Edje_Part_Parser *)ep;
6243 unsigned int j;
6244
6245 part_lookup_del(pc, &(ep->clip_to_id));
6246 part_lookup_del(pc, &(ep->dragable.confine_id));
6247 part_lookup_del(pc, &(ep->dragable.threshold_id));
6248 part_lookup_del(pc, &(ep->dragable.event_id));
6249
6250 _part_desc_free(pc, ep, ep->default_desc);
6251 for (j = 0; j < ep->other.desc_count; j++)
6252 _part_desc_free(pc, ep, ep->other.desc[j]);
6253
6254 for (j = 0; j < ep->items_count; j++)
6255 free(ep->items[j]);
6256 free(ep->items);
6257
6258 for (j = 0; j < ep->allowed_seats_count; j++)
6259 {
6260 free((void *)(ep->allowed_seats[j]->name));
6261 free(ep->allowed_seats[j]);
6262 }
6263 free(ep->allowed_seats);
6264
6265 free((void *)ep->name);
6266 free((void *)ep->source);
6267 free((void *)ep->source2);
6268 free((void *)ep->source3);
6269 free((void *)ep->source4);
6270 free((void *)ep->source5);
6271 free((void *)ep->source6);
6272
6273 free((void *)epp->reorder.insert_before);
6274 free((void *)epp->reorder.insert_after);
6275
6276 free((void *)ep->api.name);
6277 free((void *)ep->api.description);
6278
6279 free(ep->other.desc);
6280 free(ep);
6281 return NULL;
6282 }
6283
6284 /**
6285 @page edcref
6286 @property
6287 inherit
6288 @parameters
6289 [part name]
6290 @effect
6291 Copies all attributes except part name from referenced part into current part.
6292 ALL existing attributes, except part name, are overwritten.
6293 @warning When inheriting any parts, descriptions without state names are NOT
6294 allowed.
6295 @since 1.10
6296 @endproperty
6297 */
6298 static void
st_collections_group_parts_part_inherit(void)6299 st_collections_group_parts_part_inherit(void)
6300 {
6301 char *name;
6302 Edje_Part_Collection *pc;
6303 unsigned int i;
6304
6305 check_arg_count(1);
6306
6307 name = parse_str(0);
6308 pc = eina_list_data_get(eina_list_last(edje_collections));
6309 for (i = 0; i < pc->parts_count; i++)
6310 {
6311 int id = current_part->id;
6312 const char *pname;
6313
6314 if (strcmp(pc->parts[i]->name, name)) continue;
6315 if (pc->parts[i] == current_part)
6316 {
6317 ERR("Cannot inherit from same part '%s' in group '%s'", name, current_de->entry);
6318 free(name);
6319 exit(-1);
6320 }
6321 pname = current_part->name;
6322 current_part->name = NULL;
6323 current_part = _part_free(pc, current_part);
6324 edje_cc_handlers_part_make(id);
6325 _part_copy(current_part, pc->parts[i]);
6326 free((void *)current_part->name);
6327 current_part->name = pname;
6328 free(name);
6329 return;
6330 }
6331
6332 ERR("Cannot inherit non-existing part '%s' in group '%s'", name, current_de->entry);
6333 free(name);
6334 exit(-1);
6335 }
6336
6337 static void
_program_free(Edje_Program * pr)6338 _program_free(Edje_Program *pr)
6339 {
6340 Edje_Part_Collection *pc;
6341 Edje_Program_Target *prt;
6342 Edje_Program_After *pa;
6343
6344 pc = eina_list_last_data_get(edje_collections);
6345
6346 free((void *)pr->name);
6347 free((void *)pr->signal);
6348 free((void *)pr->source);
6349 free((void *)pr->filter.part);
6350 free((void *)pr->filter.state);
6351 free((void *)pr->seat);
6352 free((void *)pr->state);
6353 free((void *)pr->state2);
6354 free((void *)pr->sample_name);
6355 free((void *)pr->tone_name);
6356 EINA_LIST_FREE(pr->targets, prt)
6357 {
6358 part_lookup_del(pc, &prt->id);
6359 free(prt);
6360 }
6361 EINA_LIST_FREE(pr->after, pa)
6362 free(pa);
6363 free(pr);
6364 }
6365
6366 static Eina_Bool
_program_remove(const char * name,Edje_Program ** pgrms,unsigned int count)6367 _program_remove(const char *name, Edje_Program **pgrms, unsigned int count)
6368 {
6369 unsigned int i;
6370 Edje_Part_Collection *pc;
6371
6372 pc = eina_list_last_data_get(edje_collections);
6373
6374 for (i = 0; i < count; ++i)
6375 if (pgrms[i]->name && (!strcmp(name, pgrms[i]->name)))
6376 {
6377 Edje_Program *pr = pgrms[i];
6378
6379 if (pr->after)
6380 {
6381 Eina_List *l;
6382 Edje_Program_After *pa;
6383
6384 EINA_LIST_FOREACH(pr->after, l, pa)
6385 {
6386 copied_program_lookup_delete(pc, (char *)(pa + 1));
6387 }
6388 }
6389
6390 _edje_program_remove(pc, pr);
6391
6392 if (pr->action == EDJE_ACTION_TYPE_SCRIPT)
6393 {
6394 anonymous_delete = &pr->id;
6395 }
6396
6397 _program_free(pr);
6398 return EINA_TRUE;
6399 }
6400 return EINA_FALSE;
6401 }
6402
6403 static Eina_Bool
_part_name_check(void)6404 _part_name_check(void)
6405 {
6406 unsigned int i;
6407 Edje_Part_Collection *pc;
6408 Edje_Part *ep = current_part;
6409
6410 if (!ep->name) return EINA_FALSE;
6411
6412 pc = eina_list_data_get(eina_list_last(edje_collections));
6413
6414 for (i = 0; i < (pc->parts_count - 1); i++)
6415 { /* Compare name only if did NOT updated ep from hircy pop */
6416 if ((ep != pc->parts[i]) &&
6417 (pc->parts[i]->name &&
6418 (!strcmp(pc->parts[i]->name, ep->name))))
6419 {
6420 Edje_Part_Parser *epp;
6421
6422 epp = (Edje_Part_Parser *)pc->parts[i];
6423 if (!epp->can_override)
6424 {
6425 ERR("parse error %s:%i. There is already a part of the name %s",
6426 file_in, line - 1, ep->name);
6427 exit(-1);
6428 }
6429 else
6430 {
6431 pc->parts_count--;
6432 pc->parts = realloc(pc->parts, pc->parts_count * sizeof (Edje_Part *));
6433 current_part = pc->parts[i];
6434 edje_cc_handlers_hierarchy_rename(ep, current_part);
6435 free(ep);
6436 epp->can_override = EINA_FALSE;
6437 break;
6438 }
6439 }
6440 }
6441 return EINA_TRUE;
6442 }
6443
6444 /**
6445 @page edcref
6446 @property
6447 name
6448 @parameters
6449 [part name]
6450 @effect
6451 The part's name will be used as reference in the theme's relative
6452 positioning system, by programs and in some cases by the application.
6453 It must be unique within the group.
6454 @endproperty
6455 */
6456 static void
st_collections_group_parts_part_name(void)6457 st_collections_group_parts_part_name(void)
6458 {
6459 Edje_Part *ep;
6460
6461 check_arg_count(1);
6462
6463 ep = current_part;
6464 ep->name = parse_str(0);
6465 _part_name_check();
6466 }
6467
6468 /**
6469 @page edcref
6470 @property
6471 type
6472 @parameters
6473 [TYPE]
6474 @effect
6475 Set the type (all caps) from among the available types, it's set to
6476 IMAGE by default. Valid types:
6477 @li RECT
6478 @li TEXT
6479 @li IMAGE
6480 @li SWALLOW
6481 @li TEXTBLOCK
6482 @li GROUP
6483 @li BOX
6484 @li TABLE
6485 @li EXTERNAL
6486 @li PROXY
6487 @li SPACER
6488 @li SNAPSHOT
6489
6490 Defaults: IMAGE
6491 @endproperty
6492 */
6493 static void
st_collections_group_parts_part_type(void)6494 st_collections_group_parts_part_type(void)
6495 {
6496 unsigned int type;
6497
6498 check_arg_count(1);
6499
6500 type = parse_enum(0,
6501 "NONE", EDJE_PART_TYPE_NONE,
6502 "RECT", EDJE_PART_TYPE_RECTANGLE,
6503 "TEXT", EDJE_PART_TYPE_TEXT,
6504 "IMAGE", EDJE_PART_TYPE_IMAGE,
6505 "SWALLOW", EDJE_PART_TYPE_SWALLOW,
6506 "TEXTBLOCK", EDJE_PART_TYPE_TEXTBLOCK,
6507 "GROUP", EDJE_PART_TYPE_GROUP,
6508 "BOX", EDJE_PART_TYPE_BOX,
6509 "TABLE", EDJE_PART_TYPE_TABLE,
6510 "EXTERNAL", EDJE_PART_TYPE_EXTERNAL,
6511 "PROXY", EDJE_PART_TYPE_PROXY,
6512 "SPACER", EDJE_PART_TYPE_SPACER,
6513 "SNAPSHOT", EDJE_PART_TYPE_SNAPSHOT,
6514 "VECTOR", EDJE_PART_TYPE_VECTOR,
6515 NULL);
6516
6517 _part_type_set(type);
6518 }
6519
6520 /**
6521 @page edcref
6522 @property
6523 physics_body
6524 @parameters
6525 [TYPE]
6526 @effect
6527 Set the type (all caps) from among the available types of physics
6528 body, it's set to NONE by default. If type is NONE no physics
6529 will be applied and physics block inside part will be discarded.
6530 Valid types:
6531 @li NONE
6532 @li RIGID_BOX
6533 @li RIGID_SPHERE
6534 @li RIGID_CYLINDER
6535 @li SOFT_BOX
6536 @li SOFT_SPHERE
6537 @li SOFT_CYLINDER
6538 @li CLOTH
6539 @li BOUNDARY_TOP
6540 @li BOUNDARY_BOTTOM
6541 @li BOUNDARY_RIGHT
6542 @li BOUNDARY_LEFT
6543 @li BOUNDARY_FRONT
6544 @li BOUNDARY_BACK
6545
6546 Defaults: NONE
6547 @since 1.8
6548 @endproperty
6549 */
6550 #ifdef HAVE_EPHYSICS
6551 static void
st_collections_group_parts_part_physics_body(void)6552 st_collections_group_parts_part_physics_body(void)
6553 {
6554 unsigned int body;
6555
6556 check_arg_count(1);
6557
6558 body = parse_enum(0,
6559 "NONE", EDJE_PART_PHYSICS_BODY_NONE,
6560 "RIGID_BOX", EDJE_PART_PHYSICS_BODY_RIGID_BOX,
6561 "RIGID_SPHERE", EDJE_PART_PHYSICS_BODY_RIGID_SPHERE,
6562 "RIGID_CYLINDER", EDJE_PART_PHYSICS_BODY_RIGID_CYLINDER,
6563 "SOFT_BOX", EDJE_PART_PHYSICS_BODY_SOFT_BOX,
6564 "SOFT_SPHERE", EDJE_PART_PHYSICS_BODY_SOFT_SPHERE,
6565 "SOFT_CYLINDER", EDJE_PART_PHYSICS_BODY_SOFT_CYLINDER,
6566 "CLOTH", EDJE_PART_PHYSICS_BODY_CLOTH,
6567 "BOUNDARY_TOP", EDJE_PART_PHYSICS_BODY_BOUNDARY_TOP,
6568 "BOUNDARY_BOTTOM", EDJE_PART_PHYSICS_BODY_BOUNDARY_BOTTOM,
6569 "BOUNDARY_RIGHT", EDJE_PART_PHYSICS_BODY_BOUNDARY_RIGHT,
6570 "BOUNDARY_LEFT", EDJE_PART_PHYSICS_BODY_BOUNDARY_LEFT,
6571 "BOUNDARY_FRONT", EDJE_PART_PHYSICS_BODY_BOUNDARY_FRONT,
6572 "BOUNDARY_BACK", EDJE_PART_PHYSICS_BODY_BOUNDARY_BACK,
6573 NULL);
6574
6575 current_part->physics_body = body;
6576
6577 if (body)
6578 {
6579 Edje_Part_Collection *pc;
6580 pc = eina_list_data_get(eina_list_last(edje_collections));
6581 pc->physics_enabled = 1;
6582 }
6583 }
6584
6585 #endif
6586
6587 /**
6588 @page edcref
6589 @property
6590 part
6591 @parameters
6592 [part declaration]
6593 @effect
6594 @code
6595 group {
6596 parts {
6597 part {
6598 name: "parent_rect";
6599 type: RECT;
6600 description { }
6601 part {
6602 name: "nested_rect";
6603 type: RECT;
6604 description { }
6605 }
6606 }
6607 ..
6608 }
6609 }
6610 @endcode
6611 Nested parts adds hierarchy to edje.
6612 Nested part inherits it's location relatively to the parent part.
6613 To declare a nested part just start a new part within current part decl.
6614 You must define parent part name before adding nested parts.
6615 @since 1.7
6616 @endproperty
6617 */
6618
6619 /**
6620 @page edcref
6621 @property
6622 insert_before
6623 @parameters
6624 [another part's name]
6625 @effect
6626 The part's name which this part is inserted before. One part cannot
6627 have both insert_before and insert_after. One part cannot refer
6628 more than one by insert_before.
6629 @since 1.1
6630 @endproperty
6631 */
6632 static void
st_collections_group_parts_part_insert_before(void)6633 st_collections_group_parts_part_insert_before(void)
6634 {
6635 Edje_Part_Parser *epp;
6636
6637 check_arg_count(1);
6638
6639 epp = (Edje_Part_Parser *)current_part;
6640 epp->reorder.insert_before = parse_str(0);
6641 }
6642
6643 /**
6644 @page edcref
6645 @property
6646 insert_after
6647 @parameters
6648 [another part's name]
6649 @effect
6650 The part's name which this part is inserted after. One part cannot
6651 have both insert_before and insert_after. One part cannot refer
6652 more than one by insert_after.
6653 @since 1.1
6654 @endproperty
6655 */
6656 static void
st_collections_group_parts_part_insert_after(void)6657 st_collections_group_parts_part_insert_after(void)
6658 {
6659 Edje_Part_Parser *epp;
6660
6661 check_arg_count(1);
6662
6663 epp = (Edje_Part_Parser *)current_part;
6664 epp->reorder.insert_after = parse_str(0);
6665 }
6666
6667 /**
6668 @page edcref
6669 @property
6670 mouse_events
6671 @parameters
6672 [1 or 0]
6673 @effect
6674 Specifies whether the part will emit signals, although it is named
6675 "mouse_events", disabling it (0) will prevent the part from emitting
6676 any type of signal at all.
6677
6678 Defaults: group.mouse_events
6679 @endproperty
6680 */
6681 static void
st_collections_group_parts_part_mouse_events(void)6682 st_collections_group_parts_part_mouse_events(void)
6683 {
6684 check_arg_count(1);
6685
6686 current_part->mouse_events = parse_bool(0);
6687 }
6688
6689 static void
st_collections_group_parts_part_mouse(void)6690 st_collections_group_parts_part_mouse(void)
6691 {
6692 check_arg_count(0);
6693 current_part->mouse_events = 1;
6694 }
6695
6696 static void
st_collections_group_parts_part_nomouse(void)6697 st_collections_group_parts_part_nomouse(void)
6698 {
6699 check_arg_count(0);
6700 current_part->mouse_events = 0;
6701 }
6702
6703 /**
6704 @page edcref
6705 @property
6706 anti_alias
6707 @parameters
6708 [1 or 0]
6709 @effect
6710 Takes a boolean value specifying whether part is anti_alias (1) or not (0).
6711
6712 Defaults: 1
6713 @endproperty
6714 */
6715 static void
st_collections_group_parts_part_anti_alias(void)6716 st_collections_group_parts_part_anti_alias(void)
6717 {
6718 check_arg_count(1);
6719 current_part->anti_alias = parse_bool(0);
6720 }
6721
6722 /**
6723 @page edcref
6724 @property
6725 repeat_events
6726 @parameters
6727 [1 or 0]
6728 @effect
6729 Specifies whether a part echoes a mouse event to other parts below the
6730 pointer (1), or not (0)
6731
6732 Defaults: 0
6733 @endproperty
6734 */
6735 static void
st_collections_group_parts_part_repeat_events(void)6736 st_collections_group_parts_part_repeat_events(void)
6737 {
6738 check_arg_count(1);
6739
6740 current_part->repeat_events = parse_bool(0);
6741 }
6742
6743 static void
st_collections_group_parts_part_repeat(void)6744 st_collections_group_parts_part_repeat(void)
6745 {
6746 check_arg_count(0);
6747
6748 current_part->repeat_events = 1;
6749 }
6750
6751 static void
st_collections_group_parts_part_norepeat(void)6752 st_collections_group_parts_part_norepeat(void)
6753 {
6754 check_arg_count(0);
6755
6756 current_part->repeat_events = 0;
6757 }
6758
6759 /**
6760 @page edcref
6761 @property
6762 ignore_flags
6763 @parameters
6764 [FLAG] ...
6765 @effect
6766 Specifies whether events with the given flags should be ignored,
6767 i.e., will not have the signals emitted to the parts. Multiple flags
6768 must be separated by spaces, the effect will be ignoring all events
6769 with one of the flags specified.
6770 Possible flags:
6771 @li NONE (no event will be ignored)
6772 @li ON_HOLD
6773
6774 Defaults: NONE
6775 @endproperty
6776 */
6777 static void
st_collections_group_parts_part_ignore_flags(void)6778 st_collections_group_parts_part_ignore_flags(void)
6779 {
6780 check_min_arg_count(1);
6781
6782 current_part->ignore_flags = parse_flags(0,
6783 "NONE", EVAS_EVENT_FLAG_NONE,
6784 "ON_HOLD", EVAS_EVENT_FLAG_ON_HOLD,
6785 NULL);
6786 }
6787
6788 /**
6789 @page edcref
6790 @property
6791 mask_flags
6792 @parameters
6793 [FLAG] ...
6794 @effect
6795 Masks event flags with the given value, so that the event can be repeated
6796 to the lower object along with masked event flags.
6797 Possible flags:
6798 @li NONE (no event will be masked)
6799 @li ON_HOLD
6800
6801 Defaults: NONE
6802 @endproperty
6803 */
6804 static void
st_collections_group_parts_part_mask_flags(void)6805 st_collections_group_parts_part_mask_flags(void)
6806 {
6807 check_min_arg_count(1);
6808
6809 current_part->mask_flags = parse_flags(0,
6810 "NONE", EVAS_EVENT_FLAG_NONE,
6811 "ON_HOLD", EVAS_EVENT_FLAG_ON_HOLD,
6812 NULL);
6813 }
6814
6815 /**
6816 @page edcref
6817 @property
6818 scale
6819 @parameters
6820 [1 or 0]
6821 @effect
6822 Specifies whether the part will scale its size with an edje scaling
6823 factor. By default scale is off (0) and the default scale factor is
6824 1.0 - that means no scaling. This would be used to scale properties
6825 such as font size, min/max size of the part, and possibly can be used
6826 to scale based on DPI of the target device. The reason to be selective
6827 is that some things work well being scaled, others do not, so the
6828 designer gets to choose what works best. For MESH_NODE parts three
6829 parameters specify how much the part will stretched along each axis.
6830
6831 Defaults: 0
6832 @endproperty
6833 */
6834 static void
st_collections_group_parts_part_scale(void)6835 st_collections_group_parts_part_scale(void)
6836 {
6837 if (get_arg_count() == 1)
6838 current_part->scale = parse_bool(0);
6839 else
6840 current_part->scale = 1;
6841 }
6842
6843 static void
st_collections_group_parts_part_noscale(void)6844 st_collections_group_parts_part_noscale(void)
6845 {
6846 check_arg_count(0);
6847 current_part->scale = 0;
6848 }
6849
6850 /**
6851 @page edcref
6852 @property
6853 pointer_mode
6854 @parameters
6855 [MODE]
6856 @effect
6857 Sets the mouse pointer behavior for a given part. Aviable modes:
6858 @li AUTOGRAB, when the part is clicked and the button remains
6859 pressed, the part will be the source of all future mouse
6860 signals emitted, even outside the object, until the button is
6861 released.
6862 @li NOGRAB, the effect will be limited to the part's container.
6863
6864 Defaults: AUTOGRAB
6865 @endproperty
6866 */
6867 static void
st_collections_group_parts_part_pointer_mode(void)6868 st_collections_group_parts_part_pointer_mode(void)
6869 {
6870 check_arg_count(1);
6871
6872 current_part->pointer_mode = parse_enum(0,
6873 "AUTOGRAB", EVAS_OBJECT_POINTER_MODE_AUTOGRAB,
6874 "NOGRAB", EVAS_OBJECT_POINTER_MODE_NOGRAB,
6875 NULL);
6876 }
6877
6878 /**
6879 @page edcref
6880 @property
6881 precise_is_inside
6882 @parameters
6883 [1 or 0]
6884 @effect
6885 Enables precise point collision detection for the part, which is more
6886 resource intensive.
6887
6888 Defaults: 0
6889 @endproperty
6890 */
6891 static void
st_collections_group_parts_part_precise_is_inside(void)6892 st_collections_group_parts_part_precise_is_inside(void)
6893 {
6894 check_arg_count(1);
6895
6896 current_part->precise_is_inside = parse_bool(0);
6897 }
6898
6899 static void
st_collections_group_parts_part_precise(void)6900 st_collections_group_parts_part_precise(void)
6901 {
6902 check_arg_count(0);
6903
6904 current_part->precise_is_inside = 1;
6905 }
6906
6907 static void
st_collections_group_parts_part_noprecise(void)6908 st_collections_group_parts_part_noprecise(void)
6909 {
6910 check_arg_count(0);
6911
6912 current_part->precise_is_inside = 0;
6913 }
6914
6915 /**
6916 @page edcref
6917 @property
6918 use_alternate_font_metrics
6919 @parameters
6920 [1 or 0]
6921 @effect
6922 Only affects text and textblock parts, when enabled Edje will use
6923 different size measurement functions. Disabled by default. (note from
6924 the author: I don't know what this is exactly useful for?)
6925
6926 Defaults: 0
6927 @endproperty
6928 */
6929 static void
st_collections_group_parts_part_use_alternate_font_metrics(void)6930 st_collections_group_parts_part_use_alternate_font_metrics(void)
6931 {
6932 check_arg_count(1);
6933
6934 current_part->use_alternate_font_metrics = parse_bool(0);
6935 }
6936
6937 /**
6938 @page edcref
6939 @property
6940 clip_to
6941 @parameters
6942 [another part's name]
6943 @effect
6944 Only renders the area of part that coincides with another part's
6945 container. Overflowing content will not be displayed. Note that
6946 the part being clipped to can only be a rectangle part.
6947 @endproperty
6948 */
6949 static void
st_collections_group_parts_part_clip_to_id(void)6950 st_collections_group_parts_part_clip_to_id(void)
6951 {
6952 Edje_Part_Collection *pc;
6953
6954 check_arg_count(1);
6955
6956 pc = eina_list_data_get(eina_list_last(edje_collections));
6957 {
6958 char *name;
6959
6960 name = parse_str(0);
6961 data_queue_part_lookup(pc, name, &(current_part->clip_to_id));
6962 free(name);
6963 }
6964 }
6965
6966 /**
6967 @page edcref
6968 @property
6969 no_render
6970 @parameters
6971 [1 or 0]
6972 @effect
6973 Setting the no_render flag on an object will make it never render
6974 directly on the canvas, regardless of the visible and color properties.
6975 But the object will still be rendered in a dedicated surface when
6976 required if it is a proxy source or a mask (clipper).
6977 Strongly recommended for use with mask objects and proxy sources
6978 (instead of setting "source_visible" on the proxy itself).
6979
6980 Defaults: 0
6981 @endproperty
6982 */
6983 static void
st_collections_group_parts_part_no_render(void)6984 st_collections_group_parts_part_no_render(void)
6985 {
6986 if (check_range_arg_count(0, 1) == 1)
6987 current_part->no_render = parse_bool(0);
6988 else /* lazEDC form */
6989 current_part->no_render = EINA_TRUE;
6990 }
6991
6992 static void
st_collections_group_parts_part_render(void)6993 st_collections_group_parts_part_render(void)
6994 {
6995 current_part->no_render = EINA_FALSE;
6996 }
6997
6998 /**
6999 @page edcref
7000 @property
7001 required
7002 @parameters
7003 [1 or 0]
7004 @effect
7005 If the required flag is set, this part will be considered
7006 stable and it is safe to use by any application."
7007
7008 Defaults: 0
7009 @since 1.18
7010 @endproperty
7011 */
7012 static void
st_collections_group_parts_part_required(void)7013 st_collections_group_parts_part_required(void)
7014 {
7015 if (check_range_arg_count(0, 1) == 1)
7016 current_part->required = parse_bool(0);
7017 else /* lazEDC form */
7018 current_part->required = EINA_TRUE;
7019 }
7020
7021 static void
st_collections_group_parts_part_norequired(void)7022 st_collections_group_parts_part_norequired(void)
7023 {
7024 current_part->required = EINA_FALSE;
7025 }
7026
7027 /**
7028 @page edcref
7029 @property
7030 source
7031 @parameters
7032 [another group's name]
7033 @effect
7034 Only available to GROUP or TEXTBLOCK parts. Swallows the specified
7035 group into the part's container if a GROUP. If TEXTBLOCK it is used
7036 for the group to be loaded and used for selection display UNDER the
7037 selected text. source2 is used for on top of the selected text, if
7038 source2 is specified.
7039 @endproperty
7040 */
7041 static void
st_collections_group_parts_part_source(void)7042 st_collections_group_parts_part_source(void)
7043 {
7044 check_arg_count(1);
7045
7046 //FIXME: validate this somehow (need to decide on the format also)
7047 current_part->source = parse_str(0);
7048 data_queue_group_lookup(current_part->source, current_part);
7049 }
7050
7051 /**
7052 @page edcref
7053 @property
7054 source2
7055 @parameters
7056 [another group's name]
7057 @effect
7058 Only available to TEXTBLOCK parts. It is used for the group to be
7059 loaded and used for selection display OVER the selected text. source
7060 is used for under of the selected text, if source is specified.
7061 @endproperty
7062 */
7063 static void
st_collections_group_parts_part_source2(void)7064 st_collections_group_parts_part_source2(void)
7065 {
7066 check_arg_count(1);
7067
7068 //FIXME: validate this somehow (need to decide on the format also)
7069 current_part->source2 = parse_str(0);
7070 data_queue_group_lookup(current_part->source2, current_part);
7071 }
7072
7073 /**
7074 @page edcref
7075 @property
7076 source3
7077 @parameters
7078 [another group's name]
7079 @effect
7080 Only available to TEXTBLOCK parts. It is used for the group to be
7081 loaded and used for cursor display UNDER the cursor position. source4
7082 is used for over the cursor text, if source4 is specified.
7083 @endproperty
7084 */
7085 static void
st_collections_group_parts_part_source3(void)7086 st_collections_group_parts_part_source3(void)
7087 {
7088 check_arg_count(1);
7089
7090 //FIXME: validate this somehow (need to decide on the format also)
7091 current_part->source3 = parse_str(0);
7092 data_queue_group_lookup(current_part->source3, current_part);
7093 }
7094
7095 /**
7096 @page edcref
7097 @property
7098 source4
7099 @parameters
7100 [another group's name]
7101 @effect
7102 Only available to TEXTBLOCK parts. It is used for the group to be
7103 loaded and used for cursor display OVER the cursor position. source3
7104 is used for under the cursor text, if source4 is specified.
7105 @endproperty
7106 */
7107 static void
st_collections_group_parts_part_source4(void)7108 st_collections_group_parts_part_source4(void)
7109 {
7110 check_arg_count(1);
7111
7112 //FIXME: validate this somehow (need to decide on the format also)
7113 current_part->source4 = parse_str(0);
7114 data_queue_group_lookup(current_part->source4, current_part);
7115 }
7116
7117 /**
7118 @page edcref
7119 @property
7120 source5
7121 @parameters
7122 [another group's name]
7123 @effect
7124 Only available to TEXTBLOCK parts. It is used for the group to be
7125 loaded and used for anchors display UNDER the anchor position. source6
7126 is used for over the anchors text, if source6 is specified.
7127 @endproperty
7128 */
7129 static void
st_collections_group_parts_part_source5(void)7130 st_collections_group_parts_part_source5(void)
7131 {
7132 check_arg_count(1);
7133
7134 //FIXME: validate this somehow (need to decide on the format also)
7135 current_part->source5 = parse_str(0);
7136 data_queue_group_lookup(current_part->source5, current_part);
7137 }
7138
7139 /**
7140 @page edcref
7141 @property
7142 source6
7143 @parameters
7144 [another group's name]
7145 @effect
7146 Only available to TEXTBLOCK parts. It is used for the group to be
7147 loaded and used for anchor display OVER the anchor position. source5
7148 is used for under the anchor text, if source6 is specified.
7149 @endproperty
7150 */
7151 static void
st_collections_group_parts_part_source6(void)7152 st_collections_group_parts_part_source6(void)
7153 {
7154 check_arg_count(1);
7155
7156 //FIXME: validate this somehow (need to decide on the format also)
7157 current_part->source6 = parse_str(0);
7158 data_queue_group_lookup(current_part->source6, current_part);
7159 }
7160
7161 /**
7162 @page edcref
7163
7164 @property
7165 effect
7166 @parameters
7167 [effect]
7168 (shadow direction)
7169 @effect
7170 Causes Edje to draw the selected effect among:
7171 @li PLAIN
7172 @li OUTLINE
7173 @li SOFT_OUTLINE
7174 @li SHADOW
7175 @li SOFT_SHADOW
7176 @li OUTLINE_SHADOW
7177 @li OUTLINE_SOFT_SHADOW
7178 @li FAR_SHADOW
7179 @li FAR_SOFT_SHADOW
7180 @li GLOW
7181
7182 Shadow directions (default if not given is BOTTOM_RIGHT):
7183 @li BOTTOM_RIGHT
7184 @li BOTTOM
7185 @li BOTTOM_LEFT
7186 @li LEFT
7187 @li TOP_LEFT
7188 @li TOP
7189 @li TOP_RIGHT
7190 @li RIGHT
7191
7192 Defaults: PLAIN
7193 @endproperty
7194 */
7195 static void
st_collections_group_parts_part_effect(void)7196 st_collections_group_parts_part_effect(void)
7197 {
7198 check_min_arg_count(1);
7199
7200 current_part->effect = parse_enum(0,
7201 "NONE", EDJE_TEXT_EFFECT_NONE,
7202 "PLAIN", EDJE_TEXT_EFFECT_PLAIN,
7203 "OUTLINE", EDJE_TEXT_EFFECT_OUTLINE,
7204 "SOFT_OUTLINE", EDJE_TEXT_EFFECT_SOFT_OUTLINE,
7205 "SHADOW", EDJE_TEXT_EFFECT_SHADOW,
7206 "SOFT_SHADOW", EDJE_TEXT_EFFECT_SOFT_SHADOW,
7207 "OUTLINE_SHADOW", EDJE_TEXT_EFFECT_OUTLINE_SHADOW,
7208 "OUTLINE_SOFT_SHADOW", EDJE_TEXT_EFFECT_OUTLINE_SOFT_SHADOW,
7209 "FAR_SHADOW", EDJE_TEXT_EFFECT_FAR_SHADOW,
7210 "FAR_SOFT_SHADOW", EDJE_TEXT_EFFECT_FAR_SOFT_SHADOW,
7211 "GLOW", EDJE_TEXT_EFFECT_GLOW,
7212 NULL);
7213 if (get_arg_count() >= 2)
7214 {
7215 unsigned char shadow;
7216
7217 shadow = parse_enum(1,
7218 "BOTTOM_RIGHT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_BOTTOM_RIGHT,
7219 "BOTTOM", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_BOTTOM,
7220 "BOTTOM_LEFT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_BOTTOM_LEFT,
7221 "LEFT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_LEFT,
7222 "TOP_LEFT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_TOP_LEFT,
7223 "TOP", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_TOP,
7224 "TOP_RIGHT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_TOP_RIGHT,
7225 "RIGHT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_RIGHT,
7226 NULL);
7227 EDJE_TEXT_EFFECT_SHADOW_DIRECTION_SET(current_part->effect, shadow);
7228 }
7229 }
7230
7231 /**
7232 @page edcref
7233 @property
7234 entry_mode
7235 @parameters
7236 [mode]
7237 @effect
7238 Sets the edit mode for a textblock part to one of:
7239 @li NONE
7240 @li PLAIN
7241 @li EDITABLE
7242 @li PASSWORD
7243
7244 It causes the part be editable if the edje object has the keyboard
7245 focus AND the part has the edje focus (or selectable always
7246 regardless of focus) and in the event of password mode, not
7247 selectable and all text chars replaced with *'s but editable and
7248 pastable.
7249
7250 Defaults: NONE
7251 @endproperty
7252 */
7253 static void
st_collections_group_parts_part_entry_mode(void)7254 st_collections_group_parts_part_entry_mode(void)
7255 {
7256 check_arg_count(1);
7257
7258 current_part->entry_mode = parse_enum(0,
7259 "NONE", EDJE_ENTRY_EDIT_MODE_NONE,
7260 "PLAIN", EDJE_ENTRY_EDIT_MODE_SELECTABLE,
7261 "EDITABLE", EDJE_ENTRY_EDIT_MODE_EDITABLE,
7262 "PASSWORD", EDJE_ENTRY_EDIT_MODE_PASSWORD,
7263 NULL);
7264 }
7265
7266 /**
7267 @page edcref
7268 @property
7269 select_mode
7270 @parameters
7271 [mode]
7272 @effect
7273 Sets the selection mode for a textblock part to one of:
7274 @li DEFAULT selection mode is what you would expect on any desktop. Press
7275 mouse, drag and release to end.
7276 @li EXPLICIT mode requires the application
7277 controlling the edje object has to explicitly begin and end selection
7278 modes, and the selection itself is draggable at both ends.
7279 @endproperty
7280 */
7281 static void
st_collections_group_parts_part_select_mode(void)7282 st_collections_group_parts_part_select_mode(void)
7283 {
7284 check_arg_count(1);
7285
7286 current_part->select_mode = parse_enum(0,
7287 "DEFAULT", EDJE_ENTRY_SELECTION_MODE_DEFAULT,
7288 "EXPLICIT", EDJE_ENTRY_SELECTION_MODE_EXPLICIT,
7289 NULL);
7290 }
7291
7292 /**
7293 @page edcref
7294 @property
7295 cursor_mode
7296 @parameters
7297 [mode]
7298 @effect
7299 Sets the cursor mode for a textblock part to one of:
7300 @li UNDER cursor mode means the cursor will draw below the character pointed at.
7301 @li BEFORE cursor mode means the cursor is drawn as a vertical line before
7302 the current character, just like many other GUI toolkits handle it.
7303
7304 Defaults: UNDER
7305 @endproperty
7306 */
7307 static void
st_collections_group_parts_part_cursor_mode(void)7308 st_collections_group_parts_part_cursor_mode(void)
7309 {
7310 check_arg_count(1);
7311
7312 current_part->cursor_mode = parse_enum(0,
7313 "UNDER", EDJE_ENTRY_CURSOR_MODE_UNDER,
7314 "BEFORE", EDJE_ENTRY_CURSOR_MODE_BEFORE,
7315 NULL);
7316 }
7317
7318 /**
7319 @page edcref
7320 @property
7321 multiline
7322 @parameters
7323 [1 or 0]
7324 @effect
7325 It causes a textblock that is editable to allow multiple lines for
7326 editing.
7327
7328 Defaults: 0
7329 @endproperty
7330 */
7331 static void
st_collections_group_parts_part_multiline(void)7332 st_collections_group_parts_part_multiline(void)
7333 {
7334 check_arg_count(1);
7335
7336 current_part->multiline = parse_bool(0);
7337 }
7338
7339 /**
7340 @page edcref
7341 @property
7342 access
7343 @parameters
7344 [1 or 0]
7345 @effect
7346 Specifies whether the part will use accessibility feature (1), or not (0).
7347
7348 Defaults: 0
7349 @endproperty
7350 */
7351 static void
st_collections_group_parts_part_access(void)7352 st_collections_group_parts_part_access(void)
7353 {
7354 check_arg_count(1);
7355
7356 current_part->access = parse_bool(0);
7357 }
7358
7359 /** @edcsubsection{collections_group_parts_dragable,
7360 * Group.Parts.Part.Dragable} */
7361
7362 /**
7363 @page edcref
7364 @block
7365 dragable
7366 @context
7367 part {
7368 ..
7369 dragable {
7370 confine: "another part";
7371 threshold: "another part";
7372 events: "another dragable part";
7373 x: 0 0 0;
7374 y: 0 0 0;
7375 }
7376 ..
7377 }
7378 @description
7379 When this block is used the resulting part can be dragged around the
7380 interface, do not confuse with external drag & drop. By default Edje
7381 (and most applications) will attempt to use the minimal size possible
7382 for a dragable part. If the min property is not set in the description
7383 the part will be (most likely) set to 0px width and 0px height, thus
7384 invisible.
7385 @endblock
7386
7387 @property
7388 x
7389 @parameters
7390 [enable/disable] [step] [count]
7391 @effect
7392 Used to setup dragging events for the X axis. The first parameter is
7393 used to enable (1 or -1) and disable (0) dragging along the axis. When
7394 enabled, 1 will set the starting point at 0.0 and -1 at 1.0. The second
7395 parameter takes any integer and will limit movement to values
7396 divisible by it, causing the part to jump from position to position.
7397 If step is set to 0 it is calculated as width of confine part divided by
7398 count.
7399
7400 Defaults: 0 0 0
7401 @endproperty
7402 */
7403 static void
st_collections_group_parts_part_dragable_x(void)7404 st_collections_group_parts_part_dragable_x(void)
7405 {
7406 check_arg_count(3);
7407
7408 current_part->dragable.x = parse_int_range(0, -1, 1);
7409 current_part->dragable.step_x = parse_int_range(1, 0, 0x7fffffff);
7410 current_part->dragable.count_x = parse_int_range(2, 0, 0x7fffffff);
7411 }
7412
7413 /**
7414 @page edcref
7415 @property
7416 y
7417 @parameters
7418 [enable/disable] [step] [count]
7419 @effect
7420 Used to setup dragging events for the Y axis. The first parameter is
7421 used to enable (1 or -1) and disable (0) dragging along the axis. When
7422 enabled, 1 will set the starting point at 0.0 and -1 at 1.0. The second
7423 parameter takes any integer and will limit movement to values
7424 divisible by it, causing the part to jump from position to position.
7425 If step is set to 0 it is calculated as height of confine part divided by
7426 count.
7427
7428 Defaults: 0 0 0
7429 @endproperty
7430 */
7431 static void
st_collections_group_parts_part_dragable_y(void)7432 st_collections_group_parts_part_dragable_y(void)
7433 {
7434 check_arg_count(3);
7435
7436 current_part->dragable.y = parse_int_range(0, -1, 1);
7437 current_part->dragable.step_y = parse_int_range(1, 0, 0x7fffffff);
7438 current_part->dragable.count_y = parse_int_range(2, 0, 0x7fffffff);
7439 }
7440
7441 /**
7442 @page edcref
7443 @property
7444 confine
7445 @parameters
7446 [another part's name]
7447 @effect
7448 When set, limits the movement of the dragged part to another part's
7449 container. When you use confine don't forget to set a min size for the
7450 part, or the draggie will not show up.
7451 @endproperty
7452 */
7453 static void
st_collections_group_parts_part_dragable_confine(void)7454 st_collections_group_parts_part_dragable_confine(void)
7455 {
7456 Edje_Part_Collection *pc;
7457
7458 check_arg_count(1);
7459
7460 pc = eina_list_data_get(eina_list_last(edje_collections));
7461 {
7462 char *name;
7463
7464 name = parse_str(0);
7465 data_queue_part_lookup(pc, name, &(current_part->dragable.confine_id));
7466 free(name);
7467 }
7468 }
7469
7470 /**
7471 @page edcref
7472 @property
7473 threshold
7474 @parameters
7475 [another part's name]
7476 @effect
7477 When set, the movement of the dragged part can only start when it get
7478 moved enough to be outside of the threshold part.
7479 @endproperty
7480 */
7481 static void
st_collections_group_parts_part_dragable_threshold(void)7482 st_collections_group_parts_part_dragable_threshold(void)
7483 {
7484 Edje_Part_Collection *pc;
7485
7486 check_arg_count(1);
7487
7488 pc = eina_list_data_get(eina_list_last(edje_collections));
7489 {
7490 char *name;
7491
7492 name = parse_str(0);
7493 data_queue_part_lookup(pc, name, &(current_part->dragable.threshold_id));
7494 free(name);
7495 }
7496 }
7497
7498 /**
7499 @page edcref
7500 @property
7501 events
7502 @parameters
7503 [another dragable part's name]
7504 @effect
7505 It causes the part to forward the drag events to another part, thus
7506 ignoring them for itself.
7507 @endproperty
7508 */
7509 static void
st_collections_group_parts_part_dragable_events(void)7510 st_collections_group_parts_part_dragable_events(void)
7511 {
7512 Edje_Part_Collection *pc;
7513
7514 check_arg_count(1);
7515
7516 pc = eina_list_data_get(eina_list_last(edje_collections));
7517 {
7518 char *name;
7519
7520 name = parse_str(0);
7521 data_queue_part_lookup(pc, name, &(current_part->dragable.event_id));
7522 free(name);
7523 }
7524 }
7525
7526 /**
7527 @page edcref
7528 @property
7529 allowed_seats
7530 @parameters
7531 [seat1] [seat2] [seat3] ...
7532 @effect
7533 List of seat names allowed to interact with the part.
7534
7535 If no list is defined all seats are allowed. It's the
7536 default behaviour.
7537
7538 If a seat isn't allowed, no signals will be emitted
7539 related to its actions, as mouse and focus events.
7540 Also it won't be able to focus this part.
7541 @since 1.19
7542 @endproperty
7543 */
7544 static void
st_collections_group_parts_part_allowed_seats(void)7545 st_collections_group_parts_part_allowed_seats(void)
7546 {
7547 Edje_Part_Allowed_Seat *seat;
7548 Edje_Part *ep;
7549 int n, argc;
7550
7551 check_min_arg_count(1);
7552
7553 ep = current_part;
7554 argc = get_arg_count();
7555
7556 ep->allowed_seats = calloc(argc, sizeof(Edje_Part_Allowed_Seat *));
7557 if (!ep->allowed_seats)
7558 {
7559 ERR("Not enough memory.");
7560 exit(-1);
7561 }
7562
7563 for (n = 0; n < argc; n++)
7564 {
7565 seat = mem_alloc(SZ(Edje_Part_Allowed_Seat));
7566 seat->name = parse_str(n);
7567 ep->allowed_seats[n] = seat;
7568 }
7569
7570 ep->allowed_seats_count = argc;
7571 }
7572
7573 /** @edcsubsection{collections_group_parts_items,
7574 * Group.Parts.Part.Box/Table.Items} */
7575
7576 /**
7577 @page edcref
7578 @block
7579 items
7580 @context
7581 part {
7582 ..
7583 box/table {
7584 items {
7585 item {
7586 type: TYPE;
7587 source: "some source";
7588 min: 1 1;
7589 max: 100 100;
7590 padding: 1 1 2 2;
7591 }
7592 item {
7593 type: TYPE;
7594 source: "some other source";
7595 name: "some name";
7596 align: 1.0 0.5;
7597 }
7598 ..
7599 }
7600 }
7601 ..
7602 }
7603 @description
7604 On a part of type BOX, this block can be used to set other groups
7605 as elements of the box. These can be mixed with external objects set
7606 by the application through the edje_object_part_box_* API.
7607 @endblock
7608 */
7609 static void
ob_collections_group_parts_part_box_items_item(void)7610 ob_collections_group_parts_part_box_items_item(void)
7611 {
7612 Edje_Part *ep;
7613 Edje_Pack_Element *item;
7614 Edje_Pack_Element_Parser *pitem;
7615
7616 ep = current_part;
7617
7618 if ((ep->type != EDJE_PART_TYPE_BOX) && (ep->type != EDJE_PART_TYPE_TABLE))
7619 {
7620 ERR("parse error %s:%i. box attributes in non-BOX or TABLE part.",
7621 file_in, line - 1);
7622 exit(-1);
7623 }
7624
7625 ep->items_count++;
7626 ep->items = realloc(ep->items, sizeof (Edje_Pack_Element *) * ep->items_count);
7627 if (!ep->items)
7628 {
7629 ERR("Not enough memory.");
7630 exit(-1);
7631 }
7632
7633 item = mem_alloc(SZ(Edje_Pack_Element_Parser));
7634 current_item = ep->items[ep->items_count - 1] = item;
7635 item->type = EDJE_PART_TYPE_GROUP;
7636 item->name = NULL;
7637 item->source = NULL;
7638 item->min.w = 0;
7639 item->min.h = 0;
7640 item->prefer.w = 0;
7641 item->prefer.h = 0;
7642 item->max.w = -1;
7643 item->max.h = -1;
7644 item->padding.l = 0;
7645 item->padding.r = 0;
7646 item->padding.t = 0;
7647 item->padding.b = 0;
7648 item->align.x = FROM_DOUBLE(0.5);
7649 item->align.y = FROM_DOUBLE(0.5);
7650 item->weight.x = FROM_DOUBLE(0.0);
7651 item->weight.y = FROM_DOUBLE(0.0);
7652 item->aspect.w = 0;
7653 item->aspect.h = 0;
7654 item->aspect.mode = EDJE_ASPECT_CONTROL_NONE;
7655 item->options = NULL;
7656 item->col = -1;
7657 item->row = -1;
7658 item->colspan = 1;
7659 item->rowspan = 1;
7660 item->spread.w = 1;
7661 item->spread.h = 1;
7662 pitem = (Edje_Pack_Element_Parser *)item;
7663 pitem->can_override = EINA_FALSE;
7664 }
7665
7666 #define CURRENT_ITEM_CHECK \
7667 if (!current_item) \
7668 { \
7669 ERR("parse error %s:%i. Item not defined at this stage.", \
7670 file_in, line - 1); \
7671 exit(-1); \
7672 }
7673
7674 /**
7675 @page edcref
7676 @property
7677 type
7678 @parameters
7679 [item type]
7680 @effect
7681 Sets the type of the object this item will hold.
7682 Supported types are:
7683 @li GROUP
7684 @endproperty
7685 */
7686 static void
st_collections_group_parts_part_box_items_item_type(void)7687 st_collections_group_parts_part_box_items_item_type(void)
7688 {
7689 CURRENT_ITEM_CHECK;
7690
7691 check_arg_count(1);
7692
7693 {
7694 char *s;
7695
7696 s = parse_str(0);
7697 if (strcmp(s, "GROUP"))
7698 {
7699 ERR("parse error %s:%i. token %s not one of: GROUP.",
7700 file_in, line - 1, s);
7701 free(s);
7702 exit(-1);
7703 }
7704 free(s);
7705 /* FIXME: handle the enum, once everything else is supported */
7706 current_item->type = EDJE_PART_TYPE_GROUP;
7707 }
7708 }
7709
7710 /**
7711 @page edcref
7712 @property
7713 name
7714 @parameters
7715 [name for the object]
7716 @effect
7717 Sets the name of the object via evas_object_name_set().
7718 @endproperty
7719 */
7720 static void
st_collections_group_parts_part_box_items_item_name(void)7721 st_collections_group_parts_part_box_items_item_name(void)
7722 {
7723 Edje_Part *ep;
7724 Edje_Pack_Element *item;
7725 Edje_Pack_Element_Parser *pitem;
7726
7727 CURRENT_ITEM_CHECK;
7728
7729 check_arg_count(1);
7730
7731 ep = current_part;
7732 item = ep->items[ep->items_count - 1];
7733
7734 item->name = parse_str(0);
7735
7736 {
7737 unsigned int i;
7738
7739 for (i = 0; i < ep->items_count - 1; ++i)
7740 {
7741 if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item->name)))
7742 {
7743 pitem = (Edje_Pack_Element_Parser *)ep->items[i];
7744 if (!pitem->can_override)
7745 {
7746 ERR("parse error %s:%i. There is already a item of the name %s",
7747 file_in, line - 1, item->name);
7748 exit(-1);
7749 }
7750 else
7751 {
7752 free(item);
7753 ep->items_count--;
7754 ep->items = realloc(ep->items, ep->items_count * sizeof (Edje_Pack_Element *));
7755 current_item = ep->items[i];
7756 pitem->can_override = EINA_FALSE;
7757 break;
7758 }
7759 }
7760 }
7761 }
7762 }
7763
7764 /**
7765 @page edcref
7766 @property
7767 source
7768 @parameters
7769 [another group's name]
7770 @effect
7771 Sets the group this object will be made from.
7772 @endproperty
7773 */
7774 static void
st_collections_group_parts_part_box_items_item_source(void)7775 st_collections_group_parts_part_box_items_item_source(void)
7776 {
7777 CURRENT_ITEM_CHECK;
7778
7779 check_arg_count(1);
7780
7781 current_item->source = parse_str(0);
7782 data_queue_group_lookup(current_item->source, current_part);
7783 }
7784
7785 /**
7786 @page edcref
7787 @property
7788 min
7789 @parameters
7790 [width] [height]
7791 @effect
7792 Sets the minimum size hints for this object.
7793
7794 Defaults: 0 0
7795 @endproperty
7796 */
7797 static void
st_collections_group_parts_part_box_items_item_min(void)7798 st_collections_group_parts_part_box_items_item_min(void)
7799 {
7800 CURRENT_ITEM_CHECK;
7801
7802 check_arg_count(2);
7803
7804 current_item->min.w = parse_int_range(0, 0, 0x7ffffff);
7805 current_item->min.h = parse_int_range(1, 0, 0x7ffffff);
7806 }
7807
7808 /**
7809 @page edcref
7810 @property
7811 spread
7812 @parameters
7813 [width] [height]
7814 @effect
7815 Will replicate the item in a rectangle of size width x height
7816 box starting from the defined position of this item.
7817
7818 Defaults: 1 1
7819 @endproperty
7820 */
7821 static void
st_collections_group_parts_part_box_items_item_spread(void)7822 st_collections_group_parts_part_box_items_item_spread(void)
7823 {
7824 CURRENT_ITEM_CHECK;
7825
7826 check_arg_count(2);
7827
7828 current_item->spread.w = parse_int_range(0, 1, 0x7ffffff);
7829 current_item->spread.h = parse_int_range(1, 1, 0x7ffffff);
7830 }
7831
7832 /**
7833 @page edcref
7834 @property
7835 prefer
7836 @parameters
7837 [width] [height]
7838 @effect
7839 Sets the preferred size hints for this object.
7840
7841 Defaults: 0 0
7842 @endproperty
7843 */
7844 static void
st_collections_group_parts_part_box_items_item_prefer(void)7845 st_collections_group_parts_part_box_items_item_prefer(void)
7846 {
7847 CURRENT_ITEM_CHECK;
7848
7849 check_arg_count(2);
7850
7851 current_item->prefer.w = parse_int_range(0, 0, 0x7ffffff);
7852 current_item->prefer.h = parse_int_range(1, 0, 0x7ffffff);
7853 }
7854
7855 /**
7856 @page edcref
7857 @property
7858 max
7859 @parameters
7860 [width] [height]
7861 @effect
7862 Sets the maximum size hints for this object.
7863
7864 Defaults: -1 -1
7865 @endproperty
7866 */
7867 static void
st_collections_group_parts_part_box_items_item_max(void)7868 st_collections_group_parts_part_box_items_item_max(void)
7869 {
7870 CURRENT_ITEM_CHECK;
7871
7872 check_arg_count(2);
7873
7874 current_item->max.w = parse_int_range(0, -1, 0x7ffffff);
7875 current_item->max.h = parse_int_range(1, -1, 0x7ffffff);
7876 }
7877
7878 /**
7879 @page edcref
7880 @property
7881 padding
7882 @parameters
7883 [left] [right] [top] [bottom]
7884 @effect
7885 Sets the padding hints for this object.
7886
7887 Defaults: 0 0 0 0
7888 @endproperty
7889 */
7890 static void
st_collections_group_parts_part_box_items_item_padding(void)7891 st_collections_group_parts_part_box_items_item_padding(void)
7892 {
7893 CURRENT_ITEM_CHECK;
7894
7895 check_arg_count(4);
7896
7897 current_item->padding.l = parse_int_range(0, 0, 0x7ffffff);
7898 current_item->padding.r = parse_int_range(1, 0, 0x7ffffff);
7899 current_item->padding.t = parse_int_range(2, 0, 0x7ffffff);
7900 current_item->padding.b = parse_int_range(3, 0, 0x7ffffff);
7901 }
7902
7903 /**
7904 @page edcref
7905 @property
7906 align
7907 @parameters
7908 [x] [y]
7909 @effect
7910 Sets the alignment [-1.0 - 1.0] hints for this object.
7911
7912 Defaults: 0.5
7913 @endproperty
7914 */
7915 static void
st_collections_group_parts_part_box_items_item_align(void)7916 st_collections_group_parts_part_box_items_item_align(void)
7917 {
7918 CURRENT_ITEM_CHECK;
7919
7920 check_arg_count(2);
7921
7922 current_item->align.x = FROM_DOUBLE(parse_float_range(0, -1.0, 1.0));
7923 current_item->align.y = FROM_DOUBLE(parse_float_range(1, -1.0, 1.0));
7924 }
7925
7926 /**
7927 @page edcref
7928 @property
7929 weight
7930 @parameters
7931 [x] [y]
7932 @effect
7933 Sets the weight hints for this object.
7934
7935 Defaults: 0.0 0.0
7936 @endproperty
7937 */
7938 static void
st_collections_group_parts_part_box_items_item_weight(void)7939 st_collections_group_parts_part_box_items_item_weight(void)
7940 {
7941 CURRENT_ITEM_CHECK;
7942
7943 check_arg_count(2);
7944
7945 current_item->weight.x = FROM_DOUBLE(parse_float_range(0, 0.0, 99999.99));
7946 current_item->weight.y = FROM_DOUBLE(parse_float_range(1, 0.0, 99999.99));
7947 }
7948
7949 /**
7950 @page edcref
7951 @property
7952 aspect
7953 @parameters
7954 [w] [h]
7955 @effect
7956 Sets the aspect width and height hints for this object.
7957
7958 Defaults: 0 0
7959 @endproperty
7960 */
7961 static void
st_collections_group_parts_part_box_items_item_aspect(void)7962 st_collections_group_parts_part_box_items_item_aspect(void)
7963 {
7964 CURRENT_ITEM_CHECK;
7965
7966 check_arg_count(2);
7967
7968 current_item->aspect.w = parse_int_range(0, 0, 0x7fffffff);
7969 current_item->aspect.h = parse_int_range(1, 0, 0x7fffffff);
7970 }
7971
7972 /**
7973 @page edcref
7974 @property
7975 aspect_mode
7976 @parameters
7977 [mode]
7978 @effect
7979 Sets the aspect control hints for this object. Mode can be one of:
7980 @li NONE
7981 @li NEITHER
7982 @li HORIZONTAL
7983 @li VERTICAL
7984 @li BOTH
7985
7986 Defaults: NONE
7987 @endproperty
7988 */
7989 static void
st_collections_group_parts_part_box_items_item_aspect_mode(void)7990 st_collections_group_parts_part_box_items_item_aspect_mode(void)
7991 {
7992 CURRENT_ITEM_CHECK;
7993
7994 check_arg_count(1);
7995
7996 current_item->aspect.mode = parse_enum(0,
7997 "NONE", EDJE_ASPECT_CONTROL_NONE,
7998 "NEITHER", EDJE_ASPECT_CONTROL_NEITHER,
7999 "HORIZONTAL", EDJE_ASPECT_CONTROL_HORIZONTAL,
8000 "VERTICAL", EDJE_ASPECT_CONTROL_VERTICAL,
8001 "BOTH", EDJE_ASPECT_CONTROL_BOTH,
8002 NULL);
8003 }
8004
8005 /**
8006 @page edcref
8007 @property
8008 options
8009 @parameters
8010 [extra options]
8011 @effect
8012 Sets extra options for the object. Unused for now.
8013 @endproperty
8014 */
8015 static void
st_collections_group_parts_part_box_items_item_options(void)8016 st_collections_group_parts_part_box_items_item_options(void)
8017 {
8018 CURRENT_ITEM_CHECK;
8019
8020 check_arg_count(1);
8021
8022 current_item->options = parse_str(0);
8023 }
8024
8025 /**
8026 @page edcref
8027 @property
8028 position
8029 @parameters
8030 [col] [row]
8031 @effect
8032 Sets the position this item will have in the table.
8033 This is required for parts of type TABLE.
8034 @endproperty
8035 */
8036 static void
st_collections_group_parts_part_table_items_item_position(void)8037 st_collections_group_parts_part_table_items_item_position(void)
8038 {
8039 CURRENT_ITEM_CHECK;
8040
8041 check_arg_count(2);
8042
8043 if (current_part->type != EDJE_PART_TYPE_TABLE)
8044 {
8045 ERR("parse error %s:%i. table attributes in non-TABLE part.",
8046 file_in, line - 1);
8047 exit(-1);
8048 }
8049
8050 current_item->col = parse_int_range(0, 0, 0xffff);
8051 current_item->row = parse_int_range(1, 0, 0xffff);
8052 }
8053
8054 /**
8055 @page edcref
8056 @property
8057 span
8058 @parameters
8059 [col] [row]
8060 @effect
8061 Sets how many columns/rows this item will use.
8062
8063 Defaults: 1 1
8064 @endproperty
8065 */
8066 static void
st_collections_group_parts_part_table_items_item_span(void)8067 st_collections_group_parts_part_table_items_item_span(void)
8068 {
8069 CURRENT_ITEM_CHECK;
8070
8071 check_arg_count(2);
8072
8073 if (current_part->type != EDJE_PART_TYPE_TABLE)
8074 {
8075 ERR("parse error %s:%i. table attributes in non-TABLE part.",
8076 file_in, line - 1);
8077 exit(-1);
8078 }
8079
8080 current_item->colspan = parse_int_range(0, 1, 0xffff);
8081 current_item->rowspan = parse_int_range(1, 1, 0xffff);
8082 }
8083
8084 static Edje_Map_Color **
_copied_map_colors_get(Edje_Part_Description_Common * parent)8085 _copied_map_colors_get(Edje_Part_Description_Common *parent)
8086 {
8087 Edje_Map_Color **colors;
8088 Edje_Map_Color *color;
8089 int i;
8090
8091 if (parent->map.colors_count == 0) return NULL;
8092 colors = mem_alloc(sizeof(Edje_Map_Color *) * parent->map.colors_count);
8093
8094 for (i = 0; i < (int)parent->map.colors_count; i++)
8095 {
8096 color = parent->map.colors[i];
8097
8098 Edje_Map_Color *c = mem_alloc(SZ(Edje_Map_Color));
8099 if (!color)
8100 {
8101 ERR("Could not find allocated source when copying map colors");
8102 exit(-1);
8103 return NULL;
8104 }
8105 memcpy(c, color, sizeof(Edje_Map_Color));
8106 colors[i] = c;
8107 }
8108 return colors;
8109 }
8110
8111 /** @edcsubsection{collections_group_parts_description,
8112 * Group.Parts.Part.Description} */
8113
8114 /**
8115 @page edcref
8116 @block
8117 description
8118 @context
8119 description {
8120 inherit: "another_description" INDEX;
8121 state: "description_name" INDEX;
8122 visible: 1;
8123 min: 0 0;
8124 max: -1 -1;
8125 align: 0.5 0.5;
8126 fixed: 0 0;
8127 step: 0 0;
8128 aspect: 1 1;
8129 clip_to: "clip_override_part_name";
8130 no_render: 0;
8131 offset_scale: 0;
8132
8133 rel1 {
8134 ..
8135 }
8136
8137 rel2 {
8138 ..
8139 }
8140 }
8141 @description
8142 Every part can have one or more description blocks. Each description is
8143 used to define style and layout properties of a part in a given
8144 "state".
8145 @endblock
8146 */
8147 static void
ob_collections_group_parts_part_description(void)8148 ob_collections_group_parts_part_description(void)
8149 { /* Allocate and set desc, set relative part hierarchy if needed */
8150 Edje_Part_Collection *pc;
8151 Edje_Part *ep;
8152 Edje_Part_Description_Common *ed;
8153
8154 pc = eina_list_data_get(eina_list_last(edje_collections));
8155 ep = current_part;
8156
8157 ed = _edje_part_description_alloc(ep->type, pc->part, ep->name);
8158 eina_hash_add(desc_hash, &ed, ep);
8159
8160 ed->rel1.id_x = -1;
8161 ed->rel1.id_y = -1;
8162 ed->rel2.id_x = -1;
8163 ed->rel2.id_y = -1;
8164 ed->clip_to_id = -1;
8165
8166 if (!ep->default_desc)
8167 {
8168 current_desc = ep->default_desc = ed;
8169 ed->state.name = strdup("default");
8170
8171 { /* Get the ptr of the part above current part in hierarchy */
8172 Edje_Part *node = edje_cc_handlers_hierarchy_parent_get();
8173 if (node) /* Make relative according to part hierarchy */
8174 edje_cc_handlers_hierarchy_set(node);
8175 }
8176 }
8177 else
8178 {
8179 ep->other.desc_count++;
8180 ep->other.desc = realloc(ep->other.desc,
8181 sizeof (Edje_Part_Description_Common *) * ep->other.desc_count);
8182 current_desc = ep->other.desc[ep->other.desc_count - 1] = ed;
8183 }
8184
8185 ed->visible = 1;
8186 ed->limit = 0;
8187 ed->no_render = 0;
8188 ed->align.x = FROM_DOUBLE(0.5);
8189 ed->align.y = FROM_DOUBLE(0.5);
8190 ed->min.w = 0;
8191 ed->min.h = 0;
8192 ed->fixed.w = 0;
8193 ed->fixed.h = 0;
8194 ed->max.w = -1;
8195 ed->max.h = -1;
8196 ed->size_class = NULL;
8197 ed->rel1.relative_x = FROM_DOUBLE(0.0);
8198 ed->rel1.relative_y = FROM_DOUBLE(0.0);
8199 ed->rel1.offset_x = 0;
8200 ed->rel1.offset_y = 0;
8201 ed->rel2.relative_x = FROM_DOUBLE(1.0);
8202 ed->rel2.relative_y = FROM_DOUBLE(1.0);
8203 ed->rel2.offset_x = -1;
8204 ed->rel2.offset_y = -1;
8205 ed->color_class = NULL;
8206 ed->color.r = 255;
8207 ed->color.g = 255;
8208 ed->color.b = 255;
8209 ed->color.a = 255;
8210 ed->color2.r = 0;
8211 ed->color2.g = 0;
8212 ed->color2.b = 0;
8213 ed->color2.a = 255;
8214 ed->map.id_persp = -1;
8215 ed->map.id_light = -1;
8216 ed->map.rot.id_center = -1;
8217 ed->map.zoom.id_center = -1;
8218 ed->map.rot.x = FROM_DOUBLE(0.0);
8219 ed->map.rot.y = FROM_DOUBLE(0.0);
8220 ed->map.rot.z = FROM_DOUBLE(0.0);
8221 ed->map.on = 0;
8222 ed->map.smooth = 1;
8223 ed->map.alpha = 1;
8224 ed->map.backcull = 0;
8225 ed->map.persp_on = 0;
8226 ed->map.colors = NULL;
8227 ed->map.zoom.x = FROM_DOUBLE(1.0);
8228 ed->map.zoom.y = FROM_DOUBLE(1.0);
8229 ed->persp.zplane = 0;
8230 ed->persp.focal = 1000;
8231 ed->minmul.have = 1;
8232 ed->minmul.w = FROM_DOUBLE(1.0);
8233 ed->minmul.h = FROM_DOUBLE(1.0);
8234 }
8235
8236 static void
ob_collections_group_parts_part_desc(void)8237 ob_collections_group_parts_part_desc(void)
8238 {
8239 stack_replace_quick("description");
8240 ob_collections_group_parts_part_description();
8241 }
8242
8243 /**
8244 @page edcref
8245 @property
8246 inherit
8247 @parameters
8248 [another description's name] [another description's index]
8249 @effect
8250 When set, the description will inherit all the properties from the
8251 named description. The properties defined in this part will override
8252 the inherited properties, reducing the amount of necessary code for
8253 simple state changes. Note: inheritance in Edje is single level only.
8254 @since 1.14 omitting both the description name and index will inherit the default 0.0 description.
8255 @endproperty
8256 */
8257 static void
st_collections_group_parts_part_description_inherit(void)8258 st_collections_group_parts_part_description_inherit(void)
8259 {
8260 Edje_Part_Collection *pc;
8261 Edje_Part *ep, *parent_ep = NULL;
8262 Edje_Part_Description_Common *ed, *parent = NULL;
8263 Edje_Part_Image_Id *iid;
8264 char *parent_name;
8265 const char *state_name;
8266 double parent_val = 0.0, state_val;
8267
8268 pc = eina_list_data_get(eina_list_last(edje_collections));
8269 ep = current_part;
8270 ed = current_desc;
8271
8272 parent = parent_desc;
8273 if (parent)
8274 parent_ep = eina_hash_find(desc_hash, &parent);
8275 else
8276 {
8277 /* inherit may not be used in the default description */
8278 if (!ep->other.desc_count)
8279 {
8280 ERR("parse error %s:%i. "
8281 "inherit may not be used in the default description",
8282 file_in, line - 1);
8283 exit(-1);
8284 }
8285
8286 /* find the description that we inherit from */
8287 switch (get_arg_count())
8288 {
8289 case 0:
8290 parent_name = strdup("default");
8291 break;
8292
8293 case 2:
8294 parent_val = parse_float_range(1, 0.0, 1.0);
8295 EINA_FALLTHROUGH;
8296
8297 case 1:
8298 parent_name = parse_str(0);
8299 break;
8300
8301 default:
8302 ERR("parse error %s:%i. too many parameters",
8303 file_in, line - 1);
8304 exit(-1);
8305 }
8306
8307 if (!strcmp(parent_name, "default") && EINA_DBL_EQ(parent_val, 0.0))
8308 parent = ep->default_desc;
8309 else
8310 {
8311 Edje_Part_Description_Common *d;
8312 double min_dst = 999.0;
8313 unsigned int i;
8314
8315 if (!strcmp(parent_name, "default"))
8316 {
8317 parent = ep->default_desc;
8318 min_dst = ABS(ep->default_desc->state.value - parent_val);
8319 }
8320
8321 for (i = 0; i < ep->other.desc_count; ++i)
8322 {
8323 d = ep->other.desc[i];
8324
8325 if (!strcmp(d->state.name, parent_name))
8326 {
8327 double dst;
8328
8329 dst = ABS(d->state.value - parent_val);
8330 if (dst < min_dst)
8331 {
8332 parent = d;
8333 min_dst = dst;
8334 }
8335 }
8336 }
8337
8338 if (EINA_DBL_NONZERO(min_dst))
8339 {
8340 WRN("%s:%i: couldn't find an exact match in part '%s' when looking for '%s' %lf. Falling back to nearest one '%s' %lf.",
8341 file_in, line - 1, ep->name, parent_name, parent_val, parent ? parent->state.name : NULL, parent ? parent->state.value : 0);
8342 }
8343 }
8344
8345 if (!parent)
8346 {
8347 ERR("parse error %s:%i. "
8348 "cannot find referenced part %s state %s %lf",
8349 file_in, line - 1, ep->name, parent_name, parent_val);
8350 exit(-1);
8351 }
8352
8353 free(parent_name);
8354 }
8355 /* now do a full copy, only state info will be kept */
8356 state_name = ed->state.name;
8357 state_val = ed->state.value;
8358
8359 *ed = *parent;
8360
8361 ed->state.name = state_name;
8362 ed->state.value = state_val;
8363
8364 data_queue_copied_part_lookup(pc, &parent->rel1.id_x, &ed->rel1.id_x);
8365 data_queue_copied_part_lookup(pc, &parent->rel1.id_y, &ed->rel1.id_y);
8366 data_queue_copied_part_lookup(pc, &parent->rel2.id_x, &ed->rel2.id_x);
8367 data_queue_copied_part_lookup(pc, &parent->rel2.id_y, &ed->rel2.id_y);
8368
8369 data_queue_copied_part_lookup(pc, &parent->clip_to_id, &ed->clip_to_id);
8370
8371 data_queue_copied_part_lookup(pc, &parent->map.id_persp, &ed->map.id_persp);
8372 data_queue_copied_part_lookup(pc, &parent->map.id_light, &ed->map.id_light);
8373 data_queue_copied_part_lookup(pc, &parent->map.rot.id_center, &ed->map.rot.id_center);
8374 data_queue_copied_part_lookup(pc, &parent->map.zoom.id_center, &ed->map.zoom.id_center);
8375
8376 /* make sure all the allocated memory is getting copied, not just
8377 * referenced
8378 */
8379
8380 ed->size_class = STRDUP(ed->size_class);
8381 ed->color_class = STRDUP(ed->color_class);
8382 ed->map.colors = _copied_map_colors_get(parent);
8383
8384 if (parent_ep && (parent_ep->type != ep->type))
8385 {
8386 /* ensure parent's owner is a compatible type of part */
8387 if (((ep->type != EDJE_PART_TYPE_TEXT) && (ep->type != EDJE_PART_TYPE_TEXTBLOCK)) ||
8388 ((parent_ep->type != EDJE_PART_TYPE_TEXT) && (parent_ep->type != EDJE_PART_TYPE_TEXTBLOCK)))
8389 return;
8390 }
8391
8392 switch (ep->type)
8393 {
8394 case EDJE_PART_TYPE_SPACER:
8395 case EDJE_PART_TYPE_RECTANGLE:
8396 case EDJE_PART_TYPE_SWALLOW:
8397 case EDJE_PART_TYPE_GROUP:
8398 /* Nothing todo, this part only have a common description. */
8399 break;
8400
8401 case EDJE_PART_TYPE_TEXT:
8402 case EDJE_PART_TYPE_TEXTBLOCK:
8403 {
8404 Edje_Part_Description_Text *ted = (Edje_Part_Description_Text *)ed;
8405 Edje_Part_Description_Text *tparent = (Edje_Part_Description_Text *)parent;
8406
8407 ted->text = tparent->text;
8408
8409 ted->text.text.str = STRDUP(ted->text.text.str);
8410 ted->text.domain = STRDUP(ted->text.domain);
8411 ted->text.text_class = STRDUP(ted->text.text_class);
8412 ted->text.font.str = STRDUP(ted->text.font.str);
8413
8414 _filter_copy(&ted->filter, &tparent->filter);
8415 data_queue_copied_part_nest_lookup(pc, &(tparent->text.id_source), &(ted->text.id_source), &ted->text.id_source_part);
8416 data_queue_copied_part_nest_lookup(pc, &(tparent->text.id_text_source), &(ted->text.id_text_source), &ted->text.id_text_source_part);
8417
8418 break;
8419 }
8420
8421 case EDJE_PART_TYPE_IMAGE:
8422 {
8423 Edje_Part_Description_Image *ied = (Edje_Part_Description_Image *)ed;
8424 Edje_Part_Description_Image *iparent = (Edje_Part_Description_Image *)parent;
8425 unsigned int i;
8426
8427 ied->image = iparent->image;
8428
8429 data_queue_image_remove(&ied->image.id, &ied->image.set);
8430 data_queue_copied_image_lookup(&iparent->image.id, &ied->image.id, &ied->image.set);
8431
8432 ied->image.tweens = calloc(iparent->image.tweens_count,
8433 sizeof (Edje_Part_Image_Id *));
8434 for (i = 0; i < iparent->image.tweens_count; i++)
8435 {
8436 Edje_Part_Image_Id *iid_new;
8437
8438 iid = iparent->image.tweens[i];
8439
8440 iid_new = mem_alloc(SZ(Edje_Part_Image_Id));
8441 data_queue_image_remove(&ied->image.id, &ied->image.set);
8442 data_queue_copied_image_lookup(&(iid->id), &(iid_new->id), &(iid_new->set));
8443 ied->image.tweens[i] = iid_new;
8444 }
8445
8446 _filter_copy(&ied->filter, &iparent->filter);
8447
8448 break;
8449 }
8450
8451 case EDJE_PART_TYPE_SNAPSHOT:
8452 {
8453 Edje_Part_Description_Snapshot *sed = (Edje_Part_Description_Snapshot *)ed;
8454 Edje_Part_Description_Snapshot *sparent = (Edje_Part_Description_Snapshot *)parent;
8455
8456 _filter_copy(&sed->filter, &sparent->filter);
8457
8458 break;
8459 }
8460
8461 case EDJE_PART_TYPE_PROXY:
8462 {
8463 Edje_Part_Description_Proxy *ped = (Edje_Part_Description_Proxy *)ed;
8464 Edje_Part_Description_Proxy *pparent = (Edje_Part_Description_Proxy *)parent;
8465
8466 data_queue_copied_part_lookup(pc, &(pparent->proxy.id), &(ped->proxy.id));
8467 ped->proxy.source_clip = pparent->proxy.source_clip;
8468 ped->proxy.source_visible = pparent->proxy.source_visible;
8469 _filter_copy(&ped->filter, &pparent->filter);
8470
8471 break;
8472 }
8473
8474 case EDJE_PART_TYPE_BOX:
8475 {
8476 Edje_Part_Description_Box *bed = (Edje_Part_Description_Box *)ed;
8477 Edje_Part_Description_Box *bparent = (Edje_Part_Description_Box *)parent;
8478
8479 bed->box = bparent->box;
8480
8481 break;
8482 }
8483
8484 case EDJE_PART_TYPE_TABLE:
8485 {
8486 Edje_Part_Description_Table *ted = (Edje_Part_Description_Table *)ed;
8487 Edje_Part_Description_Table *tparent = (Edje_Part_Description_Table *)parent;
8488
8489 ted->table = tparent->table;
8490
8491 break;
8492 }
8493
8494 case EDJE_PART_TYPE_EXTERNAL:
8495 {
8496 Edje_Part_Description_External *eed = (Edje_Part_Description_External *)ed;
8497 Edje_Part_Description_External *eparent = (Edje_Part_Description_External *)parent;
8498
8499 if (eparent->external_params)
8500 {
8501 Eina_List *l;
8502 Edje_External_Param *param, *new_param;
8503
8504 eed->external_params = NULL;
8505 EINA_LIST_FOREACH(eparent->external_params, l, param)
8506 {
8507 new_param = mem_alloc(SZ(Edje_External_Param));
8508 *new_param = *param;
8509 eed->external_params = eina_list_append(eed->external_params, new_param);
8510 }
8511 }
8512 break;
8513 }
8514
8515 case EDJE_PART_TYPE_VECTOR:
8516 {
8517 Edje_Part_Description_Vector *ied = (Edje_Part_Description_Vector *)ed;
8518 Edje_Part_Description_Vector *iparent = (Edje_Part_Description_Vector *)parent;
8519 ied->vg.set = iparent->vg.set;
8520 ied->vg.id = iparent->vg.id;
8521 ied->vg.type = iparent->vg.type;
8522 ied->vg.frame = iparent->vg.frame;
8523 break;
8524 }
8525 }
8526 }
8527
8528 /**
8529 @page edcref
8530
8531 @property
8532 source
8533 @parameters
8534 [another part's name]
8535 @effect
8536 Causes the part to use another part content as the content of this part.
8537 Only work with PROXY part.
8538 @endproperty
8539 */
8540 static void
st_collections_group_parts_part_description_source(void)8541 st_collections_group_parts_part_description_source(void)
8542 {
8543 Edje_Part_Collection *pc;
8544 Edje_Part_Description_Proxy *ed;
8545 char *name;
8546
8547 check_arg_count(1);
8548
8549 pc = eina_list_data_get(eina_list_last(edje_collections));
8550
8551 if (current_part->type != EDJE_PART_TYPE_PROXY)
8552 {
8553 ERR("parse error %s:%i. source attributes in non-PROXY part.",
8554 file_in, line - 1);
8555 exit(-1);
8556 }
8557
8558 ed = (Edje_Part_Description_Proxy *)current_desc;
8559
8560 name = parse_str(0);
8561
8562 data_queue_part_lookup(pc, name, &(ed->proxy.id));
8563 free(name);
8564 }
8565
8566 static void
_part_description_state_update(Edje_Part_Description_Common * ed)8567 _part_description_state_update(Edje_Part_Description_Common *ed)
8568 {
8569 Edje_Part *ep = current_part;
8570
8571 if (ed == ep->default_desc) return;
8572 if ((ep->default_desc->state.name && !strcmp(ed->state.name, ep->default_desc->state.name) && EINA_DBL_EQ(ed->state.value, ep->default_desc->state.value)) ||
8573 (!ep->default_desc->state.name && !strcmp(ed->state.name, "default") && EINA_DBL_EQ(ed->state.value, ep->default_desc->state.value)))
8574 {
8575 if (ep->type == EDJE_PART_TYPE_IMAGE)
8576 _edje_part_description_image_remove((Edje_Part_Description_Image *)ed);
8577
8578 free(ed);
8579 ep->other.desc_count--;
8580 ep->other.desc = realloc(ep->other.desc,
8581 sizeof (Edje_Part_Description_Common *) * ep->other.desc_count);
8582 current_desc = ep->default_desc;
8583 }
8584 else if (ep->other.desc_count)
8585 {
8586 unsigned int i;
8587 for (i = 0; i < ep->other.desc_count - 1; ++i)
8588 {
8589 if (!strcmp(ed->state.name, ep->other.desc[i]->state.name) && EINA_DBL_EQ(ed->state.value, ep->other.desc[i]->state.value))
8590 {
8591 if (ep->type == EDJE_PART_TYPE_IMAGE)
8592 _edje_part_description_image_remove((Edje_Part_Description_Image *)ed);
8593
8594 free(ed);
8595 ep->other.desc_count--;
8596 ep->other.desc = realloc(ep->other.desc,
8597 sizeof (Edje_Part_Description_Common *) * ep->other.desc_count);
8598 current_desc = ep->other.desc[i];
8599 break;
8600 }
8601 }
8602 }
8603 }
8604
8605 /**
8606 @page edcref
8607 @property
8608 state
8609 @parameters
8610 [name for the description] [index]
8611 @effect
8612 Sets a name used to identify a description inside a given part.
8613 Multiple descriptions are used to declare different states of the same
8614 part, like "clicked" or "invisible". All states declarations are also
8615 coupled with an index number between 0.0 and 1.0.
8616 First description in part must always be "default" 0.0.
8617
8618 @warning state name "custom" is reserved and can't be used in edc.
8619
8620 Defaults: "default" 0.0
8621 @endproperty
8622 */
8623 static void
st_collections_group_parts_part_description_state(void)8624 st_collections_group_parts_part_description_state(void)
8625 {
8626 Edje_Part *ep;
8627 Edje_Part_Description_Common *ed;
8628 char *s;
8629 double val;
8630
8631 check_min_arg_count(1);
8632
8633 ep = current_part;
8634
8635 s = parse_str(0);
8636 if (!strcmp(s, "custom"))
8637 {
8638 ERR("parse error %s:%i. invalid state name: '%s'.",
8639 file_in, line - 1, s);
8640 exit(-1);
8641 }
8642 if (get_arg_count() == 1)
8643 val = 0.0;
8644 else
8645 val = parse_float_range(1, 0.0, 1.0);
8646
8647 /* if only default desc exists and current desc is not default, commence paddling */
8648 if ((!ep->other.desc_count) && (EINA_DBL_NONZERO(val) || (!eina_streq(s, "default"))))
8649 {
8650 ERR("parse error %s:%i. invalid state name: '%s'. \"default\" state must always be first.",
8651 file_in, line - 1, s);
8652 exit(-1);
8653 }
8654 ed = ep->default_desc;
8655 if (ep->other.desc_count) ed = ep->other.desc[ep->other.desc_count - 1];
8656
8657 free((void *)ed->state.name);
8658 ed->state.name = s;
8659 ed->state.value = val;
8660
8661 _part_description_state_update(ed);
8662 }
8663
8664 /**
8665 @page edcref
8666 @property
8667 visible
8668 @parameters
8669 [0 or 1]
8670 @effect
8671 Takes a boolean value specifying whether part is visible (1) or not
8672 (0). Non-visible parts do not emit signals.
8673
8674 Defaults: 1
8675 @endproperty
8676 */
8677 static void
st_collections_group_parts_part_description_visible(void)8678 st_collections_group_parts_part_description_visible(void)
8679 {
8680 check_arg_count(1);
8681
8682 if (current_part->type == EDJE_PART_TYPE_SPACER)
8683 {
8684 ERR("parse error %s:%i. SPACER part can't have a visibility defined",
8685 file_in, line - 1);
8686 exit(-1);
8687 }
8688
8689 current_desc->visible = parse_bool(0);
8690 }
8691
8692 static void
st_collections_group_parts_part_description_vis(void)8693 st_collections_group_parts_part_description_vis(void)
8694 {
8695 check_arg_count(0);
8696
8697 if (current_part->type == EDJE_PART_TYPE_SPACER)
8698 {
8699 ERR("parse error %s:%i. SPACER part can't have a visibility defined",
8700 file_in, line - 1);
8701 exit(-1);
8702 }
8703
8704 current_desc->visible = 1;
8705 }
8706
8707 static void
st_collections_group_parts_part_description_hid(void)8708 st_collections_group_parts_part_description_hid(void)
8709 {
8710 check_arg_count(0);
8711
8712 if (current_part->type == EDJE_PART_TYPE_SPACER)
8713 {
8714 ERR("parse error %s:%i. SPACER part can't have a visibility defined",
8715 file_in, line - 1);
8716 exit(-1);
8717 }
8718
8719 current_desc->visible = 0;
8720 }
8721
8722 /**
8723 @page edcref
8724 @property
8725 no_render
8726 @parameters
8727 [0 or 1]
8728 @effect
8729 Same as setting no_render in part, but can be changed in different states.
8730
8731 Defaults: 0
8732 @since 1.19
8733 @endproperty
8734 */
8735 static void
st_collections_group_parts_part_description_no_render(void)8736 st_collections_group_parts_part_description_no_render(void)
8737 {
8738 if (current_part->type == EDJE_PART_TYPE_SPACER)
8739 {
8740 ERR("parse error %s:%i. SPACER part can't be marked as no_render",
8741 file_in, line - 1);
8742 exit(-1);
8743 }
8744
8745 if (check_range_arg_count(0, 1) == 1)
8746 EDJE_DESC_NO_RENDER_SET(current_desc, parse_bool(0));
8747 else /* lazEDC form */
8748 EDJE_DESC_NO_RENDER_SET(current_desc, 1);
8749 }
8750
8751 /**
8752 @page edcref
8753 @property
8754 limit
8755 @parameters
8756 [mode]
8757 @effect
8758 Emit a signal when the part size change from zero or to a zero size
8759 ('limit,width,over', 'limit,width,zero'). By default no signal are
8760 emitted. Valid values are:
8761 @li NONE
8762 @li WIDTH
8763 @li HEIGHT
8764 @li BOTH
8765
8766 Defaults: NONE
8767 @since 1.7
8768 @endproperty
8769 */
8770 static void
st_collections_group_parts_part_description_limit(void)8771 st_collections_group_parts_part_description_limit(void)
8772 {
8773 check_arg_count(1);
8774
8775 current_desc->limit = parse_enum(0,
8776 "NONE", 0,
8777 "WIDTH", 1,
8778 "HEIGHT", 2,
8779 "BOTH", 3);
8780
8781 if (current_desc->limit)
8782 {
8783 Edje_Part_Collection *pc;
8784 int count;
8785
8786 pc = eina_list_data_get(eina_list_last(edje_collections));
8787 count = pc->limits.parts_count++;
8788 pc->limits.parts = realloc(pc->limits.parts,
8789 pc->limits.parts_count * sizeof (Edje_Part_Limit));
8790 data_queue_part_reallocated_lookup(pc, current_part->name,
8791 (unsigned char **)&(pc->limits.parts),
8792 (unsigned char *)&pc->limits.parts[count].part - (unsigned char *)pc->limits.parts); //fixme
8793 }
8794 }
8795
8796 /**
8797 @page edcref
8798 @property
8799 align
8800 @parameters
8801 [X axis] [Y axis]
8802 @effect
8803 When the displayed object's size is smaller (or bigger) than
8804 its container, this property moves it relatively along both
8805 axis inside its container. @c "0.0" means left/top edges of
8806 the object touching container's respective ones, while @c
8807 "1.0" stands for right/bottom edges of the object (on
8808 horizontal/vertical axis, respectively).
8809
8810 Defaults: 0.5 0.5
8811 @endproperty
8812 */
8813 static void
st_collections_group_parts_part_description_align(void)8814 st_collections_group_parts_part_description_align(void)
8815 {
8816 check_has_anchors();
8817 check_arg_count(2);
8818
8819 current_desc->align.x = FROM_DOUBLE(parse_float_range(0, 0.0, 1.0));
8820 current_desc->align.y = FROM_DOUBLE(parse_float_range(1, 0.0, 1.0));
8821 }
8822
8823 /**
8824 @page edcref
8825 @property
8826 fixed
8827 @parameters
8828 [width, 0 or 1] [height, 0 or 1]
8829 @effect
8830 This affects the minimum size calculation. See
8831 edje_object_size_min_calc() and edje_object_size_min_restricted_calc().
8832 This tells the min size calculation routine that this part does not
8833 change group size in width or height (1 for it doesn't, 0 for it does),
8834 so the routine should not try and expand or contract the group.
8835
8836 Defaults: 0 0
8837 @endproperty
8838 */
8839 static void
st_collections_group_parts_part_description_fixed(void)8840 st_collections_group_parts_part_description_fixed(void)
8841 {
8842 check_has_anchors();
8843 check_arg_count(2);
8844
8845 current_desc->fixed.w = parse_bool(0);
8846 current_desc->fixed.h = parse_bool(1);
8847
8848 current_desc->user_set.fixed = EINA_TRUE;
8849 }
8850
8851 /**
8852 @page edcref
8853 @property
8854 min
8855 @parameters
8856 [width] [height] or SOURCE
8857 @effect
8858 The minimum size of the state.
8859
8860 When min is defined to SOURCE, it will look at the original
8861 image size and enforce it minimal size to match at least the
8862 original one. The part must be an IMAGE or a GROUP part.
8863
8864 Defaults: 0 0
8865 @endproperty
8866 */
8867 static void
st_collections_group_parts_part_description_min(void)8868 st_collections_group_parts_part_description_min(void)
8869 {
8870 check_min_arg_count(1);
8871
8872 if (is_param(1))
8873 {
8874 current_desc->min.w = parse_int_range(0, 0, 0x7fffffff);
8875 current_desc->min.h = parse_int_range(1, 0, 0x7fffffff);
8876 }
8877 else
8878 {
8879 char *tmp;
8880
8881 tmp = parse_str(0);
8882 if ((current_part->type != EDJE_PART_TYPE_IMAGE && current_part->type != EDJE_PART_TYPE_GROUP) ||
8883 !tmp || strcmp(tmp, "SOURCE") != 0)
8884 {
8885 free(tmp);
8886 ERR("parse error %s:%i. "
8887 "Only IMAGE and GROUP part can have a min: SOURCE; defined",
8888 file_in, line - 1);
8889 exit(-1);
8890 }
8891 free(tmp);
8892
8893 current_desc->min.limit = EINA_TRUE;
8894 }
8895 }
8896
8897 /**
8898 @page edcref
8899 @property
8900 minmul
8901 @parameters
8902 [width multiplier] [height multiplier]
8903 @effect
8904 A multiplier FORCIBLY applied to whatever minimum size is only during
8905 minimum size calculation.
8906
8907 Defaults: 1.0 1.0
8908 @since 1.2
8909 @endproperty
8910 */
8911 static void
st_collections_group_parts_part_description_minmul(void)8912 st_collections_group_parts_part_description_minmul(void)
8913 {
8914 check_arg_count(2);
8915
8916 current_desc->minmul.w = FROM_DOUBLE(parse_float_range(0, 0, 999999));
8917 current_desc->minmul.h = FROM_DOUBLE(parse_float_range(1, 0, 999999));
8918 }
8919
8920 /**
8921 @page edcref
8922 @property
8923 max
8924 @parameters
8925 [width] [height] or SOURCE
8926 @effect
8927 The maximum size of the state. A size of -1 means that it will be ignored in one direction.
8928
8929 When max is set to SOURCE, edje will enforce the part to be
8930 not more than the original image size. The part must be an
8931 IMAGE part.
8932
8933 Defaults: -1 -1
8934 @endproperty
8935 */
8936 static void
st_collections_group_parts_part_description_max(void)8937 st_collections_group_parts_part_description_max(void)
8938 {
8939 check_min_arg_count(1);
8940
8941 if (is_param(1))
8942 {
8943 current_desc->max.w = parse_int_range(0, -1, 0x7fffffff);
8944 current_desc->max.h = parse_int_range(1, -1, 0x7fffffff);
8945 }
8946 else
8947 {
8948 char *tmp;
8949
8950 tmp = parse_str(0);
8951 if (current_part->type != EDJE_PART_TYPE_IMAGE ||
8952 !tmp || strcmp(tmp, "SOURCE") != 0)
8953 {
8954 free(tmp);
8955 ERR("parse error %s:%i. "
8956 "Only IMAGE part can have a max: SOURCE; defined",
8957 file_in, line - 1);
8958 exit(-1);
8959 }
8960 free(tmp);
8961
8962 current_desc->max.limit = EINA_TRUE;
8963 }
8964 }
8965
8966 /**
8967 @page edcref
8968 @property
8969 size_class
8970 @parameters
8971 [size class name]
8972 @effect
8973 The part will have the min and max size defined in the size class.
8974 "min" and "max" property in description can be overridden by the size class
8975 at runtime.
8976 @endproperty
8977 */
8978 static void
st_collections_group_parts_part_description_size_class(void)8979 st_collections_group_parts_part_description_size_class(void)
8980 {
8981 check_arg_count(1);
8982
8983 current_desc->size_class = parse_str(0);
8984 }
8985
8986 /**
8987 @page edcref
8988 @property
8989 step
8990 @parameters
8991 [width] [height]
8992 @effect
8993 Restricts resizing of each dimension to values divisible by its value.
8994 This causes the part to jump from value to value while resizing. The
8995 default value is "0 0" disabling stepping.
8996
8997 Defaults: 0.0 0.0
8998 @endproperty
8999 */
9000 static void
st_collections_group_parts_part_description_step(void)9001 st_collections_group_parts_part_description_step(void)
9002 {
9003 check_arg_count(2);
9004
9005 current_desc->step.x = parse_float_range(0, 0, 0x7fffffff);
9006 current_desc->step.y = parse_float_range(1, 0, 0x7fffffff);
9007 }
9008
9009 /**
9010 @page edcref
9011 @property
9012 aspect
9013 @parameters
9014 [min] [max]
9015 @effect
9016 Normally width and height can be resized to any values independently.
9017 The aspect property forces the width to height ratio to be kept between
9018 the minimum and maximum set. For example, "1.0 1.0" will increase the
9019 width a pixel for every pixel added to height. The default value is
9020 "0.0 0.0" disabling aspect.
9021
9022 Defaults: 0.0 0.0
9023 @endproperty
9024 */
9025 static void
st_collections_group_parts_part_description_aspect(void)9026 st_collections_group_parts_part_description_aspect(void)
9027 {
9028 check_arg_count(2);
9029
9030 current_desc->aspect.min = FROM_DOUBLE(parse_float_range(0, 0.0, 999999999.0));
9031 current_desc->aspect.max = FROM_DOUBLE(parse_float_range(1, 0.0, 999999999.0));
9032 }
9033
9034 /**
9035 @page edcref
9036 @property
9037 aspect_preference
9038 @parameters
9039 [DIMENSION]
9040 @effect
9041 Sets the scope of the "aspect" property to a given dimension. Available
9042 options are BOTH, VERTICAL, HORIZONTAL, SOURCE and NONE
9043
9044 Defaults: NONE
9045 @endproperty
9046 */
9047 static void
st_collections_group_parts_part_description_aspect_preference(void)9048 st_collections_group_parts_part_description_aspect_preference(void)
9049 {
9050 check_arg_count(1);
9051
9052 current_desc->aspect.prefer = parse_enum(0,
9053 "NONE", EDJE_ASPECT_PREFER_NONE,
9054 "VERTICAL", EDJE_ASPECT_PREFER_VERTICAL,
9055 "HORIZONTAL", EDJE_ASPECT_PREFER_HORIZONTAL,
9056 "BOTH", EDJE_ASPECT_PREFER_BOTH,
9057 "SOURCE", EDJE_ASPECT_PREFER_SOURCE,
9058 NULL);
9059 }
9060
9061 /**
9062 @page edcref
9063 @property
9064 color_class
9065 @parameters
9066 [color class name]
9067 @effect
9068 The part will use the color values of the named color_class, these
9069 values can be modified by the "color", "color2" and "color3"
9070 properties set below.
9071 @endproperty
9072 */
9073 static void
st_collections_group_parts_part_description_color_class(void)9074 st_collections_group_parts_part_description_color_class(void)
9075 {
9076 check_arg_count(1);
9077
9078 if (current_part->type == EDJE_PART_TYPE_SPACER)
9079 {
9080 ERR("parse error %s:%i. SPACER part can't have a color defined",
9081 file_in, line - 1);
9082 exit(-1);
9083 }
9084
9085 current_desc->color_class = parse_str(0);
9086 }
9087
9088 /**
9089 @page edcref
9090 @property
9091 color
9092 @parameters
9093 [red] [green] [blue] [alpha] or "#[RR][GG][BB](AA)" or "#[R][G][B](A)"
9094 @effect
9095 Sets the main color.
9096
9097 Format:
9098 @li [red] [green] [blue] [alpha]: one integer [0-255] for each
9099 RGBA channel, i.e. 255 0 0 255
9100 @li "#[RR][GG][BB](AA)": string with two hex values per RGBA channel,
9101 i.e "#FF0000FF" or "#FF0000"
9102 @li "#[R][G][B](A)": string with one hex value per RGBA channel,
9103 i.e "#F00F" or "#F00".\n
9104 In string format you can omit alpha channel and it will be set to FF.
9105
9106 If color_class is set resulting color channel values will be (color * color_class / 255)
9107
9108 Defaults: 255 255 255 255
9109 @endproperty
9110 */
9111 static void
st_collections_group_parts_part_description_color(void)9112 st_collections_group_parts_part_description_color(void)
9113 {
9114 if (current_part->type == EDJE_PART_TYPE_SPACER)
9115 {
9116 ERR("parse error %s:%i. SPACER part can't have a color defined",
9117 file_in, line - 1);
9118 exit(-1);
9119 }
9120
9121 parse_color(0, &(current_desc->color.r));
9122 }
9123
9124 /**
9125 @page edcref
9126 @property
9127 color2
9128 @parameters
9129 [red] [green] [blue] [alpha] or "#[RR][GG][BB](AA)" or "#[R][G][B](A)"
9130 @effect
9131 Sets the text outline color.
9132
9133 Format:
9134 @li [red] [green] [blue] [alpha]: one integer [0-255] for each
9135 RGBA channel, i.e. 255 0 0 255
9136 @li "#[RR][GG][BB](AA)": string with two hex values per RGBA channel,
9137 i.e "#FF0000FF" or "#FF0000"
9138 @li "#[R][G][B](A)": string with one hex value per RGBA channel,
9139 i.e "#F00F" or "#F00".\n
9140 In string format you can omit alpha channel and it will be set to FF.
9141
9142 If color_class is set resulting color channel values will be (color * color_class / 255)
9143
9144 Defaults: 0 0 0 255
9145 @endproperty
9146 */
9147 static void
st_collections_group_parts_part_description_color2(void)9148 st_collections_group_parts_part_description_color2(void)
9149 {
9150 if (current_part->type == EDJE_PART_TYPE_SPACER)
9151 {
9152 ERR("parse error %s:%i. SPACER part can't have a color defined",
9153 file_in, line - 1);
9154 exit(-1);
9155 }
9156
9157 parse_color(0, &(current_desc->color2.r));
9158 }
9159
9160 /**
9161 @page edcref
9162 @property
9163 color3
9164 @parameters
9165 [red] [green] [blue] [alpha] or "#[RR][GG][BB](AA)" or "#[R][G][B](A)"
9166 @effect
9167 Sets the text shadow color.
9168
9169 Format:
9170 @li [red] [green] [blue] [alpha]: one integer [0-255] for each
9171 RGBA channel, i.e. 255 0 0 255
9172 @li "#[RR][GG][BB](AA)": string with two hex values per RGBA channel,
9173 i.e "#FF0000FF" or "#FF0000"
9174 @li "#[R][G][B](A)": string with one hex value per RGBA channel,
9175 i.e "#F00F" or "#F00".\n
9176 In string format you can omit alpha channel and it will be set to FF.
9177
9178 If color_class is set resulting color channel values will be (color * color_class / 255)
9179
9180 Defaults: 0 0 0 128
9181 @endproperty
9182 */
9183 static void
st_collections_group_parts_part_description_color3(void)9184 st_collections_group_parts_part_description_color3(void)
9185 {
9186 Edje_Part_Collection *pc;
9187 Edje_Part_Description_Text *ed;
9188
9189 pc = eina_list_data_get(eina_list_last(edje_collections));
9190
9191 if (current_part->type != EDJE_PART_TYPE_TEXT
9192 && current_part->type != EDJE_PART_TYPE_TEXTBLOCK)
9193 {
9194 ERR("Setting color3 in part %s from %s not of type TEXT or TEXTBLOCK.",
9195 current_part->name, pc->part);
9196 exit(-1);
9197 }
9198
9199 ed = (Edje_Part_Description_Text *)current_desc;
9200
9201 parse_color(0, &(ed->text.color3.r));
9202 }
9203
9204 /**
9205 @page edcref
9206 @property
9207 clip_to
9208 @parameters
9209 [another part's name]
9210 @effect
9211 Overrides the 'clip_to' property of this part. This allows switching
9212 clippers (or masks) at runtime by changing this part's state. When
9213 transitioning between two states, the switch of the clipper shall
9214 happen at the end of the animation, when the new state is finally set
9215 (this is similar to the 'visible' flag).
9216 @endproperty
9217 */
9218 static void
st_collections_group_parts_part_description_clip_to_id(void)9219 st_collections_group_parts_part_description_clip_to_id(void)
9220 {
9221 Edje_Part_Collection *pc;
9222
9223 check_arg_count(1);
9224
9225 pc = eina_list_data_get(eina_list_last(edje_collections));
9226 {
9227 char *name;
9228
9229 name = parse_str(0);
9230 data_queue_part_lookup(pc, name, &(current_desc->clip_to_id));
9231 free(name);
9232 }
9233 }
9234
9235 /**
9236 @page edcref
9237 @property
9238 offset_scale
9239 @parameters
9240 [1 or 0]
9241 @effect
9242 Makes rel1/2 offset values scale by scale factor like min/max if set
9243 to 1, otherwise 0 means they will not scale. Note that the part
9244 as a whole has to be set to scale too like:
9245
9246 part { name: "partname"; scale: 1;
9247 ...
9248
9249 Defaults: 0
9250 @endproperty
9251 */
9252 static void
st_collections_group_parts_part_description_offset_scale(void)9253 st_collections_group_parts_part_description_offset_scale(void)
9254 {
9255 if (get_arg_count() == 1)
9256 current_desc->offset_is_scaled = parse_bool(0);
9257 else
9258 current_desc->offset_is_scaled = EINA_TRUE;
9259 }
9260
9261 /** @edcsubsection{collections_group_parts_description_relatives,
9262 * Group.Parts.Part.Description.Relatives (rel1/rel2)} */
9263
9264 /**
9265 @page edcref
9266 @block
9267 rel1/rel2/rel
9268 @context
9269 description {
9270 ..
9271 rel1 {
9272 relative: 0.0 0.0;
9273 offset: 0 0;
9274 }
9275 ..
9276 rel2 {
9277 relative: 1.0 1.0;
9278 offset: -1 -1;
9279 }
9280 ..
9281 rel {
9282 to: "somepart";
9283 }
9284 ..
9285 }
9286 @description
9287 The rel1 and rel2 blocks are used to define the position of each corner
9288 of the part's container. With rel1 being the left-up corner and rel2
9289 being the right-down corner; rel (no number) is equivalent to setting both
9290 rel1 AND rel2 since 1.14.
9291 @endblock
9292
9293 @property
9294 relative
9295 @parameters
9296 [X axis] [Y axis]
9297 @effect
9298 Moves a corner to a relative position inside the container of the
9299 relative "to" part. Values from 0.0 (0%, beginning) to 1.0 (100%, end)
9300 of each axis.
9301
9302 Defaults:
9303 @li rel1.relative: 0.0 0.0
9304 @li rel2.relative: 1.0 1.0
9305 @endproperty
9306 */
9307 static void
st_collections_group_parts_part_description_rel1_relative(void)9308 st_collections_group_parts_part_description_rel1_relative(void)
9309 {
9310 check_has_anchors();
9311 check_arg_count(2);
9312
9313 current_desc->rel1.relative_x = FROM_DOUBLE(parse_float(0));
9314 current_desc->rel1.relative_y = FROM_DOUBLE(parse_float(1));
9315 }
9316
9317 /**
9318 @page edcref
9319 @property
9320 offset
9321 @parameters
9322 [X axis] [Y axis]
9323 @effect
9324 Affects the corner position a fixed number of pixels along each axis.
9325
9326 Defaults:
9327 @li rel1.offset: 0 0
9328 @li rel2.offset: -1 -1
9329 @endproperty
9330 */
9331 static void
st_collections_group_parts_part_description_rel1_offset(void)9332 st_collections_group_parts_part_description_rel1_offset(void)
9333 {
9334 check_has_anchors();
9335 check_arg_count(2);
9336
9337 current_desc->rel1.offset_x = parse_int(0);
9338 current_desc->rel1.offset_y = parse_int(1);
9339 }
9340
9341 /**
9342 @page edcref
9343 @property
9344 to
9345 @parameters
9346 [another part's name]
9347 @effect
9348 Causes a corner to be positioned relatively to another part's
9349 container. Setting to "" will unset this value for inherited
9350 parts.
9351 @endproperty
9352 */
9353 static void
st_collections_group_parts_part_description_rel1_to_set(const char * name)9354 st_collections_group_parts_part_description_rel1_to_set(const char *name)
9355 {
9356 Edje_Part_Collection *pc;
9357 pc = eina_list_data_get(eina_list_last(edje_collections));
9358 data_queue_part_lookup(pc, name, &(current_desc->rel1.id_x));
9359 data_queue_part_lookup(pc, name, &(current_desc->rel1.id_y));
9360 }
9361
9362 static void
st_collections_group_parts_part_description_rel_to(void)9363 st_collections_group_parts_part_description_rel_to(void)
9364 {
9365 check_has_anchors();
9366 check_arg_count(1);
9367
9368 {
9369 char *name;
9370 name = parse_str(0);
9371 st_collections_group_parts_part_description_rel1_to_set(name);
9372 st_collections_group_parts_part_description_rel2_to_set(name);
9373 free(name);
9374 }
9375 }
9376
9377 static void
st_collections_group_parts_part_description_rel1_to(void)9378 st_collections_group_parts_part_description_rel1_to(void)
9379 {
9380 check_has_anchors();
9381 check_arg_count(1);
9382
9383 {
9384 char *name;
9385 name = parse_str(0);
9386 st_collections_group_parts_part_description_rel1_to_set(name);
9387 free(name);
9388 }
9389 }
9390
9391 /**
9392 @page edcref
9393 @property
9394 to_x
9395 @parameters
9396 [another part's name]
9397 @effect
9398 Causes a corner to be positioned relatively to the X axis of another
9399 part's container. Simply put affects the first parameter of "relative".
9400 Setting to "" will unset this value for inherited parts.
9401 @endproperty
9402 */
9403 static void
st_collections_group_parts_part_description_rel_to_x(void)9404 st_collections_group_parts_part_description_rel_to_x(void)
9405 {
9406 Edje_Part_Collection *pc;
9407
9408 check_has_anchors();
9409 check_arg_count(1);
9410
9411 pc = eina_list_data_get(eina_list_last(edje_collections));
9412
9413 {
9414 char *name;
9415
9416 name = parse_str(0);
9417 data_queue_part_lookup(pc, name, &(current_desc->rel1.id_x));
9418 data_queue_part_lookup(pc, name, &(current_desc->rel2.id_x));
9419 free(name);
9420 }
9421 }
9422
9423 static void
st_collections_group_parts_part_description_rel1_to_x(void)9424 st_collections_group_parts_part_description_rel1_to_x(void)
9425 {
9426 Edje_Part_Collection *pc;
9427
9428 check_has_anchors();
9429 check_arg_count(1);
9430
9431 pc = eina_list_data_get(eina_list_last(edje_collections));
9432
9433 {
9434 char *name;
9435
9436 name = parse_str(0);
9437 data_queue_part_lookup(pc, name, &(current_desc->rel1.id_x));
9438 free(name);
9439 }
9440 }
9441
9442 /**
9443 @page edcref
9444 @property
9445 to_y
9446 @parameters
9447 [another part's name]
9448 @effect
9449 Causes a corner to be positioned relatively to the Y axis of another
9450 part's container. Simply put, affects the second parameter of
9451 "relative". Setting to "" will unset this value for inherited parts.
9452 @endproperty
9453 */
9454 static void
st_collections_group_parts_part_description_rel_to_y(void)9455 st_collections_group_parts_part_description_rel_to_y(void)
9456 {
9457 Edje_Part_Collection *pc;
9458
9459 check_has_anchors();
9460 check_arg_count(1);
9461
9462 pc = eina_list_data_get(eina_list_last(edje_collections));
9463
9464 {
9465 char *name;
9466
9467 name = parse_str(0);
9468 data_queue_part_lookup(pc, name, &(current_desc->rel1.id_y));
9469 data_queue_part_lookup(pc, name, &(current_desc->rel2.id_y));
9470 free(name);
9471 }
9472 }
9473
9474 static void
st_collections_group_parts_part_description_rel1_to_y(void)9475 st_collections_group_parts_part_description_rel1_to_y(void)
9476 {
9477 Edje_Part_Collection *pc;
9478
9479 check_has_anchors();
9480 check_arg_count(1);
9481
9482 pc = eina_list_data_get(eina_list_last(edje_collections));
9483
9484 {
9485 char *name;
9486
9487 name = parse_str(0);
9488 data_queue_part_lookup(pc, name, &(current_desc->rel1.id_y));
9489 free(name);
9490 }
9491 }
9492
9493 static void
st_collections_group_parts_part_description_rel2_relative(void)9494 st_collections_group_parts_part_description_rel2_relative(void)
9495 {
9496 check_has_anchors();
9497 check_arg_count(2);
9498
9499 current_desc->rel2.relative_x = FROM_DOUBLE(parse_float(0));
9500 current_desc->rel2.relative_y = FROM_DOUBLE(parse_float(1));
9501 }
9502
9503 static void
st_collections_group_parts_part_description_rel2_offset(void)9504 st_collections_group_parts_part_description_rel2_offset(void)
9505 {
9506 check_has_anchors();
9507 check_arg_count(2);
9508
9509 current_desc->rel2.offset_x = parse_int(0);
9510 current_desc->rel2.offset_y = parse_int(1);
9511 }
9512
9513 static void
st_collections_group_parts_part_description_rel2_to_set(const char * name)9514 st_collections_group_parts_part_description_rel2_to_set(const char *name)
9515 {
9516 Edje_Part_Collection *pc;
9517 pc = eina_list_data_get(eina_list_last(edje_collections));
9518 data_queue_part_lookup(pc, name, &(current_desc->rel2.id_x));
9519 data_queue_part_lookup(pc, name, &(current_desc->rel2.id_y));
9520 }
9521
9522 static void
st_collections_group_parts_part_description_rel2_to(void)9523 st_collections_group_parts_part_description_rel2_to(void)
9524 {
9525 check_has_anchors();
9526 check_arg_count(1);
9527
9528 {
9529 char *name;
9530 name = parse_str(0);
9531 st_collections_group_parts_part_description_rel2_to_set(name);
9532 free(name);
9533 }
9534 }
9535
9536 static void
st_collections_group_parts_part_description_rel2_to_x(void)9537 st_collections_group_parts_part_description_rel2_to_x(void)
9538 {
9539 Edje_Part_Collection *pc;
9540
9541 check_has_anchors();
9542 check_arg_count(1);
9543
9544 pc = eina_list_data_get(eina_list_last(edje_collections));
9545
9546 {
9547 char *name;
9548
9549 name = parse_str(0);
9550 data_queue_part_lookup(pc, name, &(current_desc->rel2.id_x));
9551 free(name);
9552 }
9553 }
9554
9555 static void
st_collections_group_parts_part_description_rel2_to_y(void)9556 st_collections_group_parts_part_description_rel2_to_y(void)
9557 {
9558 Edje_Part_Collection *pc;
9559
9560 check_has_anchors();
9561 check_arg_count(1);
9562
9563 pc = eina_list_data_get(eina_list_last(edje_collections));
9564
9565 {
9566 char *name;
9567
9568 name = parse_str(0);
9569 data_queue_part_lookup(pc, name, &(current_desc->rel2.id_y));
9570 free(name);
9571 }
9572 }
9573
9574 /** @edcsubsection{collections_group_parts_description_anchors,
9575 * Group.Parts.Part.Description.Anchors} */
9576
9577 /**
9578 @page edcref
9579 @block
9580 anchors
9581 @context
9582 // This part will be expanded from the top-left corner of edje group
9583 part { name : "part1";
9584 description { state: "default" 0.0;
9585 anchors {
9586 top: GROUP TOP;
9587 left: GROUP; // This means 'left: GROUP LEFT;'
9588 }
9589 min: 50 50;
9590 }
9591 }
9592 // This part will be expanded from the bottom-right corner of "part1"
9593 // to the bottom-right
9594 part { name: "part2";
9595 description { state: "default" 0.0;
9596 anchors {
9597 top: "part1" BOTTOM;
9598 left: "part1"; // This means 'left: "part1" RIGHT;'
9599 }
9600 min: 50 50;
9601 }
9602 }
9603 // This part will be expanded from the right edje of "part2" to the right
9604 part { name: "part3";
9605 description { state: "default" 0.0;
9606 anchors {
9607 left: "part2";
9608 fill: "part2" VERTICAL;
9609 }
9610 min: 100 0; // The height will be determined by the height of "part2"
9611 }
9612 }
9613 // This part will be expanded from the center of right edge of "part3"
9614 // to the bottom-right corner of edje group
9615 part { name: "part4";
9616 description { state: "default" 0.0;
9617 anchors {
9618 top: "part3" VERTICAL_CENTER;
9619 left: "part3";
9620 right: GROUP;
9621 bottom: GROUP;
9622 }
9623 }
9624 }
9625 @description
9626 The anchors blocks are used to define the position of each edge of
9627 the part's container. Anchors will change relative, align and fixed
9628 attributes internally, so setting both of them is not allowed.
9629 When the second parameter of position enumeration is omitted, anchoring
9630 a part to the other part will put the part adjacent to the given part.
9631 However, if the part is anchored to edje group, the part will be contained
9632 inside the group.
9633 @endblock
9634
9635 @property
9636 anchors
9637 @parameters
9638 [partname] [the edge of other part]
9639 @effect
9640 Moves an edge of the part to the position of the edge of given part or
9641 whole edje group. (GROUP means edje group that the part belong to)
9642 @endproperty
9643 */
9644
9645 static void
check_has_anchors(void)9646 check_has_anchors(void)
9647 {
9648 if (current_anchors)
9649 {
9650 ERR("parse error %s:%i. Anchors and Relatives(rel/align/fixed) cannot be used at the same time.",
9651 file_in, line - 1);
9652 exit(-1);
9653 }
9654
9655 has_relatives = EINA_TRUE;
9656 }
9657
9658 static void
check_has_relatives(void)9659 check_has_relatives(void)
9660 {
9661 if (!beta)
9662 error_and_abort(NULL, "Anchors are currently a beta feature, please enable them by running edje_cc with -beta.");
9663
9664 if (has_relatives)
9665 {
9666 ERR("parse error %s:%i. Anchors and Relatives(rel/align/fixed) cannot be used at the same time.",
9667 file_in, line - 1);
9668 exit(-1);
9669 }
9670
9671 current_desc->offset_is_scaled = EINA_TRUE;
9672 }
9673
9674 static void
parse_anchor_line(Edje_Part_Anchor * anchor,Edje_Part_Anchor_Line undefined)9675 parse_anchor_line(Edje_Part_Anchor *anchor, Edje_Part_Anchor_Line undefined)
9676 {
9677 int nargs;
9678 char *name;
9679
9680 nargs = get_arg_count();
9681 if (!nargs || (nargs > 2))
9682 {
9683 ERR("parse error %s:%i. Anchors should have a name of part and base line.",
9684 file_in, line - 1);
9685 exit(-1);
9686 }
9687
9688 name = parse_str(0);
9689 anchor->set = EINA_TRUE;
9690
9691 if (nargs == 2)
9692 anchor->base.line = parse_enum(1,
9693 "TOP", EDJE_PART_ANCHOR_LINE_TOP,
9694 "BOTTOM", EDJE_PART_ANCHOR_LINE_BOTTOM,
9695 "LEFT", EDJE_PART_ANCHOR_LINE_LEFT,
9696 "RIGHT", EDJE_PART_ANCHOR_LINE_RIGHT,
9697 "VERTICAL_CENTER", EDJE_PART_ANCHOR_LINE_VERTICAL_CENTER,
9698 "HORIZONTAL_CENTER", EDJE_PART_ANCHOR_LINE_HORIZONTAL_CENTER,
9699 "*", EDJE_PART_ANCHOR_LINE_RELATIVE,
9700 NULL);
9701 else if (strcmp(name, "GROUP") || param_had_quote(0))
9702 anchor->base.line = undefined;
9703
9704 free(name);
9705 }
9706
9707 static void
parse_anchor_fill(Edje_Part_Anchor * anchor)9708 parse_anchor_fill(Edje_Part_Anchor *anchor)
9709 {
9710 int nargs;
9711
9712 nargs = get_arg_count();
9713 if (!nargs || (nargs > 2))
9714 {
9715 ERR("parse error %s:%i. Anchors should have a name of part and base line.",
9716 file_in, line - 1);
9717 exit(-1);
9718 }
9719
9720 anchor->set = EINA_TRUE;
9721
9722 if (nargs == 2)
9723 anchor->base.fill = parse_enum(1,
9724 "BOTH", EDJE_PART_ANCHOR_FILL_BOTH,
9725 "HORIZONTAL", EDJE_PART_ANCHOR_FILL_HORIZONTAL,
9726 "VERTICAL", EDJE_PART_ANCHOR_FILL_VERTICAL,
9727 NULL);
9728 else
9729 anchor->base.fill = EDJE_PART_ANCHOR_FILL_BOTH;
9730 }
9731
9732 static void
anchor_queue_part_lookup(int * part,int * counterpart,Eina_Bool counterpart_is_set)9733 anchor_queue_part_lookup(int *part, int *counterpart, Eina_Bool counterpart_is_set)
9734 {
9735 Edje_Part_Collection *pc;
9736 char *name;
9737
9738 pc = eina_list_data_get(eina_list_last(edje_collections));
9739
9740 name = parse_str(0);
9741 if (!strcmp(name, "GROUP") && !param_had_quote(0))
9742 goto end;
9743
9744 data_queue_part_lookup(pc, name, part);
9745
9746 if (!counterpart_is_set)
9747 data_queue_part_lookup(pc, name, counterpart);
9748
9749 end:
9750 free(name);
9751 }
9752
9753 static void
anchor_dequeue_part_lookup(int * part,Eina_Bool counterpart_is_set)9754 anchor_dequeue_part_lookup(int *part, Eina_Bool counterpart_is_set)
9755 {
9756 Edje_Part_Collection *pc;
9757
9758 pc = eina_list_data_get(eina_list_last(edje_collections));
9759
9760 if (counterpart_is_set && part)
9761 part_lookup_del(pc, part);
9762 }
9763
9764 static void
anchor_adjust_align(FLOAT_T * align,FLOAT_T val,unsigned char * fixed,Eina_Bool counterpart_is_set)9765 anchor_adjust_align(FLOAT_T *align, FLOAT_T val, unsigned char *fixed, Eina_Bool counterpart_is_set)
9766 {
9767 if (counterpart_is_set)
9768 {
9769 *align = 0.5;
9770 *fixed = 0;
9771 }
9772 else
9773 {
9774 *align = val;
9775 *fixed = 1;
9776 }
9777 }
9778
9779 static void
anchor_adjust_relative(const Edje_Part_Anchor_Line * anchor_lines,FLOAT_T * rel,FLOAT_T * relc,Edje_Part_Anchor_Line anchor_line,Edje_Part_Anchor_Line base,Eina_Bool counterpart_is_set)9780 anchor_adjust_relative(const Edje_Part_Anchor_Line *anchor_lines, FLOAT_T *rel, FLOAT_T *relc, Edje_Part_Anchor_Line anchor_line, Edje_Part_Anchor_Line base, Eina_Bool counterpart_is_set)
9781 {
9782 if (anchor_line == EDJE_PART_ANCHOR_LINE_NONE)
9783 anchor_line = base;
9784
9785 if (anchor_line == anchor_lines[0])
9786 {
9787 *rel = FROM_DOUBLE(0.0);
9788 if (!counterpart_is_set)
9789 *relc = FROM_DOUBLE(0.0);
9790 }
9791 else if (anchor_line == anchor_lines[1])
9792 {
9793 *rel = FROM_DOUBLE(1.0);
9794 if (!counterpart_is_set)
9795 *relc = FROM_DOUBLE(1.0);
9796 }
9797 else if (anchor_line == anchor_lines[2])
9798 {
9799 *rel = FROM_DOUBLE(0.5);
9800 if (!counterpart_is_set)
9801 *relc = FROM_DOUBLE(0.5);
9802 }
9803 else if (anchor_line == EDJE_PART_ANCHOR_LINE_RELATIVE)
9804 {
9805 *rel = FROM_DOUBLE(parse_float(1));
9806 if (!counterpart_is_set)
9807 *relc = FROM_DOUBLE(parse_float(1));
9808 }
9809 else
9810 {
9811 ERR("parse error %s:%i. Edje part is anchored to wrong position.",
9812 file_in, line - 1);
9813 exit(-1);
9814 }
9815 }
9816
9817 static void
anchor_adjust_relative_vertical(FLOAT_T * rel,FLOAT_T * relc,Edje_Part_Anchor_Line anchor_line,Edje_Part_Anchor_Line base,Eina_Bool counterpart_is_set)9818 anchor_adjust_relative_vertical(FLOAT_T *rel, FLOAT_T *relc, Edje_Part_Anchor_Line anchor_line, Edje_Part_Anchor_Line base, Eina_Bool counterpart_is_set)
9819 {
9820 static const Edje_Part_Anchor_Line anchor_lines[] = {
9821 EDJE_PART_ANCHOR_LINE_TOP,
9822 EDJE_PART_ANCHOR_LINE_BOTTOM,
9823 EDJE_PART_ANCHOR_LINE_VERTICAL_CENTER
9824 };
9825
9826 anchor_adjust_relative(anchor_lines, rel, relc, anchor_line, base, counterpart_is_set);
9827 }
9828
9829 static void
anchor_adjust_relative_horizontal(FLOAT_T * rel,FLOAT_T * relc,Edje_Part_Anchor_Line anchor_line,Edje_Part_Anchor_Line base,Eina_Bool counterpart_is_set)9830 anchor_adjust_relative_horizontal(FLOAT_T *rel, FLOAT_T *relc, Edje_Part_Anchor_Line anchor_line, Edje_Part_Anchor_Line base, Eina_Bool counterpart_is_set)
9831 {
9832 static const Edje_Part_Anchor_Line anchor_lines[] = {
9833 EDJE_PART_ANCHOR_LINE_LEFT,
9834 EDJE_PART_ANCHOR_LINE_RIGHT,
9835 EDJE_PART_ANCHOR_LINE_HORIZONTAL_CENTER
9836 };
9837
9838 anchor_adjust_relative(anchor_lines, rel, relc, anchor_line, base, counterpart_is_set);
9839 }
9840
9841 /**
9842 @page edcref
9843 @property
9844 top
9845 @parameters
9846 [partname] [TOP/BOTTOM/VERTICAL_CENTER]
9847 @effect
9848 Causes top edge to be positioned to the edge of another part's container.
9849 Setting to GROUP will indicate edje group instead of another part.
9850 If bottom anchor is not set, edje part will be expanded to the bottom.
9851 The second parameter of position enumeration can be omitted. (Default
9852 value is BOTTOM, but TOP when the part is anchored to edje group)
9853 @endproperty
9854 */
9855 static void
st_collections_group_parts_part_description_anchors_top(void)9856 st_collections_group_parts_part_description_anchors_top(void)
9857 {
9858 Eina_Bool counterpart_is_set;
9859
9860 check_has_relatives();
9861
9862 if (!current_anchors)
9863 current_anchors = mem_alloc(SZ(Edje_Part_Description_Anchors));
9864
9865 counterpart_is_set = current_anchors->bottom.set;
9866
9867 parse_anchor_line(&(current_anchors->top), EDJE_PART_ANCHOR_LINE_BOTTOM);
9868
9869 anchor_dequeue_part_lookup(&(current_desc->rel1.id_y), counterpart_is_set);
9870 anchor_queue_part_lookup(&(current_desc->rel1.id_y), &(current_desc->rel2.id_y), counterpart_is_set);
9871
9872 anchor_adjust_align(&(current_desc->align.y), 0.0, &(current_desc->fixed.h), counterpart_is_set);
9873 anchor_adjust_relative_vertical(&(current_desc->rel1.relative_y), &(current_desc->rel2.relative_y), current_anchors->top.base.line, EDJE_PART_ANCHOR_LINE_TOP, counterpart_is_set);
9874 }
9875
9876 /**
9877 @page edcref
9878 @property
9879 bottom
9880 @parameters
9881 [partname] [TOP/BOTTOM/VERTICAL_CENTER]
9882 @effect
9883 Causes bottom edge to be positioned to the edge of another part's container.
9884 Setting to GROUP will indicate edje group instead of another part.
9885 If top anchor is not set, edje part will be expanded to the top.
9886 The second parameter of position enumeration can be omitted. (Default
9887 value is TOP, but BOTTOM when the part is anchored to edje group)
9888 @endproperty
9889 */
9890 static void
st_collections_group_parts_part_description_anchors_bottom(void)9891 st_collections_group_parts_part_description_anchors_bottom(void)
9892 {
9893 Eina_Bool counterpart_is_set;
9894
9895 check_has_relatives();
9896
9897 if (!current_anchors)
9898 current_anchors = mem_alloc(SZ(Edje_Part_Description_Anchors));
9899
9900 counterpart_is_set = current_anchors->top.set;
9901
9902 parse_anchor_line(&(current_anchors->bottom), EDJE_PART_ANCHOR_LINE_TOP);
9903
9904 anchor_dequeue_part_lookup(&(current_desc->rel2.id_y), counterpart_is_set);
9905 anchor_queue_part_lookup(&(current_desc->rel2.id_y), &(current_desc->rel1.id_y), counterpart_is_set);
9906
9907 anchor_adjust_align(&(current_desc->align.y), 1.0, &(current_desc->fixed.h), counterpart_is_set);
9908 anchor_adjust_relative_vertical(&(current_desc->rel2.relative_y), &(current_desc->rel1.relative_y), current_anchors->bottom.base.line, EDJE_PART_ANCHOR_LINE_BOTTOM, counterpart_is_set);
9909 }
9910
9911 /**
9912 @page edcref
9913 @property
9914 left
9915 @parameters
9916 [partname] [LEFT/RIGHT/HORIZONTAL_CENTER]
9917 @effect
9918 Causes left edge to be positioned to the edge of another part's container.
9919 Setting to GROUP will indicate edje group instead of another part.
9920 If right anchor is not set, edje part will be expanded to the right.
9921 The second parameter of position enumeration can be omitted. (Default
9922 value is RIGHT, but LEFT when the part is anchored to edje group)
9923 @endproperty
9924 */
9925 static void
st_collections_group_parts_part_description_anchors_left(void)9926 st_collections_group_parts_part_description_anchors_left(void)
9927 {
9928 Eina_Bool counterpart_is_set;
9929
9930 check_has_relatives();
9931
9932 if (!current_anchors)
9933 current_anchors = mem_alloc(SZ(Edje_Part_Description_Anchors));
9934
9935 counterpart_is_set = current_anchors->right.set;
9936
9937 parse_anchor_line(&(current_anchors->left), EDJE_PART_ANCHOR_LINE_RIGHT);
9938
9939 anchor_dequeue_part_lookup(&(current_desc->rel1.id_x), counterpart_is_set);
9940 anchor_queue_part_lookup(&(current_desc->rel1.id_x), &(current_desc->rel2.id_x), counterpart_is_set);
9941
9942 anchor_adjust_align(&(current_desc->align.x), 0.0, &(current_desc->fixed.w), counterpart_is_set);
9943 anchor_adjust_relative_horizontal(&(current_desc->rel1.relative_x), &(current_desc->rel2.relative_x), current_anchors->left.base.line, EDJE_PART_ANCHOR_LINE_LEFT, counterpart_is_set);
9944 }
9945
9946 /**
9947 @page edcref
9948 @property
9949 right
9950 @parameters
9951 [partname] [LEFT/RIGHT/HORIZONTAL_CENTER]
9952 @effect
9953 Causes right edge to be positioned to the edge of another part's container.
9954 Setting to GROUP will indicate edje group instead of another part.
9955 If left anchor is not set, edje part will be expanded to the left.
9956 The second parameter of position enumeration can be omitted. (Default
9957 value is LEFT, but RIGHT when the part is anchored to edje group)
9958 @endproperty
9959 */
9960 static void
st_collections_group_parts_part_description_anchors_right(void)9961 st_collections_group_parts_part_description_anchors_right(void)
9962 {
9963 Eina_Bool counterpart_is_set;
9964
9965 check_has_relatives();
9966
9967 if (!current_anchors)
9968 current_anchors = mem_alloc(SZ(Edje_Part_Description_Anchors));
9969
9970 counterpart_is_set = current_anchors->left.set;
9971
9972 parse_anchor_line(&(current_anchors->right), EDJE_PART_ANCHOR_LINE_LEFT);
9973
9974 anchor_dequeue_part_lookup(&(current_desc->rel2.id_x), counterpart_is_set);
9975 anchor_queue_part_lookup(&(current_desc->rel2.id_x), &(current_desc->rel1.id_x), counterpart_is_set);
9976
9977 anchor_adjust_align(&(current_desc->align.x), 1.0, &(current_desc->fixed.w), counterpart_is_set);
9978 anchor_adjust_relative_horizontal(&(current_desc->rel2.relative_x), &(current_desc->rel1.relative_x), current_anchors->right.base.line, EDJE_PART_ANCHOR_LINE_RIGHT, counterpart_is_set);
9979 }
9980
9981 /**
9982 @page edcref
9983 @property
9984 vertical_center
9985 @parameters
9986 [partname] [TOP/BOTTOM/VERTICAL_CENTER]
9987 @effect
9988 Causes (virtual) vertical center line to be positioned to the edge of
9989 another part's container. Setting to GROUP will indicate edje group instead
9990 of another part.
9991 This part will be expanded vertically in both directions, so do not
9992 set top or bottom anchor with vertical_center anchor.
9993 The second parameter of position enumeration can be omitted. (Default
9994 value is VERTICAL_CENTER)
9995 @endproperty
9996 */
9997 static void
st_collections_group_parts_part_description_anchors_vertical_center(void)9998 st_collections_group_parts_part_description_anchors_vertical_center(void)
9999 {
10000 check_has_relatives();
10001
10002 if (!current_anchors)
10003 current_anchors = mem_alloc(SZ(Edje_Part_Description_Anchors));
10004
10005 parse_anchor_line(&(current_anchors->vertical_center), EDJE_PART_ANCHOR_LINE_VERTICAL_CENTER);
10006
10007 anchor_queue_part_lookup(&(current_desc->rel1.id_y), &(current_desc->rel2.id_y), EINA_FALSE);
10008
10009 anchor_adjust_align(&(current_desc->align.y), 0.5, &(current_desc->fixed.h), EINA_FALSE);
10010 anchor_adjust_relative_vertical(&(current_desc->rel1.relative_y), &(current_desc->rel2.relative_y), current_anchors->vertical_center.base.line, EDJE_PART_ANCHOR_LINE_VERTICAL_CENTER, EINA_FALSE);
10011 }
10012
10013 /**
10014 @page edcref
10015 @property
10016 horizontal_center
10017 @parameters
10018 [partname] [LEFT/RIGHT/HORIZONTAL_CENTER]
10019 @effect
10020 Causes (virtual) horizontal center line to be positioned to the edge of
10021 another part's container. Setting to GROUP will indicate edje group instead
10022 of another part.
10023 This part will be expanded horizontally in both directions, so do not
10024 set left or right anchor with vertical_center anchor.
10025 The second parameter of position enumeration can be omitted. (Default
10026 value is HORIZONTAL_CENTER)
10027 @endproperty
10028 */
10029 static void
st_collections_group_parts_part_description_anchors_horizontal_center(void)10030 st_collections_group_parts_part_description_anchors_horizontal_center(void)
10031 {
10032 check_has_relatives();
10033
10034 if (!current_anchors)
10035 current_anchors = mem_alloc(SZ(Edje_Part_Description_Anchors));
10036
10037 parse_anchor_line(&(current_anchors->horizontal_center), EDJE_PART_ANCHOR_LINE_HORIZONTAL_CENTER);
10038
10039 anchor_queue_part_lookup(&(current_desc->rel1.id_x), &(current_desc->rel2.id_x), EINA_FALSE);
10040
10041 anchor_adjust_align(&(current_desc->align.x), 0.5, &(current_desc->fixed.w), EINA_FALSE);
10042 anchor_adjust_relative_horizontal(&(current_desc->rel1.relative_x), &(current_desc->rel2.relative_x), current_anchors->horizontal_center.base.line, EDJE_PART_ANCHOR_LINE_HORIZONTAL_CENTER, EINA_FALSE);
10043 }
10044
10045 /**
10046 @page edcref
10047 @property
10048 fill
10049 @parameters
10050 [partname] [BOTH/HORIZONTAL/VERTICAL]
10051 @effect
10052 Causes the part's container to expand to the width or height of another
10053 part's container. Setting to GROUP will indicate edje group instead of another part.
10054 Setting horizontal fill has same effect to setting top and bottom anchors
10055 to the same part.
10056 (setting vertical fill means left and right anchors to the same part)
10057 The second parameter of direction enumeration can be omitted. (Default
10058 value is BOTH)
10059 @endproperty
10060 */
10061 static void
st_collections_group_parts_part_description_anchors_fill(void)10062 st_collections_group_parts_part_description_anchors_fill(void)
10063 {
10064 Edje_Part_Collection *pc;
10065 char *name;
10066
10067 pc = eina_list_last_data_get(edje_collections);
10068
10069 check_has_relatives();
10070
10071 if (!current_anchors)
10072 current_anchors = mem_alloc(SZ(Edje_Part_Description_Anchors));
10073
10074 parse_anchor_fill(&(current_anchors->fill));
10075
10076 name = parse_str(0);
10077
10078 switch (current_anchors->fill.base.fill)
10079 {
10080 case EDJE_PART_ANCHOR_FILL_BOTH:
10081 if (strcmp("GROUP", name) || param_had_quote(0))
10082 {
10083 data_queue_part_lookup(pc, name, &(current_desc->rel1.id_x));
10084 data_queue_part_lookup(pc, name, &(current_desc->rel2.id_x));
10085 data_queue_part_lookup(pc, name, &(current_desc->rel1.id_y));
10086 data_queue_part_lookup(pc, name, &(current_desc->rel2.id_y));
10087 }
10088 current_desc->align.x = 0.5;
10089 current_desc->align.y = 0.5;
10090 current_desc->fixed.w = 0;
10091 current_desc->fixed.h = 0;
10092 break;
10093
10094 case EDJE_PART_ANCHOR_FILL_HORIZONTAL:
10095 if (strcmp("GROUP", name) || param_had_quote(0))
10096 {
10097 data_queue_part_lookup(pc, name, &(current_desc->rel1.id_x));
10098 data_queue_part_lookup(pc, name, &(current_desc->rel2.id_x));
10099 }
10100 current_desc->align.x = 0.5;
10101 current_desc->fixed.w = 0;
10102 break;
10103
10104 case EDJE_PART_ANCHOR_FILL_VERTICAL:
10105 if (strcmp("GROUP", name) || param_had_quote(0))
10106 {
10107 data_queue_part_lookup(pc, name, &(current_desc->rel1.id_y));
10108 data_queue_part_lookup(pc, name, &(current_desc->rel2.id_y));
10109 }
10110 current_desc->align.y = 0.5;
10111 current_desc->fixed.h = 0;
10112 break;
10113 }
10114
10115 free(name);
10116 }
10117
10118 /**
10119 @page edcref
10120 @property
10121 margin
10122 @parameters
10123 [left] [right] [top] [bottom]
10124 @effect
10125 Affects the edge position a fixed number of pixels along each direction.
10126 Margins will scale its size with an edje scaling factor.
10127 @endproperty
10128 */
10129 static void
st_collections_group_parts_part_description_anchors_margin(void)10130 st_collections_group_parts_part_description_anchors_margin(void)
10131 {
10132 check_has_relatives();
10133 check_arg_count(4);
10134
10135 current_desc->rel1.offset_x = parse_int(0);
10136 current_desc->rel2.offset_x = -parse_int(1) - 1;
10137 current_desc->rel1.offset_y = parse_int(2);
10138 current_desc->rel2.offset_y = -parse_int(3) - 1;
10139 }
10140
10141 static void
free_anchors(void)10142 free_anchors(void)
10143 {
10144 has_relatives = EINA_FALSE;
10145
10146 if (!current_anchors) return;
10147
10148 free(current_anchors);
10149 current_anchors = NULL;
10150 }
10151
10152 /** @edcsubsection{collections_group_parts_description_image,
10153 * Group.Parts.Part.Description.Image} */
10154
10155 /**
10156 @page edcref
10157 @block
10158 image
10159 @context
10160 description {
10161 ..
10162 image {
10163 normal: "filename.ext";
10164 normal: "filename.svg";
10165 tween: "filename2.ext";
10166 ..
10167 tween: "filenameN.ext";
10168 border: left right top bottom;
10169 middle: 0/1/NONE/DEFAULT/SOLID;
10170 fill { }
10171 }
10172 ..
10173 }
10174 @description
10175 @endblock
10176
10177 @property
10178 normal
10179 @parameters
10180 [image's filename]
10181 @effect
10182 Name of image to be used as previously declared in the images block.
10183 In an animation, this is the first and last image displayed. It's
10184 required in any image part
10185 @endproperty
10186 */
10187 static void
st_collections_group_parts_part_description_image_normal(void)10188 st_collections_group_parts_part_description_image_normal(void)
10189 {
10190 Edje_Part_Description_Image *ed;
10191
10192 check_arg_count(1);
10193
10194 if (current_part->type == EDJE_PART_TYPE_VECTOR)
10195 {
10196 return _handle_vector_image();
10197 }
10198
10199 if (current_part->type != EDJE_PART_TYPE_IMAGE)
10200 {
10201 ERR("parse error %s:%i. "
10202 "image attributes in non-IMAGE part.",
10203 file_in, line - 1);
10204 exit(-1);
10205 }
10206
10207 ed = (Edje_Part_Description_Image *)current_desc;
10208
10209 {
10210 char *name;
10211
10212 if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
10213 ed->image.set = EINA_TRUE;
10214
10215 name = parse_str(0);
10216 data_queue_image_remove(&(ed->image.id), &(ed->image.set));
10217 data_queue_image_lookup(name, &(ed->image.id), &(ed->image.set));
10218 free(name);
10219 }
10220 }
10221
10222 /**
10223 @page edcref
10224 @property
10225 tween
10226 @parameters
10227 [image's filename]
10228 @effect
10229 Name of an image to be used in an animation loop, an image block can
10230 have none, one or multiple tween declarations. Images are displayed in
10231 the order they are listed, during the transition to the state they are
10232 declared in; the "normal" image is the final state.
10233 @endproperty
10234 */
10235 static void
st_collections_group_parts_part_description_image_tween(void)10236 st_collections_group_parts_part_description_image_tween(void)
10237 {
10238 Edje_Part_Description_Image *ed;
10239
10240 check_arg_count(1);
10241
10242 if (current_part->type != EDJE_PART_TYPE_IMAGE)
10243 {
10244 ERR("parse error %s:%i. image attributes in non-IMAGE part.",
10245 file_in, line - 1);
10246 exit(-1);
10247 }
10248
10249 ed = (Edje_Part_Description_Image *)current_desc;
10250
10251 {
10252 char *name;
10253 Edje_Part_Image_Id *iid;
10254
10255 iid = mem_alloc(SZ(Edje_Part_Image_Id));
10256 ed->image.tweens_count++;
10257 ed->image.tweens = realloc(ed->image.tweens,
10258 sizeof (Edje_Part_Image_Id *) * ed->image.tweens_count);
10259 ed->image.tweens[ed->image.tweens_count - 1] = iid;
10260 name = parse_str(0);
10261 data_queue_image_remove(&(iid->id), &(iid->set));
10262 data_queue_image_lookup(name, &(iid->id), &(iid->set));
10263 free(name);
10264 }
10265 }
10266
10267 /**
10268 @page edcref
10269 @property
10270 border
10271 @parameters
10272 [left] [right] [top] [bottom]
10273 @effect
10274 If set, the area (in pixels) of each side of the image will be
10275 displayed as a fixed size border, from the side -> inwards, preventing
10276 the corners from being changed on a resize.
10277
10278 Defaults: 0 0 0 0
10279 @endproperty
10280 */
10281 static void
st_collections_group_parts_part_description_image_border(void)10282 st_collections_group_parts_part_description_image_border(void)
10283 {
10284 Edje_Part_Description_Image *ed;
10285
10286 check_arg_count(4);
10287
10288 if (current_part->type != EDJE_PART_TYPE_IMAGE)
10289 {
10290 ERR("parse error %s:%i. image attributes in non-IMAGE part.",
10291 file_in, line - 1);
10292 exit(-1);
10293 }
10294
10295 ed = (Edje_Part_Description_Image *)current_desc;
10296
10297 ed->image.border.l = parse_int_range(0, 0, 0x7fffffff);
10298 ed->image.border.r = parse_int_range(1, 0, 0x7fffffff);
10299 ed->image.border.t = parse_int_range(2, 0, 0x7fffffff);
10300 ed->image.border.b = parse_int_range(3, 0, 0x7fffffff);
10301 }
10302
10303 /**
10304 @page edcref
10305 @property
10306 middle
10307 @parameters
10308 [mode]
10309 @effect
10310 If border is set, this value tells Edje if the rest of the
10311 image (not covered by the defined border) will be displayed or not
10312 or be assumed to be solid (without alpha). The default is 1/DEFAULT.
10313 Valid values are:
10314 @li 0 or NONE
10315 @li 1 or DEFAULT
10316 @li SOLID
10317 @endproperty
10318 */
10319 static void
st_collections_group_parts_part_description_image_middle(void)10320 st_collections_group_parts_part_description_image_middle(void)
10321 {
10322 Edje_Part_Description_Image *ed;
10323
10324 check_arg_count(1);
10325
10326 if (current_part->type != EDJE_PART_TYPE_IMAGE)
10327 {
10328 ERR("parse error %s:%i. image attributes in non-IMAGE part.",
10329 file_in, line - 1);
10330 exit(-1);
10331 }
10332
10333 ed = (Edje_Part_Description_Image *)current_desc;
10334
10335 ed->image.border.no_fill = parse_enum(0,
10336 "1", 0,
10337 "DEFAULT", 0,
10338 "0", 1,
10339 "NONE", 1,
10340 "SOLID", 2,
10341 NULL);
10342 }
10343
10344 /**
10345 @page edcref
10346 @property
10347 border_scale_by
10348 @parameters
10349 [value]
10350 @effect
10351 If border scaling is enabled then normally the OUTPUT border sizes
10352 (e.g. if 3 pixels on the left edge are set as a border, then normally
10353 at scale 1.0, those 3 columns will always be the exact 3 columns of
10354 output, or at scale 2.0 they will be 6 columns, or 0.33 they will merge
10355 into a single column). This property multiplies the input scale
10356 factor by this multiplier, allowing the creation of "supersampled"
10357 borders to make much higher resolution outputs possible by always using
10358 the highest resolution artwork and then runtime scaling it down.
10359
10360 value can be: 0.0 or bigger (0.0 or 1.0 to turn it off)
10361
10362 Defaults: 0.0
10363 @endproperty
10364 */
10365 static void
st_collections_group_parts_part_description_image_border_scale_by(void)10366 st_collections_group_parts_part_description_image_border_scale_by(void)
10367 {
10368 Edje_Part_Description_Image *ed;
10369
10370 check_arg_count(1);
10371
10372 if (current_part->type != EDJE_PART_TYPE_IMAGE)
10373 {
10374 ERR("parse error %s:%i. image attributes in non-IMAGE part.",
10375 file_in, line - 1);
10376 exit(-1);
10377 }
10378
10379 ed = (Edje_Part_Description_Image *)current_desc;
10380
10381 ed->image.border.scale_by = FROM_DOUBLE(parse_float_range(0, 0.0, 999999999.0));
10382 }
10383
10384 /**
10385 @page edcref
10386 @property
10387 border_scale
10388 @parameters
10389 [0/1]
10390 @effect
10391 If border is set, this value tells Edje if the border should be scaled
10392 by the object/global edje scale factors
10393
10394 Defaults: 0
10395 @endproperty
10396 */
10397 static void
st_collections_group_parts_part_description_image_border_scale(void)10398 st_collections_group_parts_part_description_image_border_scale(void)
10399 {
10400 Edje_Part_Description_Image *ed;
10401
10402 check_arg_count(1);
10403
10404 if (current_part->type != EDJE_PART_TYPE_IMAGE)
10405 {
10406 ERR("parse error %s:%i. image attributes in non-IMAGE part.",
10407 file_in, line - 1);
10408 exit(-1);
10409 }
10410
10411 ed = (Edje_Part_Description_Image *)current_desc;
10412
10413 ed->image.border.scale = parse_bool(0);
10414 }
10415
10416 /**
10417 @page edcref
10418 @property
10419 scale_hint
10420 @parameters
10421 [mode]
10422 @effect
10423 Sets the evas image scale hint letting the engine more effectively save
10424 cached copies of the scaled image if it makes sense.
10425 Valid values are:
10426 @li 0 or NONE
10427 @li DYNAMIC
10428 @li STATIC
10429
10430 Defaults: NONE
10431 @endproperty
10432 */
10433 static void
st_collections_group_parts_part_description_image_scale_hint(void)10434 st_collections_group_parts_part_description_image_scale_hint(void)
10435 {
10436 Edje_Part_Description_Image *ed;
10437
10438 check_arg_count(1);
10439
10440 if (current_part->type != EDJE_PART_TYPE_IMAGE)
10441 {
10442 ERR("parse error %s:%i. image attributes in non-IMAGE part.",
10443 file_in, line - 1);
10444 exit(-1);
10445 }
10446
10447 ed = (Edje_Part_Description_Image *)current_desc;
10448
10449 ed->image.scale_hint = parse_enum(0,
10450 "NONE", EVAS_IMAGE_SCALE_HINT_NONE,
10451 "DYNAMIC", EVAS_IMAGE_SCALE_HINT_DYNAMIC,
10452 "STATIC", EVAS_IMAGE_SCALE_HINT_STATIC,
10453 "0", EVAS_IMAGE_SCALE_HINT_NONE,
10454 NULL);
10455 }
10456
10457 /** @edcsubsection{collections_group_parts_description_fill,
10458 * Group.Parts.Part.Description.Fill} */
10459
10460 /**
10461 @page edcref
10462 @block
10463 fill
10464 @context
10465 part { type: [IMAGE or PROXY];
10466 description {
10467 ..
10468 fill {
10469 type: SCALE;
10470 smooth: 0-1;
10471 origin { }
10472 size { }
10473 }
10474 ..
10475 }
10476 ..
10477 }
10478 @description
10479 The fill method is an optional block that defines the way an IMAGE or
10480 PROXY part is going to be displayed inside its container.
10481 It can be used for tiling (repeating the image) or displaying only
10482 part of an image. See evas_object_image_fill_set() documentation
10483 for more details.
10484 @endblock
10485
10486 @property
10487 smooth
10488 @parameters
10489 [0 or 1]
10490 @effect
10491 The smooth property takes a boolean value to decide if the image will
10492 be smoothed on scaling (1) or not (0).
10493
10494 Defaults: 1
10495 @endproperty
10496 */
10497 static void
st_collections_group_parts_part_description_fill_smooth(void)10498 st_collections_group_parts_part_description_fill_smooth(void)
10499 {
10500 Edje_Part_Description_Spec_Fill *fill;
10501
10502 check_arg_count(1);
10503
10504 switch (current_part->type)
10505 {
10506 case EDJE_PART_TYPE_IMAGE:
10507 {
10508 Edje_Part_Description_Image *ed;
10509
10510 ed = (Edje_Part_Description_Image *)current_desc;
10511
10512 fill = &ed->image.fill;
10513 break;
10514 }
10515
10516 case EDJE_PART_TYPE_PROXY:
10517 {
10518 Edje_Part_Description_Proxy *ed;
10519
10520 ed = (Edje_Part_Description_Proxy *)current_desc;
10521
10522 fill = &ed->proxy.fill;
10523 break;
10524 }
10525
10526 default:
10527 {
10528 ERR("parse error %s:%i. "
10529 "image and proxy attributes in non-IMAGE, non-PROXY `%s` part (%i).",
10530 file_in, line - 1, current_part->name, current_part->type);
10531 exit(-1);
10532 }
10533 }
10534
10535 fill->smooth = parse_bool(0);
10536 }
10537
10538 /**
10539 @page edcref
10540 @property
10541 type
10542 @parameters
10543 [fill type]
10544 @effect
10545 Sets the image fill type. SCALE - image will be scaled accordingly params
10546 value 'relative' and 'offset' from 'origin' and 'size' blocks.
10547 TILE - image will be tiled accordingly params value 'relative' and
10548 'offset' from 'origin' and 'size' blocks. Important: the part parameter
10549 'min' must be setted, it's size of tiled image. If parameter 'max' setted
10550 tiled area will has the size accordingly 'max' values.
10551
10552 Valid values are:
10553 @li SCALE
10554 @li TILE
10555
10556 Defaults: SCALE
10557 @endproperty
10558 */
10559 static void
st_collections_group_parts_part_description_fill_type(void)10560 st_collections_group_parts_part_description_fill_type(void)
10561 {
10562 Edje_Part_Description_Spec_Fill *fill;
10563
10564 check_arg_count(1);
10565
10566 switch (current_part->type)
10567 {
10568 case EDJE_PART_TYPE_IMAGE:
10569 {
10570 Edje_Part_Description_Image *ed;
10571
10572 ed = (Edje_Part_Description_Image *)current_desc;
10573
10574 fill = &ed->image.fill;
10575 break;
10576 }
10577
10578 case EDJE_PART_TYPE_PROXY:
10579 {
10580 Edje_Part_Description_Proxy *ed;
10581
10582 ed = (Edje_Part_Description_Proxy *)current_desc;
10583
10584 fill = &ed->proxy.fill;
10585 break;
10586 }
10587
10588 default:
10589 {
10590 ERR("parse error %s:%i. "
10591 "image and proxy attributes in non-IMAGE, non-PROXY part.",
10592 file_in, line - 1);
10593 exit(-1);
10594 }
10595 }
10596
10597 fill->type = parse_enum(0,
10598 "SCALE", EDJE_FILL_TYPE_SCALE,
10599 "TILE", EDJE_FILL_TYPE_TILE,
10600 NULL);
10601 }
10602
10603 /** @edcsubsection{collections_group_parts_description_fill_origin,
10604 * Group.Parts.Part.Description.Fill.Origin} */
10605
10606 /**
10607 @page edcref
10608 @block
10609 origin
10610 @context
10611 image {
10612 ..
10613 fill {
10614 ..
10615 origin {
10616 relative: 0.0 0.0;
10617 offset: 0 0;
10618 }
10619 ..
10620 }
10621 ..
10622 }
10623 @description
10624 The origin block is used to place the starting point, inside the
10625 displayed element, that will be used to render the tile. By default,
10626 the origin is set at the element's left-up corner.
10627 @endblock
10628
10629 @property
10630 relative
10631 @parameters
10632 [X axis] [Y axis]
10633 @effect
10634 Sets the starting point relatively to displayed element's content.
10635
10636 Defaults: 0.0 0.0
10637 @endproperty
10638 */
10639 static void
st_collections_group_parts_part_description_fill_origin_relative(void)10640 st_collections_group_parts_part_description_fill_origin_relative(void)
10641 {
10642 Edje_Part_Description_Spec_Fill *fill;
10643
10644 check_arg_count(2);
10645
10646 switch (current_part->type)
10647 {
10648 case EDJE_PART_TYPE_IMAGE:
10649 {
10650 Edje_Part_Description_Image *ed;
10651
10652 ed = (Edje_Part_Description_Image *)current_desc;
10653
10654 fill = &ed->image.fill;
10655 break;
10656 }
10657
10658 case EDJE_PART_TYPE_PROXY:
10659 {
10660 Edje_Part_Description_Proxy *ed;
10661
10662 ed = (Edje_Part_Description_Proxy *)current_desc;
10663
10664 fill = &ed->proxy.fill;
10665 break;
10666 }
10667
10668 default:
10669 {
10670 ERR("parse error %s:%i. "
10671 "image and proxy attributes in non-IMAGE, non-PROXY part.",
10672 file_in, line - 1);
10673 exit(-1);
10674 }
10675 }
10676
10677 fill->pos_rel_x = FROM_DOUBLE(parse_float_range(0, -999999999.0, 999999999.0));
10678 fill->pos_rel_y = FROM_DOUBLE(parse_float_range(1, -999999999.0, 999999999.0));
10679 }
10680
10681 /**
10682 @page edcref
10683 @property
10684 offset
10685 @parameters
10686 [X axis] [Y axis]
10687 @effect
10688 Affects the starting point a fixed number of pixels along each axis.
10689
10690 Defaults: 0 0
10691 @endproperty
10692 */
10693 static void
st_collections_group_parts_part_description_fill_origin_offset(void)10694 st_collections_group_parts_part_description_fill_origin_offset(void)
10695 {
10696 Edje_Part_Description_Spec_Fill *fill;
10697
10698 check_arg_count(2);
10699
10700 switch (current_part->type)
10701 {
10702 case EDJE_PART_TYPE_IMAGE:
10703 {
10704 Edje_Part_Description_Image *ed;
10705
10706 ed = (Edje_Part_Description_Image *)current_desc;
10707
10708 fill = &ed->image.fill;
10709 break;
10710 }
10711
10712 case EDJE_PART_TYPE_PROXY:
10713 {
10714 Edje_Part_Description_Proxy *ed;
10715
10716 ed = (Edje_Part_Description_Proxy *)current_desc;
10717
10718 fill = &ed->proxy.fill;
10719 break;
10720 }
10721
10722 default:
10723 {
10724 ERR("parse error %s:%i. "
10725 "image and proxy attributes in non-IMAGE, non-PROXY part.",
10726 file_in, line - 1);
10727 exit(-1);
10728 }
10729 }
10730
10731 fill->pos_abs_x = parse_int(0);
10732 fill->pos_abs_y = parse_int(1);
10733 }
10734
10735 /** @edcsubsection{collections_group_parts_description_fill_size,
10736 * Group.Parts.Part.Description.Fill.Size} */
10737
10738 /**
10739 @page edcref
10740 @block
10741 size
10742 @context
10743 image {
10744 ..
10745 fill {
10746 ..
10747 size {
10748 relative: 1.0 1.0;
10749 offset: -1 -1;
10750 }
10751 ..
10752 }
10753 ..
10754 }
10755 @description
10756 The size block defines the tile size of the content that will be
10757 displayed.
10758 @endblock
10759
10760 @property
10761 relative
10762 @parameters
10763 [width] [height]
10764 @effect
10765 Takes a pair of decimal values that represent the percentual value
10766 of the original size of the element. For example, "0.5 0.5" represents
10767 half the size, while "2.0 2.0" represents the double.
10768
10769 Defaults: 1.0 1.0
10770 @endproperty
10771 */
10772 static void
st_collections_group_parts_part_description_fill_size_relative(void)10773 st_collections_group_parts_part_description_fill_size_relative(void)
10774 {
10775 Edje_Part_Description_Spec_Fill *fill;
10776
10777 check_arg_count(2);
10778
10779 switch (current_part->type)
10780 {
10781 case EDJE_PART_TYPE_IMAGE:
10782 {
10783 Edje_Part_Description_Image *ed;
10784
10785 ed = (Edje_Part_Description_Image *)current_desc;
10786
10787 fill = &ed->image.fill;
10788 break;
10789 }
10790
10791 case EDJE_PART_TYPE_PROXY:
10792 {
10793 Edje_Part_Description_Proxy *ed;
10794
10795 ed = (Edje_Part_Description_Proxy *)current_desc;
10796
10797 fill = &ed->proxy.fill;
10798 break;
10799 }
10800
10801 default:
10802 {
10803 ERR("parse error %s:%i. "
10804 "image and proxy attributes in non-IMAGE, non-PROXY part.",
10805 file_in, line - 1);
10806 exit(-1);
10807 }
10808 }
10809
10810 fill->rel_x = FROM_DOUBLE(parse_float_range(0, 0.0, 999999999.0));
10811 fill->rel_y = FROM_DOUBLE(parse_float_range(1, 0.0, 999999999.0));
10812 }
10813
10814 /**
10815 @page edcref
10816 @property
10817 offset
10818 @parameters
10819 [X axis] [Y axis]
10820 @effect
10821 Affects the size of the tile a fixed number of pixels along each axis.
10822
10823 Defaults: 0 0
10824 @endproperty
10825 */
10826 static void
st_collections_group_parts_part_description_fill_size_offset(void)10827 st_collections_group_parts_part_description_fill_size_offset(void)
10828 {
10829 Edje_Part_Description_Spec_Fill *fill;
10830
10831 check_arg_count(2);
10832
10833 switch (current_part->type)
10834 {
10835 case EDJE_PART_TYPE_IMAGE:
10836 {
10837 Edje_Part_Description_Image *ed;
10838
10839 ed = (Edje_Part_Description_Image *)current_desc;
10840
10841 fill = &ed->image.fill;
10842 break;
10843 }
10844
10845 case EDJE_PART_TYPE_PROXY:
10846 {
10847 Edje_Part_Description_Proxy *ed;
10848
10849 ed = (Edje_Part_Description_Proxy *)current_desc;
10850
10851 fill = &ed->proxy.fill;
10852 break;
10853 }
10854
10855 default:
10856 {
10857 ERR("parse error %s:%i. "
10858 "image and proxy attributes in non-IMAGE, non-PROXY part.",
10859 file_in, line - 1);
10860 exit(-1);
10861 }
10862 }
10863
10864 fill->abs_x = parse_int(0);
10865 fill->abs_y = parse_int(1);
10866 }
10867
10868 /** @edcsubsection{collections_group_parts_description_text,
10869 * Group.Parts.Part.Description.Text} */
10870
10871 /**
10872 @page edcref
10873
10874 @block
10875 text
10876 @context
10877 part {
10878 description {
10879 ..
10880 text {
10881 text: "some string of text to display";
10882 domain: "domain_name";
10883 font: "font_name";
10884 size: SIZE;
10885 text_class: "class_name";
10886 fit: horizontal vertical;
10887 min: horizontal vertical;
10888 max: horizontal vertical;
10889 align: X-axis Y-axis;
10890 source: "part_name";
10891 text_source: "text_part_name";
10892 ellipsis: -1.0 (since 1.8), 0.0-1.0;
10893 style: "stylename";
10894 }
10895 ..
10896 }
10897 }
10898 @description
10899 @endblock
10900
10901 @property
10902 text
10903 @parameters
10904 [a string of text, or nothing]
10905 @effect
10906 Sets the default content of a text part, normally the application is
10907 the one changing its value.
10908 @endproperty
10909 */
10910 static void
st_collections_group_parts_part_description_text_text(void)10911 st_collections_group_parts_part_description_text_text(void)
10912 {
10913 Edje_Part_Description_Text *ed;
10914 char *str = NULL;
10915 int i;
10916
10917 if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
10918 (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
10919 {
10920 ERR("parse error %s:%i. text attributes in non-TEXT part.",
10921 file_in, line - 1);
10922 exit(-1);
10923 }
10924
10925 ed = (Edje_Part_Description_Text *)current_desc;
10926
10927 for (i = 0;; i++)
10928 {
10929 char *s;
10930
10931 if (!is_param(i)) break;
10932 s = parse_str(i);
10933 if (!str) str = s;
10934 else
10935 {
10936 str = realloc(str, strlen(str) + strlen(s) + 1);
10937 strcat(str, s);
10938 free(s);
10939 }
10940 }
10941 ed->text.text.str = str;
10942 }
10943
10944 /**
10945 @page edcref
10946
10947 @property
10948 domain
10949 @parameters
10950 [domain name]
10951 @effect
10952 This is the domain name of the .mo file which has to be checked
10953 for translation.
10954 @endproperty
10955 */
10956 static void
st_collections_group_parts_part_description_text_domain(void)10957 st_collections_group_parts_part_description_text_domain(void)
10958 {
10959 Edje_Part_Description_Text *ed;
10960
10961 if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
10962 (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
10963 {
10964 ERR("parse error %s:%i. text attributes in non-TEXT part.",
10965 file_in, line - 1);
10966 exit(-1);
10967 }
10968
10969 ed = (Edje_Part_Description_Text *)current_desc;
10970
10971 ed->text.domain = parse_str(0);
10972 }
10973
10974 /**
10975 @page edcref
10976
10977 @property
10978 text_class
10979 @parameters
10980 [text class name]
10981 @effect
10982 Similar to color_class, this is the name used by the application
10983 to alter the font family and size at runtime.
10984 @endproperty
10985 */
10986 static void
st_collections_group_parts_part_description_text_text_class(void)10987 st_collections_group_parts_part_description_text_text_class(void)
10988 {
10989 Edje_Part_Description_Text *ed;
10990
10991 check_arg_count(1);
10992
10993 if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
10994 (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
10995 {
10996 ERR("parse error %s:%i. text attributes in non-TEXT part.",
10997 file_in, line - 1);
10998 exit(-1);
10999 }
11000
11001 ed = (Edje_Part_Description_Text *)current_desc;
11002
11003 ed->text.text_class = parse_str(0);
11004 }
11005
11006 /**
11007 @page edcref
11008
11009 @property
11010 font
11011 @parameters
11012 [font alias]
11013 @effect
11014 This sets the font family to one of the aliases set up in the "fonts"
11015 block. Can be overridden by the application.
11016 @endproperty
11017 */
11018 static void
st_collections_group_parts_part_description_text_font(void)11019 st_collections_group_parts_part_description_text_font(void)
11020 {
11021 Edje_Part_Description_Text *ed;
11022
11023 check_arg_count(1);
11024
11025 if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
11026 (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
11027 {
11028 ERR("parse error %s:%i. text attributes in non-TEXT part.",
11029 file_in, line - 1);
11030 exit(-1);
11031 }
11032
11033 ed = (Edje_Part_Description_Text *)current_desc;
11034
11035 ed->text.font.str = parse_str(0);
11036 }
11037
11038 /**
11039 @page edcref
11040
11041 @property
11042 style
11043 @parameters
11044 [the style name]
11045 @effect
11046 Causes the part to use the default style and tags defined in the
11047 "style" block with the specified name.
11048 @endproperty
11049 */
11050 static void
st_collections_group_parts_part_description_text_style(void)11051 st_collections_group_parts_part_description_text_style(void)
11052 {
11053 Edje_Part_Description_Text *ed;
11054
11055 check_arg_count(1);
11056
11057 if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
11058 (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
11059 {
11060 ERR("parse error %s:%i. text attributes in non-TEXT part.",
11061 file_in, line - 1);
11062 exit(-1);
11063 }
11064
11065 ed = (Edje_Part_Description_Text *)current_desc;
11066
11067 ed->text.style.str = parse_str(0);
11068 }
11069
11070 /**
11071 @page edcref
11072
11073 @property
11074 repch
11075 @parameters
11076 [the replacement character string]
11077 @effect
11078 If this is a textblock and is in PASSWORD mode this string is used
11079 to replace every character to hide the details of the entry. Normally
11080 you would use a "*", but you can use anything you like.
11081 @endproperty
11082 */
11083 static void
st_collections_group_parts_part_description_text_repch(void)11084 st_collections_group_parts_part_description_text_repch(void)
11085 {
11086 Edje_Part_Description_Text *ed;
11087
11088 check_arg_count(1);
11089
11090 if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
11091 (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
11092 {
11093 ERR("parse error %s:%i. text attributes in non-TEXT part.",
11094 file_in, line - 1);
11095 exit(-1);
11096 }
11097
11098 ed = (Edje_Part_Description_Text *)current_desc;
11099
11100 ed->text.repch.str = parse_str(0);
11101 }
11102
11103 /**
11104 @page edcref
11105
11106 @property
11107 size
11108 @parameters
11109 [font size in points (pt) 0 - 255]
11110 @effect
11111 Sets the default font size for the text part. Can be overridden by the
11112 application.
11113
11114 Defaults: 0
11115 @endproperty
11116 */
11117 static void
st_collections_group_parts_part_description_text_size(void)11118 st_collections_group_parts_part_description_text_size(void)
11119 {
11120 Edje_Part_Description_Text *ed;
11121
11122 check_arg_count(1);
11123
11124 if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
11125 (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
11126 {
11127 ERR("parse error %s:%i. text attributes in non-TEXT part.",
11128 file_in, line - 1);
11129 exit(-1);
11130 }
11131
11132 ed = (Edje_Part_Description_Text *)current_desc;
11133
11134 ed->text.size = parse_int_range(0, 0, 255);
11135 }
11136
11137 /**
11138 @page edcref
11139
11140 @property
11141 size_range
11142 @parameters
11143 [font min size in points (pt) 0 - 255] [font max size in points (pt) 0 - 255]
11144 @effect
11145 Sets the allowed font size for the text part. Setting min and max to 0
11146 means we won't restrict the sizing.
11147
11148 Defaults: 0 0
11149 @since 1.1
11150 @endproperty
11151 */
11152 static void
st_collections_group_parts_part_description_text_size_range(void)11153 st_collections_group_parts_part_description_text_size_range(void)
11154 {
11155 Edje_Part_Description_Text *ed;
11156
11157 check_arg_count(2);
11158
11159 if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
11160 (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
11161 {
11162 ERR("parse error %s:%i. text attributes in non-TEXT part.",
11163 file_in, line - 1);
11164 exit(-1);
11165 }
11166
11167 ed = (Edje_Part_Description_Text *)current_desc;
11168
11169 ed->text.size_range_min = parse_int_range(0, 0, 255);
11170 ed->text.size_range_max = parse_int_range(1, 0, 255);
11171 if (ed->text.size_range_min > ed->text.size_range_max)
11172 {
11173 ERR("parse error %s:%i. min size is bigger than max size.",
11174 file_in, line - 1);
11175 exit(-1);
11176 }
11177 }
11178
11179 /**
11180 @page edcref
11181
11182 @property
11183 fit
11184 @parameters
11185 [horizontal] [vertical]
11186 @effect
11187 When any of the parameters is set to 1 edje will resize the text for it
11188 to fit in it's container. Both are disabled by default.
11189
11190 Defaults: 0 0
11191 @endproperty
11192 */
11193 static void
st_collections_group_parts_part_description_text_fit(void)11194 st_collections_group_parts_part_description_text_fit(void)
11195 {
11196 Edje_Part_Description_Text *ed;
11197
11198 check_arg_count(2);
11199
11200 if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
11201 (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
11202 {
11203 ERR("parse error %s:%i. text attributes in non-TEXT part.",
11204 file_in, line - 1);
11205 exit(-1);
11206 }
11207
11208 ed = (Edje_Part_Description_Text *)current_desc;
11209
11210 ed->text.fit_x = parse_bool(0);
11211 ed->text.fit_y = parse_bool(1);
11212 }
11213
11214
11215 /**
11216 @page edcref
11217
11218 @property
11219 fit_step
11220 @parameters
11221 [font step size in points (pt)]
11222 @effect
11223 Sets the font step size for the text part. when fitting text
11224
11225 Defaults: 1
11226 @since 1.24.0
11227 @endproperty
11228 */
11229 static void
st_collections_group_parts_part_description_text_fit_step(void)11230 st_collections_group_parts_part_description_text_fit_step(void)
11231 {
11232 Edje_Part_Description_Text *ed;
11233
11234 check_arg_count(1);
11235
11236 if (current_part->type != EDJE_PART_TYPE_TEXTBLOCK)
11237 {
11238 ERR("parse error %s:%i. text attributes in non-TEXTBLOCK part.",
11239 file_in, line - 1);
11240 exit(-1);
11241 }
11242
11243 ed = (Edje_Part_Description_Text *)current_desc;
11244
11245 ed->text.fit_step = parse_int(0);
11246
11247 if (ed->text.fit_step < 1)
11248 {
11249 ERR("parse error %s:%i. fit step less than 1.",
11250 file_in, line - 1);
11251 exit(-1);
11252 }
11253 }
11254
11255 /**
11256 @page edcref
11257
11258 @property
11259 fit
11260 @parameters
11261 [Array of font sizes in points]
11262 @effect
11263 Sets the allowed font sizes array for the text part.
11264 @since 1.24.0
11265 @endproperty
11266 */
11267 static void
st_collections_group_parts_part_description_text_fit_size_array(void)11268 st_collections_group_parts_part_description_text_fit_size_array(void)
11269 {
11270 int n, argc;
11271 Edje_Part_Description_Text *ed;
11272
11273 if (current_part->type != EDJE_PART_TYPE_TEXTBLOCK)
11274 {
11275 ERR("parse error %s:%i. text attributes in non-TEXTBLOCK part.",
11276 file_in, line - 1);
11277 exit(-1);
11278 }
11279
11280 ed = (Edje_Part_Description_Text *)current_desc;
11281 check_min_arg_count(1);
11282
11283 for (n = 0, argc = get_arg_count(); n < argc; n++)
11284 {
11285 unsigned int *value = malloc(sizeof(unsigned int));
11286 if (value) *value = (unsigned int) parse_int(n);
11287 ed->text.fit_size_array = eina_list_append(ed->text.fit_size_array, value);
11288 }
11289 }
11290
11291 /**
11292 @page edcref
11293
11294 @property
11295 min
11296 @parameters
11297 [horizontal] [vertical]
11298 @effect
11299 When any of the parameters is enabled (1) it forces the minimum size of
11300 the container to be equal to the minimum size of the text.
11301
11302 Defaults: 0 0
11303 @endproperty
11304 */
11305 static void
st_collections_group_parts_part_description_text_min(void)11306 st_collections_group_parts_part_description_text_min(void)
11307 {
11308 Edje_Part_Description_Text *ed;
11309
11310 check_arg_count(2);
11311
11312 if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
11313 (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
11314 {
11315 ERR("parse error %s:%i. text attributes in non-TEXT part.",
11316 file_in, line - 1);
11317 exit(-1);
11318 }
11319
11320 ed = (Edje_Part_Description_Text *)current_desc;
11321
11322 ed->text.min_x = parse_bool(0);
11323 ed->text.min_y = parse_bool(1);
11324
11325 if (current_part->type == EDJE_PART_TYPE_TEXTBLOCK)
11326 edje_file->has_textblock_min_max = EINA_TRUE;
11327 }
11328
11329 /**
11330 @page edcref
11331
11332 @property
11333 max
11334 @parameters
11335 [horizontal] [vertical]
11336 @effect
11337 When any of the parameters is enabled (1) it forces the maximum size of
11338 the container to be equal to the maximum size of the text.
11339
11340 Defaults: 0 0
11341 @endproperty
11342 */
11343 static void
st_collections_group_parts_part_description_text_max(void)11344 st_collections_group_parts_part_description_text_max(void)
11345 {
11346 Edje_Part_Description_Text *ed;
11347
11348 check_arg_count(2);
11349
11350 if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
11351 (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
11352 {
11353 ERR("parse error %s:%i. text attributes in non-TEXT part.",
11354 file_in, line - 1);
11355 exit(-1);
11356 }
11357
11358 ed = (Edje_Part_Description_Text *)current_desc;
11359
11360 ed->text.max_x = parse_bool(0);
11361 ed->text.max_y = parse_bool(1);
11362
11363 if (current_part->type == EDJE_PART_TYPE_TEXTBLOCK)
11364 edje_file->has_textblock_min_max = EINA_TRUE;
11365 }
11366
11367 /**
11368 @page edcref
11369
11370 @property
11371 align
11372 @parameters
11373 [horizontal] [vertical]
11374 @effect
11375 Change the alignment of the text [0.0(left) - 1.0(right)].
11376 You can set horizontal alignment to -1.0 to use bidirectional based alignment(
11377 0.0 for LTR content or 1.0 for RTL)
11378
11379 Defaults: 0.5 0.5
11380 @endproperty
11381 */
11382 static void
st_collections_group_parts_part_description_text_align(void)11383 st_collections_group_parts_part_description_text_align(void)
11384 {
11385 Edje_Part_Description_Text *ed;
11386
11387 check_arg_count(2);
11388
11389 if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
11390 (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
11391 {
11392 ERR("parse error %s:%i. text attributes in non-TEXT part.",
11393 file_in, line - 1);
11394 exit(-1);
11395 }
11396
11397 ed = (Edje_Part_Description_Text *)current_desc;
11398
11399 ed->text.align.x = FROM_DOUBLE(parse_float_range(0, -1.0, 1.0));
11400 ed->text.align.y = FROM_DOUBLE(parse_float_range(1, 0.0, 1.0));
11401 }
11402
11403 /**
11404 @page edcref
11405
11406 @property
11407 source
11408 @parameters
11409 [another TEXT part's name]
11410 @effect
11411 Causes the part to use the text properties (like font and size) of
11412 another part and update them as they change.
11413 @endproperty
11414 */
11415 static void
st_collections_group_parts_part_description_text_source(void)11416 st_collections_group_parts_part_description_text_source(void)
11417 {
11418 Edje_Part_Collection *pc;
11419 Edje_Part_Description_Text *ed;
11420
11421 check_arg_count(1);
11422
11423 pc = eina_list_data_get(eina_list_last(edje_collections));
11424
11425 if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
11426 (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
11427 {
11428 ERR("parse error %s:%i. text attributes in non-TEXT part.",
11429 file_in, line - 1);
11430 exit(-1);
11431 }
11432
11433 ed = (Edje_Part_Description_Text *)current_desc;
11434
11435 {
11436 char *name;
11437
11438 name = parse_str(0);
11439 data_queue_part_nest_lookup(pc, name, &(ed->text.id_source), &ed->text.id_source_part);
11440 free(name);
11441 }
11442 }
11443
11444 /**
11445 @page edcref
11446
11447 @property
11448 text_source
11449 @parameters
11450 [another TEXT part's name]
11451 @effect
11452 Causes the part to display the text content of another part and update
11453 them as they change.
11454 @endproperty
11455 */
11456 static void
st_collections_group_parts_part_description_text_text_source(void)11457 st_collections_group_parts_part_description_text_text_source(void)
11458 {
11459 Edje_Part_Collection *pc;
11460 Edje_Part_Description_Text *ed;
11461
11462 check_arg_count(1);
11463
11464 pc = eina_list_data_get(eina_list_last(edje_collections));
11465
11466 if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
11467 (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
11468 {
11469 ERR("parse error %s:%i. text attributes in non-TEXT part.",
11470 file_in, line - 1);
11471 exit(-1);
11472 }
11473
11474 ed = (Edje_Part_Description_Text *)current_desc;
11475
11476 {
11477 char *name;
11478
11479 name = parse_str(0);
11480 data_queue_part_nest_lookup(pc, name, &(ed->text.id_text_source), &ed->text.id_text_source_part);
11481 free(name);
11482 }
11483 }
11484
11485 /**
11486 @page edcref
11487
11488 @property
11489 ellipsis
11490 @parameters
11491 [point of balance]
11492 @effect
11493 Used to balance the text in a relative point from 0.0 to 1.0, this
11494 point is the last section of the string to be cut out in case of a
11495 resize that is smaller than the text itself.
11496 Setting -1.0 will disable text cutting.
11497
11498 Defaults: 0.0
11499 @endproperty
11500 */
11501 static void
st_collections_group_parts_part_description_text_ellipsis(void)11502 st_collections_group_parts_part_description_text_ellipsis(void)
11503 {
11504 Edje_Part_Description_Text *ed;
11505
11506 check_arg_count(1);
11507
11508 if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
11509 (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
11510 {
11511 ERR("parse error %s:%i. text attributes in non-TEXT part.",
11512 file_in, line - 1);
11513 exit(-1);
11514 }
11515
11516 ed = (Edje_Part_Description_Text *)current_desc;
11517
11518 ed->text.ellipsis = parse_float_range(0, -1.0, 1.0);
11519 }
11520
11521 /** @edcsubsection{collections_group_parts_description_box,
11522 * Group.Parts.Part.Description.Box} */
11523
11524 /**
11525 @page edcref
11526
11527 @block
11528 box
11529 @context
11530 part {
11531 description {
11532 ..
11533 box {
11534 layout: "vertical";
11535 padding: 0 2;
11536 align: 0.5 0.5;
11537 min: 0 0;
11538 }
11539 ..
11540 }
11541 }
11542 @description
11543 A box block can contain other objects and display them in different
11544 layouts, any of the predefined set, or a custom one, set by the
11545 application.
11546 @endblock
11547
11548 @property
11549 layout
11550 @parameters
11551 [primary layout] (fallback layout)
11552 @effect
11553 Sets the layout for the box:
11554 @li horizontal
11555 @li vertical
11556 @li horizontal_homogeneous
11557 @li vertical_homogeneous
11558 @li horizontal_max (homogeneous to the max sized child)
11559 @li vertical_max
11560 @li horizontal_flow
11561 @li vertical_flow
11562 @li stack
11563 @li some_other_custom_layout_set_by_the_application
11564 You could set a custom layout as fallback, it makes very
11565 very little sense though, and if that one fails, it will
11566 default to horizontal.
11567
11568 Defaults: "horizontal"
11569 @endproperty
11570 */
11571 static void
st_collections_group_parts_part_description_box_layout(void)11572 st_collections_group_parts_part_description_box_layout(void)
11573 {
11574 Edje_Part_Description_Box *ed;
11575
11576 check_min_arg_count(1);
11577
11578 if (current_part->type != EDJE_PART_TYPE_BOX)
11579 {
11580 ERR("parse error %s:%i. box attributes in non-BOX part.",
11581 file_in, line - 1);
11582 exit(-1);
11583 }
11584
11585 ed = (Edje_Part_Description_Box *)current_desc;
11586
11587 ed->box.layout = parse_str(0);
11588 if (is_param(1))
11589 ed->box.alt_layout = parse_str(1);
11590 }
11591
11592 /**
11593 @page edcref
11594 @property
11595 align
11596 @parameters
11597 [horizontal] [vertical]
11598 @effect
11599 Change the position of the point of balance inside the box [-1.0 - 1.0].
11600
11601 Defaults: 0.5 0.5
11602 @endproperty
11603 */
11604 static void
st_collections_group_parts_part_description_box_align(void)11605 st_collections_group_parts_part_description_box_align(void)
11606 {
11607 Edje_Part_Description_Box *ed;
11608
11609 check_arg_count(2);
11610
11611 if (current_part->type != EDJE_PART_TYPE_BOX)
11612 {
11613 ERR("parse error %s:%i. box attributes in non-BOX part.",
11614 file_in, line - 1);
11615 exit(-1);
11616 }
11617
11618 ed = (Edje_Part_Description_Box *)current_desc;
11619
11620 ed->box.align.x = FROM_DOUBLE(parse_float_range(0, -1.0, 1.0));
11621 ed->box.align.y = FROM_DOUBLE(parse_float_range(1, -1.0, 1.0));
11622 }
11623
11624 /**
11625 @page edcref
11626 @property
11627 padding
11628 @parameters
11629 [horizontal] [vertical]
11630 @effect
11631 Sets the space between box items in pixels.
11632
11633 Defaults: 0 0
11634 @endproperty
11635 */
11636 static void
st_collections_group_parts_part_description_box_padding(void)11637 st_collections_group_parts_part_description_box_padding(void)
11638 {
11639 Edje_Part_Description_Box *ed;
11640
11641 check_arg_count(2);
11642
11643 if (current_part->type != EDJE_PART_TYPE_BOX)
11644 {
11645 ERR("parse error %s:%i. box attributes in non-BOX part.",
11646 file_in, line - 1);
11647 exit(-1);
11648 }
11649
11650 ed = (Edje_Part_Description_Box *)current_desc;
11651
11652 ed->box.padding.x = parse_int_range(0, 0, 0x7fffffff);
11653 ed->box.padding.y = parse_int_range(1, 0, 0x7fffffff);
11654 }
11655
11656 /**
11657 @page edcref
11658 @property
11659 min
11660 @parameters
11661 [horizontal] [vertical]
11662 @effect
11663 When any of the parameters is enabled (1) it forces the minimum size of
11664 the box to be equal to the minimum size of the items.
11665
11666 Defaults: 0 0
11667 @endproperty
11668 */
11669 static void
st_collections_group_parts_part_description_box_min(void)11670 st_collections_group_parts_part_description_box_min(void)
11671 {
11672 Edje_Part_Description_Box *ed;
11673
11674 check_arg_count(2);
11675
11676 if (current_part->type != EDJE_PART_TYPE_BOX)
11677 {
11678 ERR("parse error %s:%i. box attributes in non-BOX part.",
11679 file_in, line - 1);
11680 exit(-1);
11681 }
11682
11683 ed = (Edje_Part_Description_Box *)current_desc;
11684
11685 ed->box.min.h = parse_bool(0);
11686 ed->box.min.v = parse_bool(1);
11687 }
11688
11689 /** @edcsubsection{collections_group_parts_description_table,
11690 * Group.Parts.Part.Description.Table} */
11691
11692 /**
11693 @page edcref
11694
11695 @block
11696 table
11697 @context
11698 part {
11699 description {
11700 ..
11701 table {
11702 homogeneous: TABLE;
11703 padding: 0 2;
11704 align: 0.5 0.5;
11705 min: 0 0;
11706 }
11707 ..
11708 }
11709 }
11710 @description
11711 A table block can contain other objects packed in multiple columns
11712 and rows, and each item can span across more than one column and/or
11713 row.
11714 @endblock
11715
11716 @property
11717 homogeneous
11718 @parameters
11719 [homogeneous mode]
11720 @effect
11721 Sets the homogeneous mode for the table:
11722 @li NONE
11723 @li TABLE
11724 @li ITEM
11725
11726 Defaults: NONE
11727 @endproperty
11728 */
11729 static void
st_collections_group_parts_part_description_table_homogeneous(void)11730 st_collections_group_parts_part_description_table_homogeneous(void)
11731 {
11732 Edje_Part_Description_Table *ed;
11733
11734 check_min_arg_count(1);
11735
11736 if (current_part->type != EDJE_PART_TYPE_TABLE)
11737 {
11738 ERR("parse error %s:%i. table attributes in non-TABLE part.",
11739 file_in, line - 1);
11740 exit(-1);
11741 }
11742
11743 ed = (Edje_Part_Description_Table *)current_desc;
11744
11745 ed->table.homogeneous = parse_enum(0,
11746 "NONE", EDJE_OBJECT_TABLE_HOMOGENEOUS_NONE,
11747 "TABLE", EDJE_OBJECT_TABLE_HOMOGENEOUS_TABLE,
11748 "ITEM", EDJE_OBJECT_TABLE_HOMOGENEOUS_ITEM,
11749 NULL);
11750 }
11751
11752 /**
11753 @page edcref
11754 @property
11755 align
11756 @parameters
11757 [horizontal] [vertical]
11758 @effect
11759 Change the position of the point of balance inside the table [-1.0 - 1.0].
11760
11761 Defaults: 0.5 0.5
11762 @endproperty
11763 */
11764 static void
st_collections_group_parts_part_description_table_align(void)11765 st_collections_group_parts_part_description_table_align(void)
11766 {
11767 Edje_Part_Description_Table *ed;
11768
11769 check_arg_count(2);
11770
11771 if (current_part->type != EDJE_PART_TYPE_TABLE)
11772 {
11773 ERR("parse error %s:%i. table attributes in non-TABLE part.",
11774 file_in, line - 1);
11775 exit(-1);
11776 }
11777
11778 ed = (Edje_Part_Description_Table *)current_desc;
11779
11780 ed->table.align.x = FROM_DOUBLE(parse_float_range(0, -1.0, 1.0));
11781 ed->table.align.y = FROM_DOUBLE(parse_float_range(1, -1.0, 1.0));
11782 }
11783
11784 /**
11785 @page edcref
11786 @property
11787 padding
11788 @parameters
11789 [horizontal] [vertical]
11790 @effect
11791 Sets the space between table cells in pixels.
11792
11793 Defaults: 0 0
11794 @endproperty
11795 */
11796 static void
st_collections_group_parts_part_description_table_padding(void)11797 st_collections_group_parts_part_description_table_padding(void)
11798 {
11799 Edje_Part_Description_Table *ed;
11800
11801 check_arg_count(2);
11802
11803 if (current_part->type != EDJE_PART_TYPE_TABLE)
11804 {
11805 ERR("parse error %s:%i. table attributes in non-TABLE part.",
11806 file_in, line - 1);
11807 exit(-1);
11808 }
11809
11810 ed = (Edje_Part_Description_Table *)current_desc;
11811
11812 ed->table.padding.x = parse_int_range(0, 0, 0x7fffffff);
11813 ed->table.padding.y = parse_int_range(1, 0, 0x7fffffff);
11814 }
11815
11816 /**
11817 @page edcref
11818 @property
11819 min
11820 @parameters
11821 [horizontal] [vertical]
11822 @effect
11823 When any of the parameters is enabled (1) it forces the minimum size of
11824 the table to be equal to the minimum size of the items.
11825
11826 Defaults: 0 0
11827 @endproperty
11828 */
11829 static void
st_collections_group_parts_part_description_table_min(void)11830 st_collections_group_parts_part_description_table_min(void)
11831 {
11832 Edje_Part_Description_Table *ed;
11833
11834 check_arg_count(2);
11835
11836 if (current_part->type != EDJE_PART_TYPE_TABLE)
11837 {
11838 ERR("parse error %s:%i. table attributes in non-TABLE part.",
11839 file_in, line - 1);
11840 exit(-1);
11841 }
11842
11843 ed = (Edje_Part_Description_Table *)current_desc;
11844
11845 ed->table.min.h = parse_bool(0);
11846 ed->table.min.v = parse_bool(1);
11847 }
11848
11849 /**
11850 @edcsubsection{collections_group_parts_description_proxy,
11851 Group.Parts.Part.Description.Proxy}
11852 */
11853
11854 /**
11855 @page edcref
11856
11857 @block
11858 proxy
11859 @context
11860 part { type: PROXY;
11861 description {
11862 ..
11863 proxy {
11864 source_clip: 1;
11865 source_visible: 1;
11866 }
11867 ..
11868 }
11869 }
11870 @description
11871 State flags used for proxy objects.
11872 @endblock
11873
11874 @property
11875 source_clip
11876 @parameters
11877 [0 or 1]
11878 @effect
11879 Sets the 'source_clip' property on this PROXY object. True by default,
11880 this means the proxy will be clipped by its source clipper. False
11881 means the source clipper is ignored when rendering the proxy.
11882
11883 Defaults: 1
11884 @endproperty
11885
11886 @property
11887 source_visible
11888 @parameters
11889 [0 or 1]
11890 @effect
11891 Sets the 'source_visible' property on this PROXY object. True by
11892 default, meaning both the proxy and its source object will be visible.
11893 If false, the source object will not be visible. False is equivalent
11894 to setting the 'no_render' flag on the source object itself.
11895
11896 Defaults: 1
11897 @endproperty
11898 */
11899 static void
st_collections_group_parts_part_description_proxy_source_clip(void)11900 st_collections_group_parts_part_description_proxy_source_clip(void)
11901 {
11902 Edje_Part_Description_Proxy *ed;
11903
11904 check_arg_count(1);
11905
11906 if (current_part->type != EDJE_PART_TYPE_PROXY)
11907 {
11908 ERR("parse error %s:%i. proxy attributes in non-PROXY part.",
11909 file_in, line - 1);
11910 exit(-1);
11911 }
11912
11913 ed = (Edje_Part_Description_Proxy *)current_desc;
11914 ed->proxy.source_clip = parse_bool(0);
11915 }
11916
11917 static void
st_collections_group_parts_part_description_proxy_source_visible(void)11918 st_collections_group_parts_part_description_proxy_source_visible(void)
11919 {
11920 Edje_Part_Description_Proxy *ed;
11921
11922 check_arg_count(1);
11923
11924 if (current_part->type != EDJE_PART_TYPE_PROXY)
11925 {
11926 ERR("parse error %s:%i. proxy attributes in non-PROXY part.",
11927 file_in, line - 1);
11928 exit(-1);
11929 }
11930
11931 ed = (Edje_Part_Description_Proxy *)current_desc;
11932 ed->proxy.source_visible = parse_bool(0);
11933 }
11934
11935
11936 /** @edcsubsection{collections_group_parts_description_physics,
11937 * Group.Parts.Part.Description.Physics} */
11938
11939 /**
11940 @page edcref
11941 @block
11942 physics
11943 @context
11944 description {
11945 ..
11946 physics {
11947 ignore_part_pos: 1;
11948 mass: 5.31;
11949 friction: 0.5;
11950 restitution: 0.82;
11951 damping: 0.4 0.24;
11952 sleep: 32 18.9;
11953 material: IRON;
11954 density: 3.2;
11955 hardness: 0.42;
11956 light_on: 1;
11957 z: -15;
11958 depth: 30;
11959 movement_freedom { }
11960 faces { }
11961 }
11962 ..
11963 }
11964
11965 @description
11966 Physics block should be used to configure the body associated to the
11967 part. The part's property physics_body needs to be set to something
11968 different from NONE, otherwise the properties inside physics block
11969 won't have any effect.
11970 It's possible to set body's material, mass, restitution, friction,
11971 allow / disallow movement in specific axes, etc.
11972 @endblock
11973
11974 @property
11975 mass
11976 @parameters
11977 [body's mass in kilograms]
11978 @effect
11979 Double value used to set inertial mass of the body.
11980 It is a quantitative measure of an object's resistance to the change of
11981 its speed. If mass is set to 0 the body will have infinite mass,
11982 so it will be immovable, static.
11983 @since 1.8
11984 @endproperty
11985 */
11986
11987 #ifdef HAVE_EPHYSICS
11988 static void
st_collections_group_parts_part_description_physics_mass(void)11989 st_collections_group_parts_part_description_physics_mass(void)
11990 {
11991 check_arg_count(1);
11992
11993 current_desc->physics.mass = parse_float(0);
11994 }
11995
11996 #endif
11997
11998 /**
11999 @page edcref
12000 @property
12001 restitution
12002 @parameters
12003 [body's restitution]
12004 @effect
12005 The coefficient of restitution is proporcion between speed after and
12006 before a collision. It's 0 by default.
12007
12008 COR = relative speed after collision / relative speed before collision
12009
12010 @li elastically collide for COR == 1;
12011 @li inelastically collide for 0 < COR < 1;
12012 @li completelly stop (no bouncing at all) for COR == 0.
12013
12014 @since 1.8
12015 @endproperty
12016 */
12017
12018 #ifdef HAVE_EPHYSICS
12019 static void
st_collections_group_parts_part_description_physics_restitution(void)12020 st_collections_group_parts_part_description_physics_restitution(void)
12021 {
12022 check_arg_count(1);
12023
12024 current_desc->physics.restitution = parse_float(0);
12025 }
12026
12027 #endif
12028
12029 /**
12030 @page edcref
12031 @property
12032 friction
12033 @parameters
12034 [body's friction]
12035 @effect
12036 Friction is used to make objects slide along each ot
12037
12038 The friction parameter is usually set between 0 and 1, but can be any
12039 non-negative value. A friction value of 0 turns off friction and a value
12040 of 1 makes the friction strong.
12041
12042 By default friction value is 0.5 and simulation resulsts will be better
12043 when friction in non-zero.
12044
12045 @since 1.8
12046 @endproperty
12047 */
12048
12049 #ifdef HAVE_EPHYSICS
12050 static void
st_collections_group_parts_part_description_physics_friction(void)12051 st_collections_group_parts_part_description_physics_friction(void)
12052 {
12053 check_arg_count(1);
12054
12055 current_desc->physics.friction = parse_float(0);
12056 }
12057
12058 #endif
12059
12060 /**
12061 @page edcref
12062 @property
12063 ignore_part_pos
12064 @parameters
12065 [1 or 0]
12066 @effect
12067 If enabled, the body won't be positioned following rel1/rel2.
12068 It will keep its position updated only by physics calculations.
12069 If disabled, when the state is set, the body will be moved to
12070 the position described by the blocks rel1/rel2.
12071 Default is 1 (enabled).
12072 @since 1.8
12073 @endproperty
12074 */
12075 #ifdef HAVE_EPHYSICS
12076 static void
st_collections_group_parts_part_description_physics_ignore_part_pos(void)12077 st_collections_group_parts_part_description_physics_ignore_part_pos(void)
12078 {
12079 check_arg_count(1);
12080
12081 current_desc->physics.ignore_part_pos = parse_bool(0);
12082 }
12083
12084 #endif
12085
12086 /**
12087 @page edcref
12088 @property
12089 damping
12090 @parameters
12091 [linear damping] [angular damping]
12092 @effect
12093 Damping(linear and angular) values are applied to body's linear and
12094 angular velocity.
12095 By applying a bodies damping factor the user will face a velocity
12096 reduction, with a force applied to it - "like" air resistance.
12097 The force is applied to slow it down.
12098 Values should be between 0.0 and 1.0, and are set to 0 by default.
12099 @since 1.8
12100 @endproperty
12101 */
12102 #ifdef HAVE_EPHYSICS
12103 static void
st_collections_group_parts_part_description_physics_damping(void)12104 st_collections_group_parts_part_description_physics_damping(void)
12105 {
12106 check_arg_count(2);
12107
12108 current_desc->physics.damping.linear = parse_float_range(0, 0, 1.0);
12109 current_desc->physics.damping.angular = parse_float_range(1, 0, 1.0);
12110 }
12111
12112 #endif
12113
12114 /**
12115 @page edcref
12116 @property
12117 sleep
12118 @parameters
12119 [linear sleeping threshold] [angular sleeping threshold]
12120 @effect
12121 Sleeping threshold factors are used to determine whenever a rigid body
12122 is supposed to increment the sleeping time. Linear threshold is
12123 measured in Evas coordinates per second and angular threshold is
12124 measured in degrees per second.
12125 After every tick the sleeping time is incremented, if the body's
12126 linear and angular speed is less than the respective thresholds
12127 the sleeping time is incremented by the current time step (delta time).
12128 Reaching the max sleeping time the body is marked to sleep, that means
12129 the rigid body is to be deactivated.
12130 By default linear threshold is 24 pixels / second and angular is
12131 57.29 degrees / sec (1 rad/sec).
12132 @since 1.8
12133 @endproperty
12134 */
12135 #ifdef HAVE_EPHYSICS
12136 static void
st_collections_group_parts_part_description_physics_sleep(void)12137 st_collections_group_parts_part_description_physics_sleep(void)
12138 {
12139 check_arg_count(2);
12140
12141 current_desc->physics.sleep.linear = parse_float(0);
12142 current_desc->physics.sleep.angular = parse_float(1);
12143 }
12144
12145 #endif
12146
12147 /**
12148 @page edcref
12149 @property
12150 material
12151 @parameters
12152 [body's material]
12153 @effect
12154 Set the type (all caps) from among the available material types,
12155 it's set to CUSTOM by default.
12156 Each material has specific properties to be
12157 applied on the body, as density, friction and restitution.
12158 So if a material different of CUSTOM is set, the properties cited above
12159 won't be considered.
12160 Valid types:
12161 @li CUSTOM
12162 @li CONCRETE
12163 @li IRON
12164 @li PLASTIC
12165 @li POLYSTYRENE
12166 @li RUBBER
12167 @li WOOD
12168
12169 @since 1.8
12170 @endproperty
12171 */
12172 #ifdef HAVE_EPHYSICS
12173 static void
st_collections_group_parts_part_description_physics_material(void)12174 st_collections_group_parts_part_description_physics_material(void)
12175 {
12176 check_arg_count(1);
12177
12178 current_desc->physics.material = parse_enum(0,
12179 "CUSTOM", EPHYSICS_BODY_MATERIAL_CUSTOM,
12180 "CONCRETE", EPHYSICS_BODY_MATERIAL_CONCRETE,
12181 "IRON", EPHYSICS_BODY_MATERIAL_IRON,
12182 "PLASTIC", EPHYSICS_BODY_MATERIAL_PLASTIC,
12183 "POLYSTYRENE", EPHYSICS_BODY_MATERIAL_POLYSTYRENE,
12184 "RUBBER", EPHYSICS_BODY_MATERIAL_RUBBER,
12185 "WOOD", EPHYSICS_BODY_MATERIAL_WOOD,
12186 NULL);
12187 }
12188
12189 #endif
12190
12191 /**
12192 @page edcref
12193 @property
12194 density
12195 @parameters
12196 [body's material density]
12197 @effect
12198 It will set the body mass considering its volume. While a density is
12199 set, resizing a body will always recalculate its mass.
12200 When a mass is explicitely set the density will be unset.
12201 @since 1.8
12202 @endproperty
12203 */
12204 #ifdef HAVE_EPHYSICS
12205 static void
st_collections_group_parts_part_description_physics_density(void)12206 st_collections_group_parts_part_description_physics_density(void)
12207 {
12208 check_arg_count(1);
12209
12210 current_desc->physics.density = parse_float(0);
12211 }
12212
12213 #endif
12214
12215 /**
12216 @page edcref
12217 @property
12218 hardness
12219 @parameters
12220 [soft body or cloth hardness]
12221 @effect
12222 The hardness is set with a double value (0.0 - 1.0), defining
12223 how the soft body is supposed to deform.
12224 Its default is set to 1.0. The soft body mass will also interfere on
12225 soft body deformation, so bare in mind that the bodies mass must also
12226 be changed to have different deformation results.
12227 Valid values vary from 0.0 to 1.0. Only works on soft bodies and cloths.
12228 @since 1.8
12229 @endproperty
12230 */
12231 #ifdef HAVE_EPHYSICS
12232 static void
st_collections_group_parts_part_description_physics_hardness(void)12233 st_collections_group_parts_part_description_physics_hardness(void)
12234 {
12235 check_arg_count(1);
12236
12237 current_desc->physics.hardness = parse_float_range(0, 0, 1.0);
12238 }
12239
12240 #endif
12241
12242 /**
12243 @page edcref
12244 @property
12245 light_on
12246 @parameters
12247 [1 or 0]
12248 @effect
12249 Set body to be affected by world's light or not.
12250 It won't be respected if world's property "all_bodies" is enabled.
12251 Disabled by default (0).
12252 @since 1.8
12253 @endproperty
12254 */
12255 #ifdef HAVE_EPHYSICS
12256 static void
st_collections_group_parts_part_description_physics_light_on(void)12257 st_collections_group_parts_part_description_physics_light_on(void)
12258 {
12259 check_arg_count(1);
12260
12261 current_desc->physics.light_on = parse_bool(0);
12262 }
12263
12264 #endif
12265
12266 /**
12267 @page edcref
12268 @property
12269 z
12270 @parameters
12271 [body position in z axis]
12272 @effect
12273 Defines body position in z axis. It's set to -15 by default.
12274 @since 1.8
12275 @endproperty
12276 */
12277 #ifdef HAVE_EPHYSICS
12278 static void
st_collections_group_parts_part_description_physics_z(void)12279 st_collections_group_parts_part_description_physics_z(void)
12280 {
12281 check_arg_count(1);
12282
12283 current_desc->physics.z = parse_int(0);
12284 }
12285
12286 #endif
12287
12288 /**
12289 @page edcref
12290 @property
12291 depth
12292 @parameters
12293 [body's depth]
12294 @effect
12295 Defines body's depth (z axis). It's set to 30 by default.
12296 @since 1.8
12297 @endproperty
12298 */
12299 #ifdef HAVE_EPHYSICS
12300 static void
st_collections_group_parts_part_description_physics_depth(void)12301 st_collections_group_parts_part_description_physics_depth(void)
12302 {
12303 check_arg_count(1);
12304
12305 current_desc->physics.depth = parse_int(0);
12306 }
12307
12308 #endif
12309
12310 /**
12311 @page edcref
12312 @property
12313 backface_cull
12314 @parameters
12315 [1 or 0]
12316 @effect
12317 This enables backface culling (when the rotated part that normally faces
12318 the camera is facing away after being rotated etc.).
12319 This means that the object will be hidden when "backface culled".
12320 @since 1.8
12321 @endproperty
12322 */
12323 #ifdef HAVE_EPHYSICS
12324 static void
st_collections_group_parts_part_description_physics_backface_cull(void)12325 st_collections_group_parts_part_description_physics_backface_cull(void)
12326 {
12327 check_arg_count(1);
12328
12329 current_desc->physics.backcull = parse_bool(0);
12330 }
12331
12332 #endif
12333
12334 /** @edcsubsection{collections_group_parts_description_physics_movement_freedom,
12335 * Group.Parts.Part.Description.Physics.Movement_Freedom} */
12336
12337 /**
12338 @page edcref
12339 @block
12340 movement_freedom
12341 @context
12342 physics {
12343 ...
12344 movement_freedom {
12345 linear: 1 1 0;
12346 angular: 0 0 1;
12347 }
12348 }
12349 ..
12350 @description
12351 The "movement_freedom" block consists of two blocks to describe all
12352 the allowed movements for a body.
12353 It's set by default to allow just 2D movement (linear moves on
12354 x and y axis and rotations on x-y plane).
12355 @endblock
12356
12357 @property
12358 linear
12359 @parameters
12360 [x-axis (1 or 0)] [y-axis (1 or 0)] [z-axis (1 or 0)]
12361 @effect
12362 Block "linear" can be used to allow linear movements in the three
12363 axes. Allowed values are 0 or 1.
12364 Axes x and y are enabled by default.
12365 @since 1.8
12366 @endproperty
12367 */
12368 #ifdef HAVE_EPHYSICS
12369 static void
st_collections_group_parts_part_description_physics_movement_freedom_linear(void)12370 st_collections_group_parts_part_description_physics_movement_freedom_linear(void)
12371 {
12372 check_arg_count(3);
12373
12374 current_desc->physics.mov_freedom.lin.x = parse_bool(0);
12375 current_desc->physics.mov_freedom.lin.y = parse_bool(1);
12376 current_desc->physics.mov_freedom.lin.z = parse_bool(2);
12377 }
12378
12379 #endif
12380
12381 /**
12382 @page edcref
12383 @property
12384 angular
12385 @parameters
12386 [x-axis (1 or 0)] [y-axis (1 or 0)] [z-axis (1 or 0)]
12387 @effect
12388 Block "angular" can be used to allow angular movements around the three
12389 axes. Allowed values are 0 or 1.
12390 Z axis is enabled by default.
12391 @since 1.8
12392 @endproperty
12393 */
12394 #ifdef HAVE_EPHYSICS
12395 static void
st_collections_group_parts_part_description_physics_movement_freedom_angular(void)12396 st_collections_group_parts_part_description_physics_movement_freedom_angular(void)
12397 {
12398 check_arg_count(3);
12399
12400 current_desc->physics.mov_freedom.ang.x = parse_bool(0);
12401 current_desc->physics.mov_freedom.ang.y = parse_bool(1);
12402 current_desc->physics.mov_freedom.ang.z = parse_bool(2);
12403 }
12404
12405 #endif
12406
12407 /** @edcsubsection{collections_group_parts_description_physics_faces,
12408 * Group.Parts.Part.Description.Physics.Faces} */
12409
12410 /**
12411 @page edcref
12412 @block
12413 faces
12414 @context
12415 physics {
12416 ...
12417 faces {
12418 face {
12419 type: BOX_FRONT;
12420 source: "groupname";
12421 }
12422 ..
12423 }
12424 ..
12425 }
12426 @description
12427 The "faces" block contains a list of one or more "face" blocks.
12428 The "faces" block is used to list the faces that compose the body.
12429 Each face is described by a "face" block, that associates a part
12430 to a specific face of the body's shape.
12431 Only the "faces" block declared in the "default" description
12432 will be considered.
12433 @endblock
12434 */
12435 #ifdef HAVE_EPHYSICS
12436 static void
st_collections_group_parts_part_description_physics_face(void)12437 st_collections_group_parts_part_description_physics_face(void)
12438 {
12439 Edje_Physics_Face *pface;
12440
12441 pface = mem_alloc(SZ(Edje_Physics_Face));
12442 current_desc->physics.faces = eina_list_append(current_desc->physics.faces,
12443 pface);
12444 pface->type = 0;
12445 pface->source = NULL;
12446 }
12447
12448 #endif
12449
12450 /**
12451 @page edcref
12452 @property
12453 type
12454 @parameters
12455 [FACE]
12456 @effect
12457 Set the face (all caps) from among the available body's shape faces.
12458 Valid faces:
12459 @li BOX_MIDDLE_FRONT
12460 @li BOX_MIDDLE_BACK
12461 @li BOX_FRONT
12462 @li BOX_BACK
12463 @li BOX_LEFT
12464 @li BOX_RIGHT
12465 @li BOX_TOP
12466 @li BOX_BOTTOM
12467 @li CLOTH_FRONT
12468 @li CLOTH_BACK
12469 @li CYLINDER_MIDDLE_FRONT
12470 @li CYLINDER_MIDDLE_BACK
12471 @li CYLINDER_FRONT
12472 @li CYLINDER_BACK
12473 @li CYLINDER_CURVED
12474 @li SPHERE_FRONT
12475 @li SPHERE_BACK
12476 @endproperty
12477 */
12478 #ifdef HAVE_EPHYSICS
12479 static void
st_collections_group_parts_part_description_physics_face_type(void)12480 st_collections_group_parts_part_description_physics_face_type(void)
12481 {
12482 Edje_Physics_Face *pface, *pface2;
12483 Eina_List *l;
12484
12485 pface = eina_list_data_get(eina_list_last(current_desc->physics.faces));
12486 pface->type = parse_enum(0,
12487 "BOX_MIDDLE_FRONT", EPHYSICS_BODY_BOX_FACE_MIDDLE_FRONT,
12488 "BOX_MIDDLE_BACK", EPHYSICS_BODY_BOX_FACE_MIDDLE_BACK,
12489 "BOX_FRONT", EPHYSICS_BODY_BOX_FACE_FRONT,
12490 "BOX_BACK", EPHYSICS_BODY_BOX_FACE_BACK,
12491 "BOX_LEFT", EPHYSICS_BODY_BOX_FACE_LEFT,
12492 "BOX_RIGHT", EPHYSICS_BODY_BOX_FACE_RIGHT,
12493 "BOX_TOP", EPHYSICS_BODY_BOX_FACE_TOP,
12494 "BOX_BOTTOM", EPHYSICS_BODY_BOX_FACE_BOTTOM,
12495 "CLOTH_FRONT", EPHYSICS_BODY_CLOTH_FACE_FRONT,
12496 "CLOTH_BACK", EPHYSICS_BODY_CLOTH_FACE_BACK,
12497 "CYLINDER_MIDDLE_FRONT", EPHYSICS_BODY_CYLINDER_FACE_MIDDLE_FRONT,
12498 "CYLINDER_MIDDLE_BACK", EPHYSICS_BODY_CYLINDER_FACE_MIDDLE_BACK,
12499 "CYLINDER_FRONT", EPHYSICS_BODY_CYLINDER_FACE_FRONT,
12500 "CYLINDER_BACK", EPHYSICS_BODY_CYLINDER_FACE_BACK,
12501 "CYLINDER_CURVED", EPHYSICS_BODY_CYLINDER_FACE_CURVED,
12502 "SPHERE_FRONT", EPHYSICS_BODY_SPHERE_FACE_FRONT,
12503 "SPHERE_BACK", EPHYSICS_BODY_SPHERE_FACE_BACK,
12504 NULL);
12505
12506 EINA_LIST_FOREACH(current_desc->physics.faces, l, pface2)
12507 {
12508 if ((pface != pface2) && (pface->type == pface2->type))
12509 {
12510 ERR("parse error %s:%i. There is already a face of type \"%i\"",
12511 file_in, line - 1, pface->type);
12512 exit(-1);
12513 }
12514 }
12515 }
12516
12517 #endif
12518
12519 /**
12520 @page edcref
12521 @property
12522 source
12523 @parameters
12524 [another group's name]
12525 @effect
12526 This sets the group that is used as the object representing the physics
12527 body face.
12528 @endproperty
12529 */
12530 #ifdef HAVE_EPHYSICS
12531 static void
st_collections_group_parts_part_description_physics_face_source(void)12532 st_collections_group_parts_part_description_physics_face_source(void)
12533 {
12534 Edje_Physics_Face *pface;
12535
12536 pface = eina_list_data_get(eina_list_last(current_desc->physics.faces));
12537 check_arg_count(1);
12538
12539 pface->source = parse_str(0);
12540 data_queue_face_group_lookup(pface->source);
12541 }
12542
12543 #endif
12544
12545 /** @edcsubsection{collections_group_parts_description_map,
12546 * Group.Parts.Part.Description.Map} */
12547
12548 /**
12549 @page edcref
12550 @block
12551 map
12552 @context
12553 description {
12554 ..
12555 map {
12556 perspective: "name";
12557 light: "name";
12558 on: 1;
12559 smooth: 1;
12560 perspective_on: 1;
12561 backface_cull: 1;
12562 alpha: 1;
12563
12564 rotation {
12565 ..
12566 }
12567 }
12568 ..
12569 }
12570
12571 @description
12572 @endblock
12573
12574 @property
12575 perspective
12576 @parameters
12577 [another part's name]
12578 @effect
12579 This sets the part that is used as the "perspective point" for giving
12580 a part a "3d look". The perspective point should have a perspective
12581 section that provides zplane and focal properties. The center of this
12582 part will be used as the focal point, so size, color and visibility
12583 etc. are not relevant just center point, zplane and focal are used.
12584 This also implicitly enables perspective transforms (see the on
12585 parameter for the map section).
12586 @endproperty
12587 */
12588 static void
st_collections_group_parts_part_description_map_perspective(void)12589 st_collections_group_parts_part_description_map_perspective(void)
12590 {
12591 Edje_Part_Collection *pc;
12592
12593 check_arg_count(1);
12594
12595 pc = eina_list_data_get(eina_list_last(edje_collections));
12596
12597 {
12598 char *name;
12599
12600 name = parse_str(0);
12601 data_queue_part_lookup(pc, name, &(current_desc->map.id_persp));
12602 free(name);
12603 }
12604
12605 current_desc->map.persp_on = 1;
12606 }
12607
12608 /**
12609 @page edcref
12610 @property
12611 light
12612 @parameters
12613 [another part's name]
12614 @effect
12615 This sets the part that is used as the "light" for calculating the
12616 brightness (based on how directly the part's surface is facing the
12617 light source point). Like the perspective point part, the center point
12618 is used and zplane is used for the z position (0 being the zero-plane
12619 where all 2D objects normally live) and positive values being further
12620 away into the distance. The light part color is used as the light
12621 color (alpha not used for light color). The color2 color is used for
12622 the ambient lighting when calculating brightness (alpha also not
12623 used).
12624 @endproperty
12625 */
12626 static void
st_collections_group_parts_part_description_map_light(void)12627 st_collections_group_parts_part_description_map_light(void)
12628 {
12629 Edje_Part_Collection *pc;
12630
12631 check_arg_count(1);
12632
12633 pc = eina_list_data_get(eina_list_last(edje_collections));
12634
12635 {
12636 char *name;
12637
12638 name = parse_str(0);
12639 data_queue_part_lookup(pc, name, &(current_desc->map.id_light));
12640 free(name);
12641 }
12642 }
12643
12644 /** @edcsubsection{collections_group_parts_description_map_zoom,
12645 * Group.Parts.Part.Description.Map.Zoom} */
12646
12647 /**
12648 @page edcref
12649 @block
12650 rotation
12651 @context
12652 map {
12653 ..
12654 zoom {
12655 center: "name";
12656 x: 1.0;
12657 y: 1.0;
12658 }
12659 ..
12660 }
12661 @description
12662 Zooms the part, optionally from the center on another part.
12663 @endblock
12664
12665 @property
12666 center
12667 @parameters
12668 [another part's name]
12669 @effect
12670 This sets the part that is used as the center of zoom when
12671 zooming the part with this description. The part's center point
12672 is used as the zoom center when applying zoom from the
12673 x and y axes. If no center is given, the parts original center
12674 itself is used for the zoom center.
12675 @endproperty
12676 */
12677 static void
st_collections_group_parts_part_description_map_zoom_center(void)12678 st_collections_group_parts_part_description_map_zoom_center(void)
12679 {
12680 Edje_Part_Collection *pc;
12681
12682 check_arg_count(1);
12683
12684 pc = eina_list_data_get(eina_list_last(edje_collections));
12685
12686 {
12687 char *name;
12688
12689 name = parse_str(0);
12690 data_queue_part_lookup(pc, name, &(current_desc->map.zoom.id_center));
12691 free(name);
12692 }
12693 }
12694
12695 /**
12696 @page edcref
12697 @property
12698 on
12699 @parameters
12700 [1 or 0]
12701 @effect
12702 This enables mapping for the part.
12703
12704 Defaults: 0
12705 @endproperty
12706 */
12707 static void
st_collections_group_parts_part_description_map_on(void)12708 st_collections_group_parts_part_description_map_on(void)
12709 {
12710 check_arg_count(1);
12711
12712 current_desc->map.on = parse_bool(0);
12713 }
12714
12715 /**
12716 @page edcref
12717 @property
12718 smooth
12719 @parameters
12720 [1 or 0]
12721 @effect
12722 This enable smooth map rendering. This may be linear interpolation,
12723 anisotropic filtering or anything the engine decides is "smooth".
12724 This is a best-effort hint and may not produce precisely the same
12725 results in all engines and situations.
12726
12727 Defaults: 1
12728 @endproperty
12729 */
12730 static void
st_collections_group_parts_part_description_map_smooth(void)12731 st_collections_group_parts_part_description_map_smooth(void)
12732 {
12733 check_arg_count(1);
12734
12735 current_desc->map.smooth = parse_bool(0);
12736 }
12737
12738 /**
12739 @page edcref
12740 @property
12741 alpha
12742 @parameters
12743 [1 or 0]
12744 @effect
12745 This enable alpha channel when map rendering.
12746
12747 Defaults: 1
12748 @endproperty
12749 */
12750 static void
st_collections_group_parts_part_description_map_alpha(void)12751 st_collections_group_parts_part_description_map_alpha(void)
12752 {
12753 check_arg_count(1);
12754
12755 current_desc->map.alpha = parse_bool(0);
12756 }
12757
12758 /**
12759 @page edcref
12760 @property
12761 backface_cull
12762 @parameters
12763 [1 or 0]
12764 @effect
12765 This enables backface culling (when the rotated part that normally
12766 faces the camera is facing away after being rotated etc.). This means
12767 that the object will be hidden when "backface culled".
12768
12769 Defaults: 0
12770 @endproperty
12771 */
12772 static void
st_collections_group_parts_part_description_map_backface_cull(void)12773 st_collections_group_parts_part_description_map_backface_cull(void)
12774 {
12775 check_arg_count(1);
12776
12777 current_desc->map.backcull = parse_bool(0);
12778 }
12779
12780 /**
12781 @page edcref
12782 @property
12783 perspective_on
12784 @parameters
12785 [1 or 0]
12786 @effect
12787 Enable perspective when rotating even without a perspective point object.
12788 This would use perspective set for the object itself or for the
12789 canvas as a whole as the global perspective with
12790 edje_perspective_set() and edje_perspective_global_set().
12791
12792 Defaults: 0
12793 @endproperty
12794 */
12795 static void
st_collections_group_parts_part_description_map_perspective_on(void)12796 st_collections_group_parts_part_description_map_perspective_on(void)
12797 {
12798 check_arg_count(1);
12799
12800 current_desc->map.persp_on = parse_bool(0);
12801 }
12802
12803 /**
12804 @page edcref
12805 @property
12806 color
12807 @parameters
12808 [point] [red] [green] [blue] [alpha] or
12809 [point] "#[RR][GG][BB](AA)" or "#[R][G][B](A)"
12810 @effect
12811 Set the color of a vertex in the map.
12812 Colors will be linearly interpolated between vertex points through the map.
12813 The default color of a vertex in a map is white solid (255, 255, 255, 255)
12814 which means it will have no affect on modifying the part pixels.
12815 Currently only four points are supported:
12816 @li 0 - Left-Top point of a part.
12817 @li 1 - Right-Top point of a part.
12818 @li 2 - Left-Bottom point of a part.
12819 @li 3 - Right-Bottom point of a part.
12820
12821 Color format:
12822 @li [red] [green] [blue] [alpha]: one integer [0-255] for each
12823 RGBA channel, i.e. 255 0 0 255
12824 @li "#[RR][GG][BB](AA)": string with two hex values per RGBA channel,
12825 i.e "#FF0000FF" or "#FF0000"
12826 @li "#[R][G][B](A)": string with one hex value per RGBA channel,
12827 i.e "#F00F" or "#F00".\n
12828 In string format you can omit alpha channel and it will be set to FF.
12829
12830 Defaults: 255 255 255 255
12831 @endproperty
12832 */
12833 static void
st_collections_group_parts_part_description_map_color(void)12834 st_collections_group_parts_part_description_map_color(void)
12835 {
12836 Edje_Map_Color *color;
12837 Edje_Map_Color tmp = { 0 };
12838 int i;
12839
12840 check_min_arg_count(2);
12841
12842 tmp.idx = parse_int(0);
12843 parse_color(1, &tmp.r);
12844
12845 for (i = 0; i < (int)current_desc->map.colors_count; i++)
12846 {
12847 color = current_desc->map.colors[i];
12848 if (color->idx != tmp.idx) continue;
12849 color->r = tmp.r;
12850 color->g = tmp.g;
12851 color->b = tmp.b;
12852 color->a = tmp.a;
12853 return;
12854 }
12855 color = mem_alloc(SZ(Edje_Map_Color));
12856 if (!color)
12857 {
12858 ERR("not enough memory");
12859 exit(-1);
12860 }
12861
12862 *color = tmp;
12863 current_desc->map.colors_count++;
12864 current_desc->map.colors =
12865 realloc(current_desc->map.colors,
12866 sizeof(Edje_Map_Color *) * current_desc->map.colors_count);
12867 current_desc->map.colors[current_desc->map.colors_count - 1] = color;
12868 }
12869
12870 /**
12871 @page edcref
12872 @property
12873 zoom.x
12874 @parameters
12875 [X horizontal zoom to use]
12876 @effect
12877 This sets the zoom rate of the horizontal
12878
12879 Defaults: 1.0
12880 @endproperty
12881 */
12882 static void
st_collections_group_parts_part_description_map_zoom_x(void)12883 st_collections_group_parts_part_description_map_zoom_x(void)
12884 {
12885 check_arg_count(1);
12886
12887 current_desc->map.zoom.x = FROM_DOUBLE(parse_float_range(0, 0.0, 999999999.0));
12888 }
12889
12890 /**
12891 @page edcref
12892 @property
12893 zoom.y
12894 @parameters
12895 [Y vertical zoom to use]
12896 @effect
12897 This sets the zoom rate of vertical
12898
12899 Defaults: 1.0
12900 @endproperty
12901 */
12902 static void
st_collections_group_parts_part_description_map_zoom_y(void)12903 st_collections_group_parts_part_description_map_zoom_y(void)
12904 {
12905 check_arg_count(1);
12906
12907 current_desc->map.zoom.y = FROM_DOUBLE(parse_float_range(0, 0.0, 999999999.0));
12908 }
12909
12910 /** @edcsubsection{collections_group_parts_description_map_rotation,
12911 * Group.Parts.Part.Description.Map.Rotation} */
12912
12913 /**
12914 @page edcref
12915 @block
12916 rotation
12917 @context
12918 map {
12919 ..
12920 rotation {
12921 center: "name";
12922 x: 45.0;
12923 y: 45.0;
12924 z: 45.0;
12925 }
12926 ..
12927 }
12928 @description
12929 Rotates the part, optionally with the center on another part.
12930 @endblock
12931
12932 @property
12933 center
12934 @parameters
12935 [another part's name]
12936 @effect
12937 This sets the part that is used as the center of rotation when
12938 rotating the part with this description. The part's center point
12939 is used as the rotation center when applying rotation around the
12940 x, y and z axes. If no center is given, the parts original center
12941 itself is used for the rotation center.
12942 @endproperty
12943 */
12944 static void
st_collections_group_parts_part_description_map_rotation_center(void)12945 st_collections_group_parts_part_description_map_rotation_center(void)
12946 {
12947 Edje_Part_Collection *pc;
12948
12949 check_arg_count(1);
12950
12951 pc = eina_list_data_get(eina_list_last(edje_collections));
12952
12953 {
12954 char *name;
12955
12956 name = parse_str(0);
12957 data_queue_part_lookup(pc, name, &(current_desc->map.rot.id_center));
12958 free(name);
12959 }
12960 }
12961
12962 /**
12963 @page edcref
12964 @property
12965 x
12966 @parameters
12967 [X degrees]
12968 @effect
12969 This sets the rotation around the x axis of the part considering
12970 the center set. In degrees.
12971
12972 Defaults: 0.0
12973 @endproperty
12974 */
12975 static void
st_collections_group_parts_part_description_map_rotation_x(void)12976 st_collections_group_parts_part_description_map_rotation_x(void)
12977 {
12978 check_arg_count(1);
12979
12980 current_desc->map.rot.x = FROM_DOUBLE(parse_float(0));
12981 }
12982
12983 /**
12984 @page edcref
12985 @property
12986 y
12987 @parameters
12988 [Y degrees]
12989 @effect
12990 This sets the rotation around the y axis of the part considering
12991 the center set. In degrees.
12992
12993 Defaults: 0.0
12994 @endproperty
12995 */
12996 static void
st_collections_group_parts_part_description_map_rotation_y(void)12997 st_collections_group_parts_part_description_map_rotation_y(void)
12998 {
12999 check_arg_count(1);
13000
13001 current_desc->map.rot.y = FROM_DOUBLE(parse_float(0));
13002 }
13003
13004 /**
13005 @page edcref
13006 @property
13007 z
13008 @parameters
13009 [Z degrees]
13010 @effect
13011 This sets the rotation around the z axis of the part considering
13012 the center set. In degrees.
13013
13014 Defaults: 0.0
13015 @endproperty
13016 */
13017 static void
st_collections_group_parts_part_description_map_rotation_z(void)13018 st_collections_group_parts_part_description_map_rotation_z(void)
13019 {
13020 check_arg_count(1);
13021
13022 current_desc->map.rot.z = FROM_DOUBLE(parse_float(0));
13023 }
13024
13025 /** @edcsubsection{collections_group_parts_description_perspective,
13026 * Group.Parts.Part.Description.Perspective} */
13027
13028 /**
13029 @page edcref
13030 @block
13031 perspective
13032 @context
13033 description {
13034 ..
13035 perspective {
13036 zplane: 0;
13037 focal: 1000;
13038 }
13039 ..
13040 }
13041 @description
13042 Adds focal and plane perspective to the part. Active if perspective_on is true.
13043 Must be provided if the part is being used by other part as it's perspective target.
13044 @endblock
13045
13046 @property
13047 zplane
13048 @parameters
13049 [unscaled Z value]
13050 @effect
13051 This sets the z value that will not be scaled. Normally this is 0 as
13052 that is the z distance that all objects are at normally.
13053
13054 Defaults: 0
13055 @endproperty
13056 */
13057 static void
st_collections_group_parts_part_description_perspective_zplane(void)13058 st_collections_group_parts_part_description_perspective_zplane(void)
13059 {
13060 check_arg_count(1);
13061
13062 current_desc->persp.zplane = parse_int(0);
13063 }
13064
13065 /**
13066 @page edcref
13067 @property
13068 focal
13069 @parameters
13070 [distance]
13071 @effect
13072 This sets the distance from the focal z plane (zplane) and the
13073 camera - i.e. very much equating to focal length of the camera
13074
13075 Defaults: 1000
13076 @endproperty
13077 */
13078 static void
st_collections_group_parts_part_description_perspective_focal(void)13079 st_collections_group_parts_part_description_perspective_focal(void)
13080 {
13081 check_arg_count(1);
13082
13083 current_desc->persp.focal = parse_int_range(0, 1, 0x7fffffff);
13084 }
13085
13086 /** @edcsubsection{collections_group_parts_description_filter,
13087 * Group.Parts.Part.Description.Filter} */
13088
13089 /**
13090 @page edcref
13091 @block
13092 filter
13093 @context
13094 part {
13095 type: [IMAGE or TEXT or PROXY or SNAPSHOT];
13096 ..
13097 description {
13098 ..
13099 filter {
13100 code: "blend {}";
13101 // or:
13102 code: "filter_name";
13103 source: "part1" "buf";
13104 source: "part2" "otherbuf";
13105 source: "part3";
13106 ..
13107 data: "the_answer" "42";
13108 data: "something" "anything";
13109 data: "mycc" "color_class('my_color_class')";
13110 ..
13111 }
13112 // or:
13113 text.filter: "blend {} -- ...";
13114 ..
13115 }
13116 }
13117 @description
13118 Applies a series of image filters to a TEXT, IMAGE, PROXY or SNAPSHOT part.
13119 For more information, please refer to the page
13120 @ref evasfiltersref "Evas filters reference".
13121 @endblock
13122
13123 @property
13124 filter.code
13125 @parameters
13126 [filter script or filter name]
13127 @effect
13128 The argument to this field is the source code of a Lua script as defined
13129 @ref evasfiltersref "here" or a filter name defined in the
13130 @ref sec_collections_group_filters "Filters" section.
13131 @endproperty
13132 */
13133 static void
st_collections_group_parts_part_description_filter_code(void)13134 st_collections_group_parts_part_description_filter_code(void)
13135 {
13136 Edje_Part_Description_Spec_Filter *filter;
13137
13138 check_arg_count(1);
13139
13140 if (current_part->type == EDJE_PART_TYPE_TEXT)
13141 filter = &(((Edje_Part_Description_Text *)current_desc)->filter);
13142 else if (current_part->type == EDJE_PART_TYPE_IMAGE)
13143 filter = &(((Edje_Part_Description_Image *)current_desc)->filter);
13144 else if (current_part->type == EDJE_PART_TYPE_PROXY)
13145 filter = &(((Edje_Part_Description_Proxy *)current_desc)->filter);
13146 else if (current_part->type == EDJE_PART_TYPE_SNAPSHOT)
13147 filter = &(((Edje_Part_Description_Snapshot *)current_desc)->filter);
13148 else
13149 {
13150 ERR("parse error %s:%i. filter only supported for: TEXT, IMAGE, PROXY, SNAPSHOT.",
13151 file_in, line - 1);
13152 exit(-1);
13153 }
13154
13155 free((void *)filter->code);
13156 filter->code = parse_str(0);
13157 }
13158
13159 /**
13160 @page edcref
13161
13162 @property
13163 filter.source
13164 @parameters
13165 [another part's name] [(optional) buffer name for filter program]
13166 @effect
13167 Binds another part as an image source (like a proxy source) for a
13168 text or image filter operation. Optionally, a buffer name may be
13169 specified, so the same filter code can be used with different sources.
13170 @endproperty
13171 */
13172 static void
st_collections_group_parts_part_description_filter_source(void)13173 st_collections_group_parts_part_description_filter_source(void)
13174 {
13175 Edje_Part_Description_Spec_Filter *filter;
13176 Edje_Part_Collection *pc;
13177 char *name, *part, *str;
13178 size_t sn = 0, sp, k;
13179 int *part_key;
13180 int args;
13181
13182 static const char allowed_name_chars[] =
13183 "abcdefghijklmnopqrstuvwxyzABCDEFGHJIKLMNOPQRSTUVWXYZ0123456789_";
13184
13185 if (current_part->type == EDJE_PART_TYPE_TEXT)
13186 filter = &(((Edje_Part_Description_Text *)current_desc)->filter);
13187 else if (current_part->type == EDJE_PART_TYPE_IMAGE)
13188 filter = &(((Edje_Part_Description_Image *)current_desc)->filter);
13189 else if (current_part->type == EDJE_PART_TYPE_PROXY)
13190 filter = &(((Edje_Part_Description_Proxy *)current_desc)->filter);
13191 else if (current_part->type == EDJE_PART_TYPE_SNAPSHOT)
13192 filter = &(((Edje_Part_Description_Snapshot *)current_desc)->filter);
13193 else
13194 {
13195 ERR("parse error %s:%i. filter only supported for: TEXT, IMAGE, PROXY, SNAPSHOT.",
13196 file_in, line - 1);
13197 exit(-1);
13198 }
13199
13200 args = check_range_arg_count(1, 2);
13201 pc = eina_list_data_get(eina_list_last(edje_collections));
13202
13203 part = parse_str(0);
13204 sp = strlen(part);
13205
13206 if (args > 1)
13207 {
13208 name = parse_str(1);
13209 if (name) sn = strlen(name);
13210 if (!name || (strspn(name, allowed_name_chars) != sn))
13211 {
13212 ERR("parse error %s:%i. invalid name for a filter buffer: '%s'",
13213 file_in, line - 1, name);
13214 exit(-1);
13215 }
13216 }
13217 else
13218 name = NULL;
13219
13220 if (!name && (strspn(part, allowed_name_chars) == sp))
13221 str = strdup(part);
13222 else
13223 {
13224 if (!name)
13225 {
13226 // name = part so we replace all invalid chars by '_'
13227 name = strdup(part);
13228 sn = strlen(name);
13229 for (k = 0; k < sn; k++)
13230 {
13231 if (!strchr(allowed_name_chars, name[k]))
13232 name[k] = '_';
13233 }
13234 }
13235 sn += sp + 1;
13236 str = malloc(sn + 1);
13237 if (!str) exit(-1);
13238 strncpy(str, name, sn);
13239 strncat(str, ":", sn);
13240 strncat(str, part, sn);
13241 str[sn] = '\0';
13242 }
13243 filter->sources = eina_list_append(filter->sources, str);
13244
13245 // note: this is leaked. not a big deal.
13246 part_key = malloc(sizeof(int));
13247 *part_key = -1;
13248 data_queue_part_lookup(pc, part, part_key);
13249
13250 free(part);
13251 free(name);
13252 }
13253
13254 /**
13255 @page edcref
13256
13257 @property
13258 filter.data
13259 @parameters
13260 [name] [content]
13261 @effect
13262 Pass extra data to the Lua filter program. All data passed will
13263 be strings, except for the special case of color classes:
13264 @code
13265 filter.data: "mycc" "color_class('my_color_class')";
13266 @endcode
13267 Those will appear to Lua as a table of the following structure:
13268 @code
13269 -- Lua code
13270 mycc = { r = 255, g = 0, b, a, r2, g2, b2, a2, r3, g3, b3, a3 }
13271 @endcode
13272 @endproperty
13273 */
13274 static void
st_collections_group_parts_part_description_filter_data(void)13275 st_collections_group_parts_part_description_filter_data(void)
13276 {
13277 Edje_Part_Description_Spec_Filter_Data *array;
13278 Edje_Part_Description_Spec_Filter *filter;
13279 char *name, *value;
13280 unsigned k;
13281
13282 if (current_part->type == EDJE_PART_TYPE_TEXT)
13283 filter = &(((Edje_Part_Description_Text *)current_desc)->filter);
13284 else if (current_part->type == EDJE_PART_TYPE_IMAGE)
13285 filter = &(((Edje_Part_Description_Image *)current_desc)->filter);
13286 else if (current_part->type == EDJE_PART_TYPE_PROXY)
13287 filter = &(((Edje_Part_Description_Proxy *)current_desc)->filter);
13288 else if (current_part->type == EDJE_PART_TYPE_SNAPSHOT)
13289 filter = &(((Edje_Part_Description_Snapshot *)current_desc)->filter);
13290 else
13291 {
13292 ERR("parse error %s:%i. filter only supported for: TEXT, IMAGE, PROXY, SNAPSHOT.",
13293 file_in, line - 1);
13294 exit(-1);
13295 }
13296
13297 check_arg_count(2);
13298
13299 name = parse_str(0);
13300 value = parse_str(1);
13301 for (k = 0; k < filter->data_count; k++)
13302 if (!strcmp(filter->data[k].name, name))
13303 {
13304 ERR("parse error %s:%i. filter.data '%s' already exists in this context",
13305 file_in, line - 1, name);
13306 exit(-1);
13307 }
13308
13309 filter->data_count++;
13310 array = realloc(filter->data, sizeof(Edje_Part_Description_Spec_Filter_Data) * filter->data_count);
13311 array[filter->data_count - 1].name = name;
13312 array[filter->data_count - 1].value = value;
13313 filter->data = array;
13314 }
13315
13316 /** @edcsubsection{collections_group_parts_descriptions_params,
13317 * Group.Parts.Part.Description.Params} */
13318
13319 /**
13320 @page edcref
13321 @block
13322 params
13323 @context
13324 description {
13325 ..
13326 params {
13327 int: "name" 0;
13328 double: "other_name" 0.0;
13329 string: "another_name" "some text";
13330 bool: "name" 1;
13331 choice: "some_name" "value";
13332 }
13333 ..
13334 }
13335 @description
13336 Set parameters for EXTERNAL parts. The value overwrites previous
13337 definitions with the same name.
13338 @endblock
13339 */
13340 static void
_st_collections_group_parts_part_description_params(Edje_External_Param_Type type)13341 _st_collections_group_parts_part_description_params(Edje_External_Param_Type type)
13342 {
13343 Edje_Part_Description_External *ed;
13344 Edje_External_Param *param;
13345 Eina_List *l;
13346 char *name;
13347 int found = 0;
13348
13349 check_arg_count(2);
13350
13351 if (current_part->type != EDJE_PART_TYPE_EXTERNAL)
13352 {
13353 ERR("parse error %s:%i. params in non-EXTERNAL part.",
13354 file_in, line - 1);
13355 exit(-1);
13356 }
13357
13358 ed = (Edje_Part_Description_External *)current_desc;
13359
13360 name = parse_str(0);
13361
13362 /* if a param with this name already exists, overwrite it */
13363 EINA_LIST_FOREACH(ed->external_params, l, param)
13364 {
13365 if (!strcmp(param->name, name))
13366 {
13367 found = 1;
13368 free(name);
13369 break;
13370 }
13371 }
13372
13373 if (!found)
13374 {
13375 param = mem_alloc(SZ(Edje_External_Param));
13376 param->name = name;
13377 }
13378
13379 param->type = type;
13380 param->i = 0;
13381 param->d = 0;
13382 param->s = NULL;
13383
13384 switch (type)
13385 {
13386 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
13387 param->i = parse_bool(1);
13388 break;
13389
13390 case EDJE_EXTERNAL_PARAM_TYPE_INT:
13391 param->i = parse_int(1);
13392 break;
13393
13394 case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
13395 param->d = parse_float(1);
13396 break;
13397
13398 case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
13399 case EDJE_EXTERNAL_PARAM_TYPE_STRING:
13400 param->s = parse_str(1);
13401 break;
13402
13403 default:
13404 ERR("parse error %s:%i. Invalid param type.",
13405 file_in, line - 1);
13406 break;
13407 }
13408
13409 if (!found)
13410 ed->external_params = eina_list_append(ed->external_params, param);
13411 }
13412
13413 /**
13414 @page edcref
13415 @property
13416 int
13417 @parameters
13418 [param_name] [int_value]
13419 @effect
13420 Adds an integer parameter for an external object
13421 @endproperty
13422 */
13423 static void
st_collections_group_parts_part_description_params_int(void)13424 st_collections_group_parts_part_description_params_int(void)
13425 {
13426 _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_INT);
13427 }
13428
13429 /**
13430 @page edcref
13431 @property
13432 double
13433 @parameters
13434 [param_name] [double_value]
13435 @effect
13436 Adds a double parameter for an external object
13437 @endproperty
13438 */
13439 static void
st_collections_group_parts_part_description_params_double(void)13440 st_collections_group_parts_part_description_params_double(void)
13441 {
13442 _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_DOUBLE);
13443 }
13444
13445 /**
13446 @page edcref
13447 @property
13448 string
13449 @parameters
13450 [param_name] [string_value]
13451 @effect
13452 Adds a string parameter for an external object
13453 @endproperty
13454 */
13455 static void
st_collections_group_parts_part_description_params_string(void)13456 st_collections_group_parts_part_description_params_string(void)
13457 {
13458 _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_STRING);
13459 }
13460
13461 /**
13462 @page edcref
13463 @property
13464 bool
13465 @parameters
13466 [param_name] [bool_value]
13467 @effect
13468 Adds an boolean parameter for an external object.
13469 @endproperty
13470 */
13471 static void
st_collections_group_parts_part_description_params_bool(void)13472 st_collections_group_parts_part_description_params_bool(void)
13473 {
13474 _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_BOOL);
13475 }
13476
13477 /**
13478 @page edcref
13479 @property
13480 choice
13481 @parameters
13482 [param_name] [choice_string]
13483 @effect
13484 Adds a choice parameter for an external object. The possible
13485 choice values are defined by external type at their register time
13486 and will be validated at runtime.
13487 @endproperty
13488 */
13489 static void
st_collections_group_parts_part_description_params_choice(void)13490 st_collections_group_parts_part_description_params_choice(void)
13491 {
13492 _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_CHOICE);
13493 }
13494
13495 static void
st_collections_group_parts_part_description_vector_frame(void)13496 st_collections_group_parts_part_description_vector_frame(void)
13497 {
13498 Edje_Part_Description_Vector *ed;
13499
13500 check_arg_count(1);
13501
13502 if (current_part->type != EDJE_PART_TYPE_VECTOR)
13503 {
13504 ERR("parse error %s:%i. vector attributes in non-VECTOR part.",
13505 file_in, line - 1);
13506 exit(-1);
13507 }
13508
13509 ed = (Edje_Part_Description_Vector *)current_desc;
13510
13511 ed->vg.frame = parse_float_range(0, 0.0, 1.0);
13512 }
13513
13514 /** @edcsubsection{collections_group_parts_description_links,
13515 * Group.Parts.Part.Description.Links} */
13516
13517 /**
13518 @page edcref
13519 @block
13520 link
13521 @context
13522 description {
13523 ..
13524 link {
13525 base: "edje,signal" "edje";
13526 transition: LINEAR 0.2;
13527 in: 0.5 0.1;
13528 after: "some_program";
13529 }
13530 ..
13531 }
13532 @description
13533 The link block can be used to create transitions to the enclosing part description state.
13534 The result of the above block is identical to creating a program with
13535 action: STATE_SET "default";
13536 signal: "edje,signal"; source: "edje";
13537 @since 1.10
13538 @endblock
13539 */
13540 static void
ob_collections_group_parts_part_description_link(void)13541 ob_collections_group_parts_part_description_link(void)
13542 {
13543 Edje_Part_Collection_Parser *pcp;
13544 Edje_Part_Parser *epp;
13545 Edje_Part_Description_Link *el;
13546 const char *nm;
13547
13548 pcp = eina_list_last_data_get(edje_collections);
13549 epp = (Edje_Part_Parser *)current_part;
13550
13551 ob_collections_group_programs_program();
13552 _edje_program_remove((Edje_Part_Collection *)pcp, current_program);
13553 el = mem_alloc(SZ(Edje_Part_Description_Link));
13554 el->pr = current_program;
13555 el->ed = current_desc;
13556 el->epp = epp;
13557 pcp->links = eina_list_append(pcp->links, el);
13558 current_program->action = EDJE_ACTION_TYPE_STATE_SET;
13559 nm = current_desc->state.name;
13560 current_program->state = strdup(nm ? nm : "default");
13561 current_program->value = current_desc->state.value;
13562 }
13563
13564 static void
list_free(void * list)13565 list_free(void *list)
13566 {
13567 eina_list_free(list);
13568 }
13569
13570 /**
13571 @page edcref
13572 @property
13573 base
13574 @parameters
13575 [signal] [source]
13576 @effect
13577 Defines the signal and source which will trigger the transition to this state.
13578 The source parameter is optional here and will be filled with the current group's
13579 default value if it is not provided.
13580 @since 1.10
13581 @endproperty
13582 */
13583 static void
st_collections_group_parts_part_description_link_base(void)13584 st_collections_group_parts_part_description_link_base(void)
13585 {
13586 char *name;
13587 char buf[4096];
13588 Edje_Part_Collection_Parser *pcp;
13589 Edje_Part_Description_Link *el, *ell;
13590 Eina_List *l;
13591
13592 pcp = eina_list_last_data_get(edje_collections);
13593 el = eina_list_last_data_get(pcp->links);
13594
13595 if ((!el) || (el->pr != current_program) ||
13596 (el->ed != current_desc) || (el->epp != (Edje_Part_Parser *)current_part) ||
13597 el->pr->source)
13598 ob_collections_group_parts_part_description_link();
13599 el = eina_list_last_data_get(pcp->links);
13600
13601 check_min_arg_count(1);
13602 name = parse_str(0);
13603 if (current_program->signal && pcp->link_hash)
13604 {
13605 snprintf(buf, sizeof(buf), "%s\"\"\"%s", current_program->signal,
13606 current_program->source ? current_program->source : "");
13607 eina_hash_list_remove(pcp->link_hash, buf, el);
13608 }
13609 if (!pcp->link_hash)
13610 pcp->link_hash = eina_hash_string_superfast_new(list_free);
13611 free((void *)current_program->signal);
13612 current_program->signal = name;
13613 if (get_arg_count() == 2)
13614 {
13615 name = parse_str(1);
13616 free((void *)current_program->source);
13617 current_program->source = name;
13618 }
13619 snprintf(buf, sizeof(buf), "%s\"\"\"%s", current_program->signal,
13620 current_program->source ? current_program->source : "");
13621 EINA_LIST_FOREACH(eina_hash_find(pcp->link_hash, buf), l, ell)
13622 {
13623 if (ell->epp == el->epp)
13624 {
13625 ERR("parse error %s:%i. "
13626 "cannot have multiple links with the same signal on the same part",
13627 file_in, line - 1);
13628 exit(-1);
13629 }
13630 }
13631 eina_hash_list_append(pcp->link_hash, buf, el);
13632 }
13633
13634 /** @edcsubsection{collections_group_programs,
13635 * Group.Programs} */
13636
13637 /**
13638 @page edcref
13639 @block
13640 programs
13641 @context
13642 group {
13643 programs {
13644 ..
13645 program { }
13646 program { }
13647 program { }
13648 ..
13649 }
13650 }
13651 @description
13652 The programs group contain one ore more program.
13653 @endblock
13654 */
13655 static void
_program_sequence_check(void)13656 _program_sequence_check(void)
13657 {
13658 if (sequencing != current_program) return;
13659 ERR("parse error %s:%i. cannot set sequence parent program attributes within sequence block",
13660 file_in, line - 1);
13661 exit(-1);
13662 }
13663
13664 static void
_program_after(const char * name)13665 _program_after(const char *name)
13666 {
13667 Edje_Part_Collection *pc;
13668 Edje_Program *ep;
13669 Edje_Program_After *pa;
13670 Edje_Program_After *pa2;
13671 Eina_List *l;
13672 char *copy;
13673 void *pl;
13674
13675 pc = eina_list_data_get(eina_list_last(edje_collections));
13676 ep = current_program;
13677
13678 EINA_LIST_FOREACH(ep->after, l, pa2)
13679 {
13680 if (!strcmp(name, (char *)(pa2 + 1)))
13681 return;
13682 }
13683
13684 pa = mem_alloc(SZ(Edje_Program_After) + strlen(name) + 1);
13685 pa->id = -1;
13686 ep->after = eina_list_append(ep->after, pa);
13687 copy = (char *)(pa + 1);
13688 memcpy(copy, name, strlen(name) + 1);
13689 pl = data_queue_program_lookup(pc, name, &(pa->id));
13690 if (pl)
13691 current_program_lookups = eina_list_append(current_program_lookups, pl);
13692 }
13693
13694 static Edje_Program *
_program_sequence_new(void)13695 _program_sequence_new(void)
13696 {
13697 Edje_Program *ep, *pr = current_program;
13698
13699 /* sequence a new program after current */
13700 ob_collections_group_programs_program();
13701 ep = current_program;
13702 current_program = pr;
13703 _program_after(ep->name);
13704 return current_program = ep;
13705 }
13706
13707 /** @edcsubsection{collections_group_programs_program,
13708 * Group.Programs.Program} */
13709
13710 /**
13711 @page edcref
13712 @block
13713 program
13714 @context
13715 programs {
13716 ..
13717 program {
13718 name: "programname";
13719 signal: "signalname";
13720 source: "partname";
13721 filter: "partname" "statename";
13722 in: 0.3 0.0;
13723 action: STATE_SET "statename" state_value;
13724 transition: LINEAR 0.5;
13725 target: "partname";
13726 target: "anotherpart";
13727 after: "programname";
13728 after: "anotherprogram";
13729 }
13730 ..
13731 }
13732 @description
13733 Programs define how your interface reacts to events.
13734 Programs can change the state of parts, react to events or trigger
13735 other events.
13736 @endblock
13737 */
13738 static void
ob_collections_group_programs_program(void)13739 ob_collections_group_programs_program(void)
13740 {
13741 Edje_Part_Collection *pc;
13742 Edje_Part_Collection_Parser *pcp;
13743 Edje_Program *ep;
13744 Edje_Program_Parser *epp;
13745 char *def_name;
13746
13747 current_program_lookups = eina_list_free(current_program_lookups);
13748
13749 pc = eina_list_data_get(eina_list_last(edje_collections));
13750 pcp = eina_list_data_get(eina_list_last(edje_collections));
13751
13752 ep = mem_alloc(SZ(Edje_Program_Parser));
13753 ep->id = -1;
13754 ep->tween.mode = EDJE_TWEEN_MODE_LINEAR;
13755 ep->tween.use_duration_factor = EINA_FALSE;
13756 ep->after = NULL;
13757 epp = (Edje_Program_Parser *)ep;
13758 epp->can_override = EINA_FALSE;
13759
13760 /* generate new name */
13761 def_name = alloca(strlen("program_") + strlen("FFFFFFFFFFFFFFFF") + 1);
13762 sprintf(def_name, "program_%X", pc->programs.total_count);
13763 ep->name = strdup(def_name);
13764 if (pcp->default_source)
13765 ep->source = strdup(pcp->default_source);
13766 _edje_program_insert(pc, ep);
13767
13768 current_program = ep;
13769 pc->programs.total_count++;
13770 }
13771
13772 static void
_program_name(char * name)13773 _program_name(char *name)
13774 {
13775 Edje_Part_Collection *pc;
13776 Eina_List *l;
13777 void *pl;
13778
13779 pc = eina_list_data_get(eina_list_last(edje_collections));
13780 free((void *)current_program->name);
13781 current_program->name = name;
13782
13783 _edje_program_check(current_program->name, current_program, pc->programs.fnmatch, pc->programs.fnmatch_count);
13784 _edje_program_check(current_program->name, current_program, pc->programs.strcmp, pc->programs.strcmp_count);
13785 _edje_program_check(current_program->name, current_program, pc->programs.strncmp, pc->programs.strncmp_count);
13786 _edje_program_check(current_program->name, current_program, pc->programs.strrncmp, pc->programs.strrncmp_count);
13787 _edje_program_check(current_program->name, current_program, pc->programs.nocmp, pc->programs.nocmp_count);
13788
13789 EINA_LIST_FOREACH(current_program_lookups, l, pl)
13790 program_lookup_rename(pl, name);
13791 }
13792
13793 /**
13794 @page edcref
13795 @property
13796 name
13797 @parameters
13798 [program name]
13799 @effect
13800 Symbolic name of program as a unique identifier.
13801 @endproperty
13802 */
13803 static void
st_collections_group_programs_program_name(void)13804 st_collections_group_programs_program_name(void)
13805 {
13806 check_arg_count(1);
13807 _program_sequence_check();
13808 _program_name(parse_str(0));
13809 }
13810
13811 /**
13812 @page edcref
13813 @property
13814 signal
13815 @parameters
13816 [signal name]
13817 @effect
13818 Specifies signal(s) that should cause the program to run. The signal
13819 received must match the specified source to run.
13820 Signals may be globbed, but only one signal keyword per program
13821 may be used. ex: signal: "mouse,clicked,*"; (clicking any mouse button
13822 that matches source starts program).
13823 A list of global signal, that edje provide:
13824 - hold,on;
13825 - hold,off;
13826 - mouse,in;
13827 - mouse,out;
13828 - mouse,pressed,in;
13829 - mouse,pressed,out;
13830 - mouse,down,N: where N - mouse button number;
13831 - mouse,down,N,double: where N - mouse button number;
13832 - mouse,down,N,triple: where N - mouse button number;
13833 - mouse,up,N: where N - mouse button number;
13834 - mouse,clicked,N: where N - mouse button number;
13835 - mouse,move;
13836 - mouse,wheel,N,M: where N - the direction (by default is 0),
13837 M - 1 if wheel scrolled up and -1 if down;
13838 - drag,start;
13839 - drag;
13840 - drag,stop;
13841 - focus,part,in;
13842 - focus,part,out.
13843 @endproperty
13844 */
13845 static void
st_collections_group_programs_program_signal(void)13846 st_collections_group_programs_program_signal(void)
13847 {
13848 Edje_Part_Collection *pc;
13849
13850 check_arg_count(1);
13851
13852 _program_sequence_check();
13853
13854 pc = eina_list_data_get(eina_list_last(edje_collections));
13855
13856 _edje_program_remove(pc, current_program);
13857 current_program->signal = parse_str(0);
13858 _edje_program_insert(pc, current_program);
13859 }
13860
13861 /**
13862 @page edcref
13863 @property
13864 source
13865 @parameters
13866 [source name]
13867 @effect
13868 Source of accepted signal. Sources may be globbed, but only one source
13869 keyword per program may be used. ex: source: "button-*"; (Signals from
13870 any part or program named "button-*" are accepted).
13871 @endproperty
13872 */
13873 static void
st_collections_group_programs_program_source(void)13874 st_collections_group_programs_program_source(void)
13875 {
13876 Edje_Part_Collection *pc;
13877
13878 check_arg_count(1);
13879
13880 _program_sequence_check();
13881
13882 pc = eina_list_data_get(eina_list_last(edje_collections));
13883
13884 _edje_program_remove(pc, current_program);
13885 free((void *)current_program->source);
13886 current_program->source = parse_str(0);
13887 _edje_program_insert(pc, current_program);
13888 }
13889
13890 /**
13891 @page edcref
13892 @property
13893 filter
13894 @parameters
13895 [part] [state]
13896 @effect
13897 Filter signals to be only accepted if the part [part] is in state named [state].
13898 Only one filter per program can be used. If [part] is not given, the source of
13899 the event will be used instead.
13900 @endproperty
13901 */
13902 static void
st_collections_group_programs_program_filter(void)13903 st_collections_group_programs_program_filter(void)
13904 {
13905 check_min_arg_count(1);
13906
13907 _program_sequence_check();
13908
13909 if (is_param(1))
13910 {
13911 current_program->filter.part = parse_str(0);
13912 current_program->filter.state = parse_str(1);
13913 }
13914 else
13915 {
13916 current_program->filter.state = parse_str(0);
13917 }
13918 }
13919
13920 /**
13921 @page edcref
13922 @property
13923 in
13924 @parameters
13925 [from] [range]
13926 @effect
13927 Wait 'from' seconds before executing the program. And add a random
13928 number of seconds (from 0 to 'range') to the total waiting time.
13929
13930 Defaults: 0.0 0.0
13931 @endproperty
13932 */
13933 static void
st_collections_group_programs_program_in(void)13934 st_collections_group_programs_program_in(void)
13935 {
13936 check_arg_count(2);
13937
13938 _program_sequence_check();
13939
13940 current_program->in.from = parse_float_range(0, 0.0, 999999999.0);
13941 current_program->in.range = parse_float_range(1, 0.0, 999999999.0);
13942 }
13943
13944 /**
13945 @page edcref
13946 @property
13947 action
13948 @parameters
13949 [type] (param1) (param2) (param3) (param4)
13950 @effect
13951 Action to be performed by the program. Valid actions are:
13952 @li STATE_SET "state name" (state value)
13953 @li ACTION_STOP
13954 @li SIGNAL_EMIT "signalname" "emitter"
13955 @li DRAG_VAL_SET 0.5 0.0
13956 @li DRAG_VAL_STEP 1.0 0.0
13957 @li DRAG_VAL_PAGE 0.0 0.0
13958 @li FOCUS_SET ("seat")
13959 @li FOCUS_OBJECT ("seat")
13960 @li PARAM_COPY "src_part" "src_param" "dst_part" "dst_param"
13961 @li PARAM_SET "part" "param" "value"
13962 @li PLAY_SAMPLE "sample name" speed (channel)
13963 @li PLAY_TONE "tone name" duration_in_seconds( Range 0.1 to 10.0 )
13964 @li PLAY_VIBRATION "sample name" repeat (repeat count)
13965 @li PHYSICS_IMPULSE 10 -23.4 0
13966 @li PHYSICS_TORQUE_IMPULSE 0 2.1 0.95
13967 @li PHYSICS_FORCE -20.8 0 30.85
13968 @li PHYSICS_TORQUE 0 0 4.8
13969 @li PHYSICS_FORCES_CLEAR
13970 @li PHYSICS_VEL_SET 40.9 0 0
13971 @li PHYSICS_ANG_VEL_SET 12.4 0 0.66
13972 @li PHYSICS_STOP
13973 @li PHYSICS_ROT_SET 0.707 0 0 0.707
13974
13975 Only one action can be specified per program.
13976
13977 PLAY_SAMPLE (optional) channel can be one of:
13978 @li EFFECT/FX
13979 @li BACKGROUND/BG
13980 @li MUSIC/MUS
13981 @li FOREGROUND/FG
13982 @li INTERFACE/UI
13983 @li INPUT
13984 @li ALERT
13985
13986 @endproperty
13987 */
13988 static void
st_collections_group_programs_program_action(void)13989 st_collections_group_programs_program_action(void)
13990 {
13991 Edje_Part_Collection *pc;
13992 Edje_Program *ep;
13993 int i;
13994 Eina_Bool found = EINA_FALSE;
13995
13996 pc = eina_list_data_get(eina_list_last(edje_collections));
13997 if (sequencing)
13998 ep = _program_sequence_new();
13999 else
14000 ep = current_program;
14001 ep->action = parse_enum(0,
14002 "STATE_SET", EDJE_ACTION_TYPE_STATE_SET,
14003 "ACTION_STOP", EDJE_ACTION_TYPE_ACTION_STOP,
14004 "SIGNAL_EMIT", EDJE_ACTION_TYPE_SIGNAL_EMIT,
14005 "DRAG_VAL_SET", EDJE_ACTION_TYPE_DRAG_VAL_SET,
14006 "DRAG_VAL_STEP", EDJE_ACTION_TYPE_DRAG_VAL_STEP,
14007 "DRAG_VAL_PAGE", EDJE_ACTION_TYPE_DRAG_VAL_PAGE,
14008 "SCRIPT", EDJE_ACTION_TYPE_SCRIPT,
14009 "FOCUS_SET", EDJE_ACTION_TYPE_FOCUS_SET,
14010 "FOCUS_OBJECT", EDJE_ACTION_TYPE_FOCUS_OBJECT,
14011 "PARAM_COPY", EDJE_ACTION_TYPE_PARAM_COPY,
14012 "PARAM_SET", EDJE_ACTION_TYPE_PARAM_SET,
14013 "PLAY_SAMPLE", EDJE_ACTION_TYPE_SOUND_SAMPLE,
14014 "PLAY_TONE", EDJE_ACTION_TYPE_SOUND_TONE,
14015 "PHYSICS_IMPULSE", EDJE_ACTION_TYPE_PHYSICS_IMPULSE,
14016 "PHYSICS_TORQUE_IMPULSE", EDJE_ACTION_TYPE_PHYSICS_TORQUE_IMPULSE,
14017 "PHYSICS_FORCE", EDJE_ACTION_TYPE_PHYSICS_FORCE,
14018 "PHYSICS_TORQUE", EDJE_ACTION_TYPE_PHYSICS_TORQUE,
14019 "PHYSICS_FORCES_CLEAR", EDJE_ACTION_TYPE_PHYSICS_FORCES_CLEAR,
14020 "PHYSICS_VEL_SET", EDJE_ACTION_TYPE_PHYSICS_VEL_SET,
14021 "PHYSICS_ANG_VEL_SET", EDJE_ACTION_TYPE_PHYSICS_ANG_VEL_SET,
14022 "PHYSICS_STOP", EDJE_ACTION_TYPE_PHYSICS_STOP,
14023 "PHYSICS_ROT_SET", EDJE_ACTION_TYPE_PHYSICS_ROT_SET,
14024 "PLAY_VIBRATION", EDJE_ACTION_TYPE_VIBRATION_SAMPLE,
14025 "VG_ANIM_STOP", EDJE_ACTION_TYPE_VG_ANIM_STOP,
14026 "VG_ANIM_PAUSE", EDJE_ACTION_TYPE_VG_ANIM_PAUSE,
14027 "VG_ANIM_RESUME", EDJE_ACTION_TYPE_VG_ANIM_RESUME,
14028 "VG_ANIM_PLAY", EDJE_ACTION_TYPE_VG_ANIM_PLAY,
14029 "VG_ANIM_REWIND", EDJE_ACTION_TYPE_VG_ANIM_REWIND,
14030 "VG_ANIM_LOOP", EDJE_ACTION_TYPE_VG_ANIM_LOOP,
14031 NULL);
14032 if (ep->action == EDJE_ACTION_TYPE_STATE_SET)
14033 {
14034 ep->state = parse_str(1);
14035 if (get_arg_count() == 2)
14036 ep->value = 0.0;
14037 else
14038 ep->value = parse_float_range(2, 0.0, 1.0);
14039 }
14040 else if ((ep->action == EDJE_ACTION_TYPE_FOCUS_SET) ||
14041 (ep->action == EDJE_ACTION_TYPE_FOCUS_OBJECT))
14042 {
14043 if (get_arg_count() == 1)
14044 ep->seat = NULL;
14045 else
14046 ep->seat = parse_str(1);
14047 }
14048 else if (ep->action == EDJE_ACTION_TYPE_SIGNAL_EMIT)
14049 {
14050 ep->state = parse_str(1);
14051 ep->state2 = parse_str(2);
14052 }
14053 else if (ep->action == EDJE_ACTION_TYPE_SOUND_SAMPLE)
14054 {
14055 ep->sample_name = parse_str(1);
14056 if (edje_file->sound_dir)
14057 {
14058 for (i = 0; i < (int)edje_file->sound_dir->samples_count; i++)
14059 {
14060 if (!strcmp(edje_file->sound_dir->samples[i].name, ep->sample_name))
14061 {
14062 found = EINA_TRUE;
14063 break;
14064 }
14065 }
14066 }
14067 if (!found)
14068 {
14069 ERR("No Sample name %s exist.", ep->sample_name);
14070 exit(-1);
14071 }
14072 ep->speed = parse_float_range(2, 0.0, 100.0);
14073 if (get_arg_count() >= 4)
14074 ep->channel = parse_enum(3,
14075 "EFFECT", 0, "FX", 0,
14076 "BACKGROUND", 1, "BG", 1,
14077 "MUSIC", 2, "MUS", 2,
14078 "FOREGROUND", 3, "FG", 3,
14079 "INTERFACE", 4, "UI", 4,
14080 "INPUT", 5,
14081 "ALERT", 6,
14082 NULL);
14083 }
14084 else if (ep->action == EDJE_ACTION_TYPE_SOUND_TONE)
14085 {
14086 ep->tone_name = parse_str(1);
14087 if (edje_file->sound_dir)
14088 {
14089 for (i = 0; i < (int)edje_file->sound_dir->tones_count; i++)
14090 {
14091 if (!strcmp(edje_file->sound_dir->tones[i].name, ep->tone_name))
14092 {
14093 found = EINA_TRUE;
14094 break;
14095 }
14096 }
14097 }
14098 if (!found)
14099 {
14100 ERR("No Tone name %s exist.", ep->tone_name);
14101 exit(-1);
14102 }
14103 ep->duration = parse_float_range(2, 0.1, 10.0);
14104 }
14105 else if (ep->action == EDJE_ACTION_TYPE_VIBRATION_SAMPLE)
14106 {
14107 ep->vibration_name = parse_str(1);
14108 for (i = 0; i < (int)edje_file->vibration_dir->samples_count; i++)
14109 {
14110 if (!strcmp(edje_file->vibration_dir->samples[i].name, ep->vibration_name))
14111 break;
14112 if (i == (int)(edje_file->vibration_dir->samples_count - 1))
14113 {
14114 ERR("No Vibration Sample name %s exist.", ep->vibration_name);
14115 exit(-1);
14116 }
14117 }
14118 ep->vibration_repeat = parse_int(2);
14119 }
14120 else if (ep->action == EDJE_ACTION_TYPE_DRAG_VAL_SET)
14121 {
14122 ep->value = parse_float(1);
14123 ep->value2 = parse_float(2);
14124 }
14125 else if (ep->action == EDJE_ACTION_TYPE_DRAG_VAL_STEP)
14126 {
14127 ep->value = parse_float(1);
14128 ep->value2 = parse_float(2);
14129 }
14130 else if (ep->action == EDJE_ACTION_TYPE_DRAG_VAL_PAGE)
14131 {
14132 ep->value = parse_float(1);
14133 ep->value2 = parse_float(2);
14134 }
14135 else if (ep->action == EDJE_ACTION_TYPE_PARAM_COPY)
14136 {
14137 char *src_part, *dst_part;
14138
14139 src_part = parse_str(1);
14140 ep->state = parse_str(2);
14141 dst_part = parse_str(3);
14142 ep->state2 = parse_str(4);
14143
14144 data_queue_part_lookup(pc, src_part, &(ep->param.src));
14145 data_queue_part_lookup(pc, dst_part, &(ep->param.dst));
14146
14147 free(src_part);
14148 free(dst_part);
14149 }
14150 else if (ep->action == EDJE_ACTION_TYPE_PARAM_SET)
14151 {
14152 char *part;
14153
14154 part = parse_str(1);
14155 ep->state = parse_str(2);
14156 ep->state2 = parse_str(3);
14157
14158 data_queue_part_lookup(pc, part, &(ep->param.dst));
14159 free(part);
14160 }
14161 #ifdef HAVE_EPHYSICS
14162 else if ((ep->action == EDJE_ACTION_TYPE_PHYSICS_IMPULSE) ||
14163 (ep->action == EDJE_ACTION_TYPE_PHYSICS_TORQUE_IMPULSE) ||
14164 (ep->action == EDJE_ACTION_TYPE_PHYSICS_FORCE) ||
14165 (ep->action == EDJE_ACTION_TYPE_PHYSICS_TORQUE) ||
14166 (ep->action == EDJE_ACTION_TYPE_PHYSICS_VEL_SET) ||
14167 (ep->action == EDJE_ACTION_TYPE_PHYSICS_ANG_VEL_SET))
14168 {
14169 ep->physics.x = parse_float(1);
14170 ep->physics.y = parse_float(2);
14171 ep->physics.z = parse_float(3);
14172 }
14173 else if (ep->action == EDJE_ACTION_TYPE_PHYSICS_ROT_SET)
14174 {
14175 ep->physics.w = parse_float(1);
14176 ep->physics.x = parse_float(2);
14177 ep->physics.y = parse_float(3);
14178 ep->physics.z = parse_float(4);
14179 }
14180 #endif
14181
14182 switch (ep->action)
14183 {
14184 case EDJE_ACTION_TYPE_SCRIPT:
14185 /* this is implicitly set by script {} so this is here just for
14186 * completeness */
14187 break;
14188
14189 case EDJE_ACTION_TYPE_ACTION_STOP:
14190 case EDJE_ACTION_TYPE_PHYSICS_FORCES_CLEAR:
14191 case EDJE_ACTION_TYPE_PHYSICS_STOP:
14192 case EDJE_ACTION_TYPE_VG_ANIM_STOP:
14193 case EDJE_ACTION_TYPE_VG_ANIM_PAUSE:
14194 case EDJE_ACTION_TYPE_VG_ANIM_RESUME:
14195 case EDJE_ACTION_TYPE_VG_ANIM_PLAY:
14196 case EDJE_ACTION_TYPE_VG_ANIM_REWIND:
14197 case EDJE_ACTION_TYPE_VG_ANIM_LOOP:
14198 check_arg_count(1);
14199 break;
14200
14201 case EDJE_ACTION_TYPE_PARAM_SET:
14202 case EDJE_ACTION_TYPE_PHYSICS_IMPULSE:
14203 case EDJE_ACTION_TYPE_PHYSICS_TORQUE_IMPULSE:
14204 case EDJE_ACTION_TYPE_PHYSICS_FORCE:
14205 case EDJE_ACTION_TYPE_PHYSICS_TORQUE:
14206 case EDJE_ACTION_TYPE_PHYSICS_VEL_SET:
14207 case EDJE_ACTION_TYPE_PHYSICS_ANG_VEL_SET:
14208 check_arg_count(4);
14209 break;
14210
14211 case EDJE_ACTION_TYPE_PARAM_COPY:
14212 case EDJE_ACTION_TYPE_PHYSICS_ROT_SET:
14213 check_arg_count(5);
14214 break;
14215
14216 case EDJE_ACTION_TYPE_SOUND_SAMPLE:
14217 case EDJE_ACTION_TYPE_VIBRATION_SAMPLE:
14218 break;
14219
14220 case EDJE_ACTION_TYPE_STATE_SET:
14221 check_min_arg_count(2);
14222 break;
14223
14224 case EDJE_ACTION_TYPE_FOCUS_SET:
14225 case EDJE_ACTION_TYPE_FOCUS_OBJECT:
14226 check_min_arg_count(1);
14227 break;
14228
14229 default:
14230 check_arg_count(3);
14231 }
14232 }
14233
14234 /**
14235 @page edcref
14236 @property
14237 transition
14238 @parameters
14239 [type] [length] (interp val 1) (interp val 2) (option)
14240 @effect
14241 Defines how transitions occur using STATE_SET action.\n
14242 Where 'type' is the style of the transition and 'length' is a double
14243 specifying the number of seconds in which to preform the transition.\n
14244 Valid types are:
14245 @li LIN or LINEAR
14246 @li SIN or SINUSOIDAL
14247 @li ACCEL or ACCELERATE
14248 @li DECEL or DECELERATE
14249 @li ACCEL_FAC or ACCELERATE_FACTOR
14250 @li DECEL_FAC or DECELERATE_FACTOR
14251 @li SIN_FAC or SINUSOIDAL_FACTOR
14252 @li DIVIS or DIVISOR_INTERP
14253 @li BOUNCE
14254 @li SPRING
14255 @li CUBIC_BEZIER
14256
14257 ACCEL_FAC, DECEL_FAC and SIN_FAC need the extra optional
14258 "interp val 1" to determine the "factor" of curviness. 1.0 is the same
14259 as their non-factor counterparts, where 0.0 is equal to linear.
14260 Numbers higher than one make the curve angles steeper with a more
14261 pronounced curve point.
14262
14263 DIVIS, BOUNCE and SPRING also require "interp val 2" in addition
14264 to "interp val 1".
14265
14266 DIVIS uses val 1 as the initial gradient start
14267 (0.0 is horizontal, 1.0 is diagonal (linear), 2.0 is twice the
14268 gradient of linear etc.). val 2 is interpreted as an integer factor
14269 defining how much the value swings "outside" the gradient only to come
14270 back to the final resting spot at the end. 0.0 for val 2 is equivalent
14271 to linear interpolation. Note that DIVIS can exceed 1.0
14272
14273 BOUNCE uses val 2 as the number of bounces (so its rounded down to
14274 the nearest integer value), with val 1 determining how much the
14275 bounce decays, with 0.0 giving linear decay per bounce, and higher
14276 values giving much more decay.
14277
14278 SPRING is similar to bounce, where val 2 specifies the number of
14279 spring "swings" and val 1 specifies the decay, but it can exceed 1.0
14280 on the outer swings.
14281
14282 Valid options are:
14283 @li CURRENT causes the object to move from its current position.
14284 Can be used as the last parameter of any transition type. (since 1.1.0)
14285
14286 @endproperty
14287 */
14288 static void
st_collections_group_programs_program_transition(void)14289 st_collections_group_programs_program_transition(void)
14290 {
14291 int current = -1, index = -1;
14292 unsigned int required_args = 0;
14293
14294 check_min_arg_count(2);
14295
14296 _program_sequence_check();
14297
14298 current_program->tween.v1 = current_program->tween.v2 =
14299 current_program->tween.v3 = current_program->tween.v4 = 0.0;
14300
14301 current_program->tween.mode = parse_enum(0,
14302 // short names
14303 "LIN", EDJE_TWEEN_MODE_LINEAR,
14304 "SIN", EDJE_TWEEN_MODE_SINUSOIDAL,
14305 "ACCEL", EDJE_TWEEN_MODE_ACCELERATE,
14306 "DECEL", EDJE_TWEEN_MODE_DECELERATE,
14307 "ACCEL_FAC", EDJE_TWEEN_MODE_ACCELERATE_FACTOR,
14308 "DECEL_FAC", EDJE_TWEEN_MODE_DECELERATE_FACTOR,
14309 "SIN_FAC", EDJE_TWEEN_MODE_SINUSOIDAL_FACTOR,
14310 "DIVIS", EDJE_TWEEN_MODE_DIVISOR_INTERP,
14311
14312 // long/full names
14313 "LINEAR", EDJE_TWEEN_MODE_LINEAR,
14314 "SINUSOIDAL", EDJE_TWEEN_MODE_SINUSOIDAL,
14315 "CUBIC_BEZIER", EDJE_TWEEN_MODE_CUBIC_BEZIER,
14316 "ACCELERATE", EDJE_TWEEN_MODE_ACCELERATE,
14317 "DECELERATE", EDJE_TWEEN_MODE_DECELERATE,
14318 "ACCELERATE_FACTOR", EDJE_TWEEN_MODE_ACCELERATE_FACTOR,
14319 "DECELERATE_FACTOR", EDJE_TWEEN_MODE_DECELERATE_FACTOR,
14320 "SINUSOIDAL_FACTOR", EDJE_TWEEN_MODE_SINUSOIDAL_FACTOR,
14321 "DIVISOR_INTERP", EDJE_TWEEN_MODE_DIVISOR_INTERP,
14322
14323 // long/full is short enough
14324 "BOUNCE", EDJE_TWEEN_MODE_BOUNCE,
14325 "SPRING", EDJE_TWEEN_MODE_SPRING,
14326 NULL);
14327 current_program->tween.time = FROM_DOUBLE(parse_float_range(1, 0.0, 999999999.0));
14328
14329 //Check the index of params not related to tweenmode's param
14330 //This index use for count of the tweenmode's param
14331 if ((index = get_param_index("USE_DURATION_FACTOR")) != -1)
14332 {
14333 current_program->tween.use_duration_factor = parse_bool(index + 1);
14334 required_args += 2;
14335 }
14336 if ((current = get_param_index("CURRENT")) != -1)
14337 {
14338 if (index == -1 || current < index)
14339 index = current;
14340 required_args++;
14341 }
14342 switch (current_program->tween.mode)
14343 {
14344 case EDJE_TWEEN_MODE_LINEAR:
14345 case EDJE_TWEEN_MODE_SINUSOIDAL:
14346 case EDJE_TWEEN_MODE_ACCELERATE:
14347 case EDJE_TWEEN_MODE_DECELERATE:
14348 {
14349 required_args += 2;
14350 check_arg_count(required_args);
14351 }
14352 break;
14353
14354 // the following need v1
14355 case EDJE_TWEEN_MODE_ACCELERATE_FACTOR:
14356 case EDJE_TWEEN_MODE_DECELERATE_FACTOR:
14357 case EDJE_TWEEN_MODE_SINUSOIDAL_FACTOR:
14358 {
14359 required_args += 3;
14360 check_arg_count(required_args);
14361 if (index == -1 || index > 2)
14362 {
14363 current_program->tween.v1 =
14364 FROM_DOUBLE(parse_float_range(2, -999999999.0, 999999999.0));
14365 break;
14366 }
14367 else
14368 {
14369 ERR("parse error %s:%i. Need 3rd parameter to set factor",
14370 file_in, line - 1);
14371 exit(-1);
14372 }
14373 }
14374
14375 case EDJE_TWEEN_MODE_DIVISOR_INTERP:
14376 case EDJE_TWEEN_MODE_BOUNCE:
14377 case EDJE_TWEEN_MODE_SPRING:
14378 {
14379 required_args += 4;
14380 check_arg_count(required_args);
14381 if (index == -1 || index > 3)
14382 {
14383 current_program->tween.v1 =
14384 FROM_DOUBLE(parse_float_range(2, -999999999.0, 999999999.0));
14385 current_program->tween.v2 =
14386 FROM_DOUBLE(parse_float_range(3, -999999999.0, 999999999.0));
14387 break;
14388 }
14389 else
14390 {
14391 ERR("parse error %s:%i. "
14392 "Need 3rd and 4th parameters to set factor and counts",
14393 file_in, line - 1);
14394 exit(-1);
14395 }
14396 }
14397
14398 case EDJE_TWEEN_MODE_CUBIC_BEZIER:
14399 {
14400 required_args += 6;
14401 check_arg_count(required_args);
14402 if (index == -1 || index > 5)
14403 {
14404 current_program->tween.v1 =
14405 FROM_DOUBLE(parse_float_range(2, -999999999.0, 999999999.0));
14406 current_program->tween.v2 =
14407 FROM_DOUBLE(parse_float_range(3, -999999999.0, 999999999.0));
14408 current_program->tween.v3 =
14409 FROM_DOUBLE(parse_float_range(4, -999999999.0, 999999999.0));
14410 current_program->tween.v4 =
14411 FROM_DOUBLE(parse_float_range(5, -999999999.0, 999999999.0));
14412 break;
14413 }
14414 else
14415 {
14416 ERR("parse error %s:%i. "
14417 "Need 3rd, 4th, 5th and 6th parameters to set x1, y1, x2 and y2",
14418 file_in, line - 1);
14419 exit(-1);
14420 }
14421 }
14422 }
14423 if (current > 0)
14424 current_program->tween.mode |= EDJE_TWEEN_MODE_OPT_FROM_CURRENT;
14425 }
14426
14427 static void
_program_target_add(char * name)14428 _program_target_add(char *name)
14429 {
14430 Edje_Part_Collection *pc;
14431 Edje_Program *ep;
14432 Edje_Program_Target *et;
14433 Edje_Program_Target *etw;
14434 Eina_List *l;
14435 char *copy;
14436
14437 pc = eina_list_data_get(eina_list_last(edje_collections));
14438 ep = current_program;
14439
14440 EINA_LIST_FOREACH(ep->targets, l, etw)
14441 {
14442 if (!strcmp(name, (char *)(etw + 1)))
14443 {
14444 free(name);
14445 return;
14446 }
14447 }
14448
14449 et = mem_alloc(SZ(Edje_Program_Target) + strlen(name) + 1);
14450 ep->targets = eina_list_append(ep->targets, et);
14451 copy = (char *)(et + 1);
14452 memcpy(copy, name, strlen(name) + 1);
14453 switch (ep->action)
14454 {
14455 case EDJE_ACTION_TYPE_ACTION_STOP:
14456 data_queue_program_lookup(pc, name, &(et->id));
14457 break;
14458
14459 case EDJE_ACTION_TYPE_STATE_SET:
14460 case EDJE_ACTION_TYPE_SIGNAL_EMIT:
14461 case EDJE_ACTION_TYPE_DRAG_VAL_SET:
14462 case EDJE_ACTION_TYPE_DRAG_VAL_STEP:
14463 case EDJE_ACTION_TYPE_DRAG_VAL_PAGE:
14464 case EDJE_ACTION_TYPE_FOCUS_SET:
14465 case EDJE_ACTION_TYPE_FOCUS_OBJECT:
14466 #ifdef HAVE_EPHYSICS
14467 case EDJE_ACTION_TYPE_PHYSICS_IMPULSE:
14468 case EDJE_ACTION_TYPE_PHYSICS_TORQUE_IMPULSE:
14469 case EDJE_ACTION_TYPE_PHYSICS_FORCE:
14470 case EDJE_ACTION_TYPE_PHYSICS_TORQUE:
14471 case EDJE_ACTION_TYPE_PHYSICS_FORCES_CLEAR:
14472 case EDJE_ACTION_TYPE_PHYSICS_VEL_SET:
14473 case EDJE_ACTION_TYPE_PHYSICS_ANG_VEL_SET:
14474 case EDJE_ACTION_TYPE_PHYSICS_STOP:
14475 case EDJE_ACTION_TYPE_PHYSICS_ROT_SET:
14476 #endif
14477 case EDJE_ACTION_TYPE_VG_ANIM_STOP:
14478 case EDJE_ACTION_TYPE_VG_ANIM_PAUSE:
14479 case EDJE_ACTION_TYPE_VG_ANIM_RESUME:
14480 case EDJE_ACTION_TYPE_VG_ANIM_PLAY:
14481 case EDJE_ACTION_TYPE_VG_ANIM_REWIND:
14482 case EDJE_ACTION_TYPE_VG_ANIM_LOOP:
14483 data_queue_part_lookup(pc, name, &(et->id));
14484 break;
14485
14486 default:
14487 ERR("parse error %s:%i. target may only be used after action",
14488 file_in, line - 1);
14489 exit(-1);
14490 }
14491 free(name);
14492 }
14493
14494 /**
14495 @page edcref
14496 @property
14497 target
14498 @parameters
14499 [target]
14500 @effect
14501 Program or part on which the specified action acts. Multiple target
14502 keywords may be specified, one per target. SIGNAL_EMITs can have
14503 targets.
14504 @endproperty
14505 */
14506 static void
st_collections_group_programs_program_target(void)14507 st_collections_group_programs_program_target(void)
14508 {
14509 check_arg_count(1);
14510
14511 _program_sequence_check();
14512
14513 _program_target_add(parse_str(0));
14514 }
14515
14516 /**
14517 @page edcref
14518 @property
14519 targets
14520 @parameters
14521 [target1] [target2] [target3] ...
14522 @effect
14523 Programs or parts upon which the specified action will act. Multiple
14524 target or targets keywords may be specified. SIGNAL_EMITs can have
14525 targets.
14526 @since 1.10
14527 @endproperty
14528 */
14529 static void
st_collections_group_programs_program_targets(void)14530 st_collections_group_programs_program_targets(void)
14531 {
14532 int n, argc;
14533
14534 check_min_arg_count(1);
14535
14536 _program_sequence_check();
14537
14538 for (n = 0, argc = get_arg_count(); n < argc; n++)
14539 _program_target_add(parse_str(n));
14540 }
14541
14542 /**
14543 @page edcref
14544 @property
14545 target_groups
14546 groups
14547 @parameters
14548 [group1] [group2] [group3] ...
14549 @effect
14550 Groups of programs or parts upon which the specified action will act. Multiple 'groups', 'target',
14551 and 'targets' keywords may be specified. SIGNAL_EMITs can have targets.
14552 @since 1.10
14553 @endproperty
14554 */
14555 static void
st_collections_group_programs_program_target_groups(void)14556 st_collections_group_programs_program_target_groups(void)
14557 {
14558 int n, argc;
14559 Edje_Part_Collection_Parser *pc;
14560
14561 check_min_arg_count(1);
14562
14563 pc = eina_list_last_data_get(edje_collections);
14564 for (n = 0, argc = get_arg_count(); n < argc; n++)
14565 {
14566 Eina_List *l;
14567 Edje_Target_Group *tg;
14568 char *name;
14569 Eina_Bool found = EINA_FALSE;
14570
14571 name = parse_str(n);
14572 EINA_LIST_FOREACH(pc->target_groups, l, tg)
14573 if (!strcmp(tg->name, name))
14574 {
14575 char **t;
14576
14577 for (t = tg->targets; *t; t++)
14578 _program_target_add(strdup(*t));
14579 found = EINA_TRUE;
14580 }
14581 if (found)
14582 {
14583 free(name);
14584 continue;
14585 }
14586 ERR("parse error %s:%i. There is no target_group with the name '%s'",
14587 file_in, line - 1, name);
14588 exit(-1);
14589 }
14590 }
14591
14592 /**
14593 @page edcref
14594 @property
14595 after
14596 @parameters
14597 [after]
14598 @effect
14599 Specifies a program to run after the current program completes. The
14600 source and signal parameters of a program run as an "after" are ignored.
14601 Multiple "after" statements can be specified per program.
14602 @endproperty
14603 */
14604 static void
st_collections_group_programs_program_after(void)14605 st_collections_group_programs_program_after(void)
14606 {
14607 char *name;
14608
14609 check_arg_count(1);
14610 _program_sequence_check();
14611 name = parse_str(0);
14612 _program_after(name);
14613 free(name);
14614 }
14615
14616 /**
14617 @page edcref
14618 @property
14619 api
14620 @parameters
14621 [name] [description]
14622 @effect
14623 Specifies a hint to let applications (or IDE's) know how to bind
14624 things. The parameter name should contain the name of the function that
14625 the application should use, and description describes how it should
14626 be used.
14627 @endproperty
14628 */
14629 static void
st_collections_group_programs_program_api(void)14630 st_collections_group_programs_program_api(void)
14631 {
14632 check_min_arg_count(1);
14633
14634 _program_sequence_check();
14635
14636 current_program->api.name = parse_str(0);
14637
14638 if (is_param(1))
14639 {
14640 check_arg_count(2);
14641 current_program->api.description = parse_str(1);
14642 }
14643 }
14644
14645 /** @edcsubsection{collections_group_program_sequence,
14646 * Group.Programs.Program.Sequence} */
14647
14648 /**
14649 @page edcref
14650 @block
14651 sequence
14652 @context
14653 ..
14654 program {
14655 name: "programname";
14656 signal: "signalname";
14657 source: "partname";
14658 filter: "partname" "statename";
14659 in: 0.3 0.0;
14660 action: STATE_SET "statename" state_value;
14661 transition: LINEAR 0.5;
14662 targets: "partname" "anotherpart";
14663 sequence {
14664 action: SIGNAL_EMIT "signal" "source";
14665 action: STATE_SET "somestate";
14666 transition: SINUSOIDAL 0.4;
14667 targets: "partname" "anotherpart";
14668 signal: "also,runs"; source: "on,signals";
14669 name: "runs_after_programname";
14670
14671 action: STATE_SET "someotherstate";
14672 transition: DECELERATE 4.0;
14673 in: 0.2 0.0;
14674 targets: "partname" "anotherpart";
14675 name: "runs_after_runs_after_programname";
14676 after: "coolprogram1337";
14677 filter: "partname" "goodstate";
14678 }
14679 }
14680 ..
14681 @description
14682 Sequences allow quick, easy chaining of programs.
14683 Each "action" keyword within the sequence will start a new program definition.
14684 Programs defined in sequences can be used as regular programs in every way,
14685 but they will automatically set up sequence chains which run after the originating program.
14686 After the sequence block is closed, the original program can continue to be
14687 modified.
14688 Scripts are allowed within sequences: each script block will be treated as a newly
14689 sequenced program.
14690 @since 1.10
14691 @endblock
14692 */
14693 static void
ob_collections_group_programs_program_sequence(void)14694 ob_collections_group_programs_program_sequence(void)
14695 {
14696 sequencing = current_program;
14697 sequencing_lookups = current_program_lookups;
14698 current_program_lookups = NULL;
14699 ((Edje_Program_Parser *)sequencing)->can_override = EINA_FALSE;
14700 }
14701
14702 static void
st_collections_group_parts_part_api(void)14703 st_collections_group_parts_part_api(void)
14704 {
14705 check_min_arg_count(1);
14706
14707 current_part->api.name = parse_str(0);
14708 if (is_param(1))
14709 {
14710 check_arg_count(2);
14711 current_part->api.description = parse_str(1);
14712 }
14713 }
14714
14715 static void
ob_collections_group_programs_program_script(void)14716 ob_collections_group_programs_program_script(void)
14717 {
14718 Edje_Part_Collection *pc;
14719 Code *cd;
14720
14721 pc = eina_list_data_get(eina_list_last(edje_collections));
14722 cd = eina_list_data_get(eina_list_last(codes));
14723
14724 if (!is_verbatim()) track_verbatim(1);
14725 else
14726 {
14727 Eina_Bool empty = EINA_TRUE;
14728 char *s;
14729 int i, len;
14730
14731 s = get_verbatim();
14732 if (s)
14733 {
14734 Code_Program *cp;
14735
14736 /* FIXME: Need to store the script somewhere to be restored when using edje_edit API */
14737 cp = mem_alloc(SZ(Code_Program));
14738 cp->l1 = get_verbatim_line1();
14739 cp->l2 = get_verbatim_line2();
14740 cp->script = s;
14741 cp->original = strdup(s);
14742 if (cd->shared && cd->is_lua)
14743 {
14744 ERR("parse error %s:%i. You're trying to mix Embryo and Lua scripting in the same group",
14745 file_in, line - 1);
14746 exit(-1);
14747 }
14748 cd->is_lua = 0;
14749
14750 len = strlen(cp->script);
14751 for (i = 0; empty && i < len; i++)
14752 {
14753 if (((cp->script[i] > 'a') && (cp->script[i] < 'z')) ||
14754 ((cp->script[i] > 'A') && (cp->script[i] < 'Z')) ||
14755 ((cp->script[i] > '0') && (cp->script[i] < '9')))
14756 empty = EINA_FALSE;
14757 }
14758
14759 if (sequencing)
14760 _program_sequence_new();
14761 if (!empty)
14762 {
14763 cd->programs = eina_list_append(cd->programs, cp);
14764 data_queue_anonymous_lookup(pc, current_program, &(cp->id));
14765 current_program->action = EDJE_ACTION_TYPE_SCRIPT;
14766 }
14767 else
14768 {
14769 data_queue_anonymous_lookup(pc, current_program, NULL);
14770 free(cp->original);
14771 free(cp);
14772 cp = NULL;
14773 }
14774
14775 set_verbatim(NULL, 0, 0);
14776 }
14777 }
14778 }
14779
14780 /** @edcsubsection{collections_group_physics,
14781 * Group.Physics} */
14782
14783 /**
14784 @page edcref
14785 @block
14786 physics
14787 @context
14788 group {
14789 ..
14790 physics {
14791 world {
14792 ..
14793 }
14794 }
14795 ..
14796 }
14797 @description
14798 The "physics" block consists of blocks related to physics but
14799 not to configure a body. By now, it only has a "world" block.
14800 @endblock
14801 */
14802
14803 /** @edcsubsection{collections_group_physics_world,
14804 * Group.Physics.World} */
14805
14806 /**
14807 @page edcref
14808 @block
14809 world
14810 @context
14811 physics {
14812 world {
14813 gravity: 0 294 0;
14814 rate: 30;
14815 z: -50;
14816 depth: 100;
14817 }
14818 }
14819 @description
14820 The "world" block configures the physics world. It's the
14821 environment where the part's bodies will be simulated.
14822 It can be used to customize gravity, rate, depth and others.
14823 @endblock
14824
14825 @property
14826 gravity
14827 @parameters
14828 [x-axis] [y-axis] [z-axis]
14829 @effect
14830 Three double values defining the gravity vector.
14831 Each one is the component of this same vector over each axis.
14832 Its unit is Evas Coordinates per second ^ 2.
14833 The default value is 0, 294, 0, since we've a default rate of
14834 30 pixels.
14835 @since 1.8
14836 @endproperty
14837 */
14838 #ifdef HAVE_EPHYSICS
14839 static void
st_collections_group_physics_world_gravity(void)14840 st_collections_group_physics_world_gravity(void)
14841 {
14842 Edje_Part_Collection *pc;
14843
14844 pc = eina_list_data_get(eina_list_last(edje_collections));
14845 check_arg_count(3);
14846
14847 pc->physics.world.gravity.x = parse_int(0);
14848 pc->physics.world.gravity.y = parse_int(1);
14849 pc->physics.world.gravity.z = parse_int(2);
14850 }
14851
14852 #endif
14853
14854 /**
14855 @page edcref
14856 @property
14857 rate
14858 @parameters
14859 [rate pixels / meter]
14860 @effect
14861 Set rate between pixels on evas canvas and meters on physics world.
14862 It will be used by automatic updates of evas objects associated to
14863 physics bodies.
14864 By default rate is 30 pixels per meter.
14865 @since 1.8
14866 @endproperty
14867 */
14868 #ifdef HAVE_EPHYSICS
14869 static void
st_collections_group_physics_world_rate(void)14870 st_collections_group_physics_world_rate(void)
14871 {
14872 Edje_Part_Collection *pc;
14873
14874 pc = eina_list_data_get(eina_list_last(edje_collections));
14875 check_arg_count(1);
14876
14877 pc->physics.world.rate = parse_float(0);
14878 }
14879
14880 #endif
14881
14882 /**
14883 @page edcref
14884 @property
14885 depth
14886 @parameters
14887 [depth in pixels]
14888 @effect
14889 World's depth, in pixels. It's only relevant if boundaries are used,
14890 since their size depends on this.
14891 By default world's depth is 100 pixels.
14892 @since 1.8
14893 @endproperty
14894 */
14895 #ifdef HAVE_EPHYSICS
14896 static void
st_collections_group_physics_world_depth(void)14897 st_collections_group_physics_world_depth(void)
14898 {
14899 Edje_Part_Collection *pc;
14900
14901 pc = eina_list_data_get(eina_list_last(edje_collections));
14902 check_arg_count(1);
14903
14904 pc->physics.world.depth = parse_int(0);
14905 }
14906
14907 #endif
14908
14909 /**
14910 @page edcref
14911 @property
14912 z
14913 @parameters
14914 [world's front border position]
14915 @effect
14916 Position in z axis, in pixels.
14917 It's only relevant if boundaries are used, since their position
14918 depends on this.
14919 By default world's z is -50 pixels.
14920 @since 1.8
14921 @endproperty
14922 */
14923 #ifdef HAVE_EPHYSICS
14924 static void
st_collections_group_physics_world_z(void)14925 st_collections_group_physics_world_z(void)
14926 {
14927 Edje_Part_Collection *pc;
14928
14929 pc = eina_list_data_get(eina_list_last(edje_collections));
14930 check_arg_count(1);
14931
14932 pc->physics.world.z = parse_int(0);
14933 }
14934
14935 #endif
14936
14937 /**
14938 @page edcref
14939 </table>
14940 */
14941
14942 void
edje_cc_handlers_pop_notify(const char * token)14943 edje_cc_handlers_pop_notify(const char *token)
14944 {
14945 if (sequencing && (!strcmp(token, "sequence")))
14946 {
14947 current_program = sequencing;
14948 ((Edje_Program_Parser *)sequencing)->can_override = EINA_TRUE;
14949 eina_list_free(current_program_lookups);
14950 current_program_lookups = sequencing_lookups;
14951 sequencing_lookups = NULL;
14952 sequencing = NULL;
14953 }
14954 else if (current_program && (!strcmp(token, "link")))
14955 current_program = NULL;
14956 else if (current_de && (!strcmp(token, "group")))
14957 {
14958 _link_combine();
14959 _script_flush();
14960 }
14961 else if (current_desc && (!strcmp(token, "description")))
14962 free_anchors();
14963 }
14964
14965 static void
edje_cc_handlers_hierarchy_set(Edje_Part * src)14966 edje_cc_handlers_hierarchy_set(Edje_Part *src)
14967 { /* This funcion makes current part rel_1.id, rel_2.id relative to src */
14968 if (!src->name)
14969 {
14970 ERR("parse error %s:%i. You must set parent name before creating nested part",
14971 file_in, line - 1);
14972 exit(-1);
14973 }
14974 st_collections_group_parts_part_description_rel1_to_set(src->name);
14975 st_collections_group_parts_part_description_rel2_to_set(src->name);
14976 }
14977
14978 static Edje_Part *
edje_cc_handlers_hierarchy_parent_get(void)14979 edje_cc_handlers_hierarchy_parent_get(void)
14980 { /* Return the parent part pointer */
14981 int idx = eina_array_count(part_hierarchy) - 2;
14982 Edje_Cc_Handlers_Hierarchy_Info *info = (idx >= 0) ?
14983 eina_array_data_get(part_hierarchy, idx) : NULL;
14984
14985 return (info) ? info->ep : NULL;
14986 }
14987
14988 static void
edje_cc_handlers_hierarchy_push(Edje_Part * ep,Edje_Part * cp)14989 edje_cc_handlers_hierarchy_push(Edje_Part *ep, Edje_Part *cp)
14990 { /* Remove part from hierarchy stack when finished parsing it */
14991 Edje_Cc_Handlers_Hierarchy_Info *info = malloc(sizeof(*info));
14992 info->current_de = current_de;
14993 info->current_part = cp; /* current_part restored on pop */
14994 info->current_item = current_item;
14995 info->current_desc = current_desc;
14996 info->parent_desc = parent_desc;
14997 info->current_program = current_program;
14998 info->ep = ep;
14999
15000 eina_array_push(part_hierarchy, info);
15001 }
15002
15003 static void
edje_cc_handlers_hierarchy_rename(Edje_Part * old,Edje_Part * new)15004 edje_cc_handlers_hierarchy_rename(Edje_Part *old, Edje_Part *new)
15005 {
15006 Edje_Cc_Handlers_Hierarchy_Info *item;
15007 Eina_Array_Iterator iterator;
15008 unsigned int i;
15009
15010 EINA_ARRAY_ITER_NEXT(part_hierarchy, i, item, iterator)
15011 {
15012 if (item->ep == old) item->ep = new;
15013 if (item->current_part == old) item->current_part = new;
15014 }
15015 }
15016
15017 void
edje_cc_handlers_hierarchy_alloc(void)15018 edje_cc_handlers_hierarchy_alloc(void)
15019 {
15020 part_hierarchy = eina_array_new(8);
15021 }
15022
15023 void
edje_cc_handlers_hierarchy_free(void)15024 edje_cc_handlers_hierarchy_free(void)
15025 {
15026 eina_array_free(part_hierarchy);
15027 part_hierarchy = NULL;
15028 }
15029
15030 static void
edje_cc_handlers_hierarchy_pop(void)15031 edje_cc_handlers_hierarchy_pop(void)
15032 { /* Remove part from hierarchy stack when finished parsing it */
15033 Edje_Cc_Handlers_Hierarchy_Info *info = eina_array_pop(part_hierarchy);
15034
15035 if (current_part)
15036 {
15037 unsigned int i;
15038
15039 if (!current_part->name)
15040 {
15041 WRN("Parse error near %s:%i. Unnamed part exists in Group \"%s\".",
15042 file_in, line - 1, current_de->entry);
15043 }
15044
15045 for (i = 0; i < current_part->other.desc_count; i++)
15046 {
15047 if (!current_part->other.desc[i]->state.name)
15048 {
15049 ERR("syntax error near %s:%i. Non-default or inherited parts are required to have state names for all descriptions (Group '%s', part '%s' has missing description state names)",
15050 file_in, line - 1, current_de->entry, current_part->name);
15051 exit(-1);
15052 }
15053 }
15054
15055 /* auto-add default desc if it was omitted */
15056 if (!current_part->default_desc)
15057 ob_collections_group_parts_part_description();
15058 }
15059
15060 if (info)
15061 {
15062 current_de = info->current_de;
15063 current_part = info->current_part;
15064 current_item = info->current_item;
15065 current_desc = info->current_desc;
15066 parent_desc = info->parent_desc;
15067 current_program = info->current_program;
15068
15069 free(info);
15070 }
15071 }
15072
15073 Eina_Bool
edje_cc_handlers_wildcard(void)15074 edje_cc_handlers_wildcard(void)
15075 {
15076 char *token, *last;
15077
15078 token = eina_list_last_data_get(stack);
15079 last = eina_list_data_get(eina_list_prev(eina_list_last(stack)));
15080 if (!last) return EINA_FALSE;
15081 if (last)
15082 {
15083 char *end;
15084
15085 end = strrchr(last, '.');
15086 if (end) last = end + 1;
15087 }
15088 if (current_part)
15089 {
15090 if ((!strcmp(last, "part")) && (!current_part->name))
15091 {
15092 Eina_Bool ret;
15093
15094 if (!had_quote) return EINA_FALSE;
15095 current_part->name = token;
15096 ret = _part_name_check();
15097 if (ret)
15098 stack_pop_quick(EINA_FALSE, EINA_FALSE);
15099 return ret;
15100 }
15101 if (current_desc && ((!strcmp(last, "desc")) || (!strcmp(last, "description"))))
15102 {
15103 double st;
15104 char *end;
15105
15106 if (had_quote)
15107 {
15108 if ((!current_desc->state.name) || strcmp(current_desc->state.name, token))
15109 {
15110 free((char *)current_desc->state.name);
15111 current_desc->state.name = token;
15112 _part_description_state_update(current_desc);
15113 }
15114 stack_pop_quick(EINA_FALSE, current_desc->state.name != token);
15115 return EINA_TRUE;
15116 }
15117
15118 if (!isdigit(token[0])) return EINA_FALSE;
15119 st = strtod(token, &end);
15120 if ((end && end[0]) || (fabs(current_desc->state.value) > DBL_EPSILON))
15121 return EINA_FALSE;
15122 if (current_desc == current_part->default_desc)
15123 {
15124 ob_collections_group_parts_part_description();
15125 current_desc->state.name = strdup("default");
15126 }
15127 else
15128 {
15129 unsigned int j;
15130
15131 for (j = 0; j < current_part->other.desc_count; j++)
15132 {
15133 /* check for inherited descriptions */
15134 Edje_Part_Description_Common *ed = current_part->other.desc[j];
15135
15136 if (((!!ed->state.name) != (!!current_desc->state.name)) ||
15137 (ed->state.name && strcmp(ed->state.name, current_desc->state.name)) ||
15138 (!EINA_DBL_EQ(ed->state.value, st))) continue;
15139 current_desc = ed;
15140 break;
15141 }
15142 /* not found */
15143 if (j == current_part->other.desc_count)
15144 {
15145 void *name = NULL;
15146
15147 if (current_desc->state.name)
15148 name = strdup(current_desc->state.name);
15149 ob_collections_group_parts_part_description();
15150 current_desc->state.name = name;
15151 }
15152 }
15153 current_desc->state.value = st;
15154 stack_pop_quick(EINA_FALSE, EINA_TRUE);
15155 return EINA_TRUE;
15156 }
15157 }
15158 if (current_program && ((!strcmp(last, "program")) || (!strcmp(last, "sequence"))))
15159 {
15160 if (!had_quote) return EINA_FALSE;
15161 _program_sequence_check();
15162 _program_name(token);
15163 stack_pop_quick(EINA_FALSE, EINA_FALSE);
15164 return EINA_TRUE;
15165 }
15166 if (current_de && (!strcmp(last, "group")))
15167 {
15168 if (!had_quote) return EINA_FALSE;
15169 _group_name(token);
15170 stack_pop_quick(EINA_FALSE, EINA_FALSE);
15171 return EINA_TRUE;
15172 }
15173 if (edje_file->styles && (!strcmp(last, "style")))
15174 {
15175 if (!had_quote) return EINA_FALSE;
15176 _style_name(token);
15177 stack_pop_quick(EINA_FALSE, EINA_FALSE);
15178 return EINA_TRUE;
15179 }
15180 if (edje_file->color_classes && (!strcmp(last, "color_class")))
15181 {
15182 if (!had_quote) return EINA_FALSE;
15183 _color_class_name(token);
15184 stack_pop_quick(EINA_FALSE, EINA_FALSE);
15185 return EINA_TRUE;
15186 }
15187 if (edje_file->text_classes && (!strcmp(last, "text_class")))
15188 {
15189 if (!had_quote) return EINA_FALSE;
15190 _text_class_name(token);
15191 stack_pop_quick(EINA_FALSE, EINA_FALSE);
15192 return EINA_TRUE;
15193 }
15194 if (edje_file->size_classes && (!strcmp(last, "size_class")))
15195 {
15196 if (!had_quote) return EINA_FALSE;
15197 _size_class_name(token);
15198 stack_pop_quick(EINA_FALSE, EINA_FALSE);
15199 return EINA_TRUE;
15200 }
15201 return EINA_FALSE;
15202 }
15203
15204