b3d2bcbd134566ad75850c9faf263609c4b7fccc
[framework/uifw/edje.git] / src / bin / edje_cc_handlers.c
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     \@endblock
17
18     \@property
19         property name
20     \@parameters
21         property's parameter list
22     \@effect
23         the property description (lol)
24     \@endproperty
25 */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <string.h>
32 #include <errno.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35 #include <sys/mman.h>
36 #include <unistd.h>
37
38 #include "edje_cc.h"
39
40 /**
41  * @page edcref Edje Data Collection reference
42  * An Edje Data Collection, it's a plain text file (normally identified with the
43  * .edc extension), consisting of instructions for the Edje Compiler.
44  *
45  * The syntax for the edje data collection files follows a simple structure of
46  * "blocks { .. }" that can contain "properties: ..", more blocks, or both.
47  *
48  * @anchor sec_quickaccess Quick access to block descriptions:
49  * <ul>
50  *    <li>@ref sec_toplevel "Top-Level"</li>
51  *    <li>@ref sec_group "Group"</li>
52  *    <li>@ref sec_description "State description"</li>
53  *    <ul>
54  *      <li>@ref sec_description_image "Image"</li>
55  *      <li>@ref sec_description_text "Text"</li>
56  *      <li>@ref sec_description_box "Box"</li>
57  *      <li>@ref sec_description_table "Table"</li>
58  *      <li>@ref sec_description_map "Map (3d/transformations)"</li>
59  *    </ul>
60  *    <li>@ref sec_program "Program block"</li>
61  * </ul>
62  *
63  * @author Andres Blanc (dresb) andresblanc@gmail.com
64  *
65  * <table class="edcref" border="0">
66  */
67
68 static Edje_Part_Collection_Directory_Entry *current_de = NULL;
69 static Edje_Part *current_part = NULL;
70 static Edje_Pack_Element *current_item = NULL;
71 static Edje_Part_Description_Common *current_desc = NULL;
72 static Edje_Part_Description_Common *parent_desc = NULL;
73 static Edje_Program *current_program = NULL;
74
75 struct _Edje_Cc_Handlers_Hierarchy_Info
76 {  /* Struct that keeps globals value to impl hierarchy */
77    Edje_Part_Collection_Directory_Entry *current_de;
78    Edje_Part *current_part;
79    Edje_Pack_Element *current_item;
80    Edje_Part_Description_Common *current_desc;
81    Edje_Part_Description_Common *parent_desc;
82    Edje_Program *current_program;
83    Edje_Part *ep;
84 };
85 typedef struct _Edje_Cc_Handlers_Hierarchy_Info Edje_Cc_Handlers_Hierarchy_Info;
86
87 static Eina_Array *part_hierarchy = NULL; /* stack parts,support nested parts */
88 static void edje_cc_handlers_hierarchy_set(Edje_Part *src);
89 static Edje_Part *edje_cc_handlers_hierarchy_parent_get(void);
90 static void edje_cc_handlers_hierarchy_push(Edje_Part *ep, Edje_Part *cp);
91 static void edje_cc_handlers_hierarchy_rename(Edje_Part *old, Edje_Part *new);
92 static void edje_cc_handlers_hierarchy_pop(void);
93
94 static void st_externals_external(void);
95
96 static void st_images_image(void);
97 static void ob_images_set(void);
98 static void st_images_set_name(void);
99 static void ob_images_set_image(void);
100 static void st_images_set_image_image(void);
101 static void st_images_set_image_size(void);
102
103 static void st_fonts_font(void);
104
105 static void st_data_item(void);
106 static void st_data_file(void);
107
108 static void ob_styles_style(void);
109 static void st_styles_style_name(void);
110 static void st_styles_style_base(void);
111 static void st_styles_style_tag(void);
112
113 static void ob_color_class(void);
114 static void st_color_class_name(void);
115 static void st_color_class_color(void);
116 static void st_color_class_color2(void);
117 static void st_color_class_color3(void);
118
119 static void ob_collections(void);
120
121 static void ob_collections_group(void);
122 static void st_collections_group_name(void);
123 static void st_collections_group_inherit(void);
124 static void st_collections_group_script_only(void);
125 static void st_collections_group_alias(void);
126 static void st_collections_group_min(void);
127 static void st_collections_group_max(void);
128 static void st_collections_group_broadcast_signal(void);
129 static void st_collections_group_data_item(void);
130 static void st_collections_group_orientation(void);
131
132 static void st_collections_group_limits_vertical(void);
133 static void st_collections_group_limits_horizontal(void);
134
135 static void ob_collections_group_script(void);
136 static void ob_collections_group_lua_script(void);
137
138 static void st_collections_group_parts_alias(void);
139
140 static Edje_Part *edje_cc_handlers_part_make(void);
141 static void ob_collections_group_parts_part(void);
142 static void st_collections_group_parts_part_name(void);
143 static void st_collections_group_parts_part_type(void);
144 static void st_collections_group_parts_part_insert_before(void);
145 static void st_collections_group_parts_part_insert_after(void);
146 static void st_collections_group_parts_part_effect(void);
147 static void st_collections_group_parts_part_mouse_events(void);
148 static void st_collections_group_parts_part_repeat_events(void);
149 static void st_collections_group_parts_part_ignore_flags(void);
150 static void st_collections_group_parts_part_scale(void);
151 static void st_collections_group_parts_part_pointer_mode(void);
152 static void st_collections_group_parts_part_precise_is_inside(void);
153 static void st_collections_group_parts_part_use_alternate_font_metrics(void);
154 static void st_collections_group_parts_part_clip_to_id(void);
155 static void st_collections_group_parts_part_source(void);
156 static void st_collections_group_parts_part_source2(void);
157 static void st_collections_group_parts_part_source3(void);
158 static void st_collections_group_parts_part_source4(void);
159 static void st_collections_group_parts_part_source5(void);
160 static void st_collections_group_parts_part_source6(void);
161 static void st_collections_group_parts_part_entry_mode(void);
162 static void st_collections_group_parts_part_select_mode(void);
163 static void st_collections_group_parts_part_cursor_mode(void);
164 static void st_collections_group_parts_part_multiline(void);
165 static void st_collections_group_parts_part_access(void);
166 static void st_collections_group_parts_part_dragable_x(void);
167 static void st_collections_group_parts_part_dragable_y(void);
168 static void st_collections_group_parts_part_dragable_confine(void);
169 static void st_collections_group_parts_part_dragable_events(void);
170
171 /* box and table items share these */
172 static void ob_collections_group_parts_part_box_items_item(void);
173 static void st_collections_group_parts_part_box_items_item_type(void);
174 static void st_collections_group_parts_part_box_items_item_name(void);
175 static void st_collections_group_parts_part_box_items_item_source(void);
176 static void st_collections_group_parts_part_box_items_item_min(void);
177 static void st_collections_group_parts_part_box_items_item_prefer(void);
178 static void st_collections_group_parts_part_box_items_item_max(void);
179 static void st_collections_group_parts_part_box_items_item_padding(void);
180 static void st_collections_group_parts_part_box_items_item_align(void);
181 static void st_collections_group_parts_part_box_items_item_weight(void);
182 static void st_collections_group_parts_part_box_items_item_aspect(void);
183 static void st_collections_group_parts_part_box_items_item_aspect_mode(void);
184 static void st_collections_group_parts_part_box_items_item_options(void);
185 /* but these are only for table */
186 static void st_collections_group_parts_part_table_items_item_position(void);
187 static void st_collections_group_parts_part_table_items_item_span(void);
188
189 static void ob_collections_group_parts_part_description(void);
190 static void st_collections_group_parts_part_description_inherit(void);
191 static void st_collections_group_parts_part_description_source(void);
192 static void st_collections_group_parts_part_description_state(void);
193 static void st_collections_group_parts_part_description_visible(void);
194 static void st_collections_group_parts_part_description_limit(void);
195 static void st_collections_group_parts_part_description_align(void);
196 static void st_collections_group_parts_part_description_fixed(void);
197 static void st_collections_group_parts_part_description_min(void);
198 static void st_collections_group_parts_part_description_minmul(void);
199 static void st_collections_group_parts_part_description_max(void);
200 static void st_collections_group_parts_part_description_step(void);
201 static void st_collections_group_parts_part_description_aspect(void);
202 static void st_collections_group_parts_part_description_aspect_preference(void);
203 static void st_collections_group_parts_part_description_rel1_relative(void);
204 static void st_collections_group_parts_part_description_rel1_offset(void);
205 static void st_collections_group_parts_part_description_rel1_to_set(const char *name);
206 static void st_collections_group_parts_part_description_rel1_to(void);
207 static void st_collections_group_parts_part_description_rel1_to_x(void);
208 static void st_collections_group_parts_part_description_rel1_to_y(void);
209 static void st_collections_group_parts_part_description_rel2_relative(void);
210 static void st_collections_group_parts_part_description_rel2_offset(void);
211 static void st_collections_group_parts_part_description_rel2_to_set(const char *name);
212 static void st_collections_group_parts_part_description_rel2_to(void);
213 static void st_collections_group_parts_part_description_rel2_to_x(void);
214 static void st_collections_group_parts_part_description_rel2_to_y(void);
215 static void st_collections_group_parts_part_description_image_normal(void);
216 static void st_collections_group_parts_part_description_image_tween(void);
217 static void st_collections_group_parts_part_description_image_border(void);
218 static void st_collections_group_parts_part_description_image_middle(void);
219 static void st_collections_group_parts_part_description_image_border_scale(void);
220 static void st_collections_group_parts_part_description_image_border_scale_by(void);
221 static void st_collections_group_parts_part_description_image_scale_hint(void);
222 static void st_collections_group_parts_part_description_fill_smooth(void);
223 static void st_collections_group_parts_part_description_fill_origin_relative(void);
224 static void st_collections_group_parts_part_description_fill_origin_offset(void);
225 static void st_collections_group_parts_part_description_fill_size_relative(void);
226 static void st_collections_group_parts_part_description_fill_size_offset(void);
227 static void st_collections_group_parts_part_description_fill_spread(void);
228 static void st_collections_group_parts_part_description_fill_type(void);
229 static void st_collections_group_parts_part_description_color_class(void);
230 static void st_collections_group_parts_part_description_color(void);
231 static void st_collections_group_parts_part_description_color2(void);
232 static void st_collections_group_parts_part_description_color3(void);
233 static void st_collections_group_parts_part_description_text_text(void);
234 static void st_collections_group_parts_part_description_text_text_class(void);
235 static void st_collections_group_parts_part_description_text_font(void);
236 static void st_collections_group_parts_part_description_text_style(void);
237 static void st_collections_group_parts_part_description_text_repch(void);
238 static void st_collections_group_parts_part_description_text_size(void);
239 static void st_collections_group_parts_part_description_text_size_range(void);
240 static void st_collections_group_parts_part_description_text_fit(void);
241 static void st_collections_group_parts_part_description_text_min(void);
242 static void st_collections_group_parts_part_description_text_max(void);
243 static void st_collections_group_parts_part_description_text_align(void);
244 static void st_collections_group_parts_part_description_text_source(void);
245 static void st_collections_group_parts_part_description_text_text_source(void);
246 static void st_collections_group_parts_part_description_text_elipsis(void);
247 static void st_collections_group_parts_part_description_box_layout(void);
248 static void st_collections_group_parts_part_description_box_align(void);
249 static void st_collections_group_parts_part_description_box_padding(void);
250 static void st_collections_group_parts_part_description_box_min(void);
251 static void st_collections_group_parts_part_description_table_homogeneous(void);
252 static void st_collections_group_parts_part_description_table_align(void);
253 static void st_collections_group_parts_part_description_table_padding(void);
254 static void st_collections_group_parts_part_description_table_min(void);
255 static void st_collections_group_parts_part_description_map_perspective(void);
256 static void st_collections_group_parts_part_description_map_light(void);
257 static void st_collections_group_parts_part_description_map_rotation_center(void);
258 static void st_collections_group_parts_part_description_map_rotation_x(void);
259 static void st_collections_group_parts_part_description_map_rotation_y(void);
260 static void st_collections_group_parts_part_description_map_rotation_z(void);
261 static void st_collections_group_parts_part_description_map_on(void);
262 static void st_collections_group_parts_part_description_map_smooth(void);
263 static void st_collections_group_parts_part_description_map_alpha(void);
264 static void st_collections_group_parts_part_description_map_backface_cull(void);
265 static void st_collections_group_parts_part_description_map_perspective_on(void);
266 static void st_collections_group_parts_part_description_perspective_zplane(void);
267 static void st_collections_group_parts_part_description_perspective_focal(void);
268 static void st_collections_group_parts_part_api(void);
269
270 /* external part parameters */
271 static void st_collections_group_parts_part_description_params_int(void);
272 static void ob_collections_group_programs_program(void);
273 static void st_collections_group_parts_part_description_params_double(void);
274
275 static void st_collections_group_programs_program_name(void);
276 static void st_collections_group_parts_part_description_params_string(void);
277 static void st_collections_group_parts_part_description_params_bool(void);
278 static void st_collections_group_parts_part_description_params_choice(void);
279 static void st_collections_group_programs_program_signal(void);
280 static void st_collections_group_programs_program_source(void);
281 static void st_collections_group_programs_program_filter(void);
282 static void st_collections_group_programs_program_in(void);
283 static void st_collections_group_programs_program_action(void);
284 static void st_collections_group_programs_program_transition(void);
285 static void st_collections_group_programs_program_target(void);
286 static void st_collections_group_programs_program_after(void);
287 static void st_collections_group_programs_program_api(void);
288
289 static void ob_collections_group_programs_program_script(void);
290
291 static void st_collections_group_sound_sample_name(void);
292 static void st_collections_group_sound_sample_source(void);
293 static void st_collections_group_sound_tone(void);
294 /*****/
295
296 New_Statement_Handler statement_handlers[] =
297 {
298      {"externals.external", st_externals_external},
299      {"images.image", st_images_image},
300      {"images.set.name", st_images_set_name},
301      {"images.set.image.image", st_images_set_image_image},
302      {"images.set.image.size", st_images_set_image_size},
303      {"fonts.font", st_fonts_font},
304      {"data.item", st_data_item},
305      {"data.file", st_data_file},
306      {"styles.style.name", st_styles_style_name},
307      {"styles.style.base", st_styles_style_base},
308      {"styles.style.tag", st_styles_style_tag},
309      {"color_classes.color_class.name", st_color_class_name},
310      {"color_classes.color_class.color", st_color_class_color},
311      {"color_classes.color_class.color2", st_color_class_color2},
312      {"color_classes.color_class.color3", st_color_class_color3},
313      {"collections.externals.external", st_externals_external}, /* dup */
314      {"collections.image", st_images_image}, /* dup */
315      {"collections.set.name", st_images_set_name}, /* dup */
316      {"collections.set.image.image", st_images_set_image_image}, /* dup */
317      {"collections.set.image.size", st_images_set_image_size}, /* dup */
318      {"collections.images.image", st_images_image}, /* dup */
319      {"collections.images.set.name", st_images_set_name}, /* dup */
320      {"collections.images.set.image.image", st_images_set_image_image}, /* dup */
321      {"collections.images.set.image.size", st_images_set_image_size}, /* dup */
322      {"collections.font", st_fonts_font}, /* dup */
323      {"collections.fonts.font", st_fonts_font}, /* dup */
324      {"collections.styles.style.name", st_styles_style_name}, /* dup */
325      {"collections.styles.style.base", st_styles_style_base}, /* dup */
326      {"collections.styles.style.tag", st_styles_style_tag}, /* dup */
327      {"collections.color_classes.color_class.name", st_color_class_name}, /* dup */
328      {"collections.color_classes.color_class.color", st_color_class_color}, /* dup */
329      {"collections.color_classes.color_class.color2", st_color_class_color2}, /* dup */
330      {"collections.color_classes.color_class.color3", st_color_class_color3}, /* dup */
331      {"collections.sounds.sample.name", st_collections_group_sound_sample_name},
332      {"collections.sounds.sample.source", st_collections_group_sound_sample_source},
333      {"collections.group.sounds.sample.name", st_collections_group_sound_sample_name}, /* dup */
334      {"collections.group.sounds.sample.source", st_collections_group_sound_sample_source}, /* dup */
335      {"collections.sounds.tone", st_collections_group_sound_tone},
336      {"collections.group.sounds.tone", st_collections_group_sound_tone}, /* dup */
337      {"collections.group.name", st_collections_group_name},
338      {"collections.group.inherit", st_collections_group_inherit},
339      {"collections.group.script_only", st_collections_group_script_only},
340      {"collections.group.lua_script_only", st_collections_group_script_only},
341      {"collections.group.alias", st_collections_group_alias},
342      {"collections.group.min", st_collections_group_min},
343      {"collections.group.max", st_collections_group_max},
344      {"collections.group.broadcast_signal", st_collections_group_broadcast_signal},
345      {"collections.group.orientation", st_collections_group_orientation},
346      {"collections.group.data.item", st_collections_group_data_item},
347      {"collections.group.limits.horizontal", st_collections_group_limits_horizontal},
348      {"collections.group.limits.vertical", st_collections_group_limits_vertical},
349      {"collections.group.externals.external", st_externals_external}, /* dup */
350      {"collections.group.image", st_images_image}, /* dup */
351      {"collections.group.set.name", st_images_set_name},
352      {"collections.group.set.image.image", st_images_set_image_image},
353      {"collections.group.set.image.size", st_images_set_image_size},
354      {"collections.group.images.image", st_images_image}, /* dup */
355      {"collections.group.images.set.name", st_images_set_name},
356      {"collections.group.images.set.image.image", st_images_set_image_image},
357      {"collections.group.images.set.image.size", st_images_set_image_size},
358      {"collections.group.font", st_fonts_font}, /* dup */
359      {"collections.group.fonts.font", st_fonts_font}, /* dup */
360      {"collections.group.styles.style.name", st_styles_style_name}, /* dup */
361      {"collections.group.styles.style.base", st_styles_style_base}, /* dup */
362      {"collections.group.styles.style.tag", st_styles_style_tag}, /* dup */
363      {"collections.group.color_classes.color_class.name", st_color_class_name}, /* dup */
364      {"collections.group.color_classes.color_class.color", st_color_class_color}, /* dup */
365      {"collections.group.color_classes.color_class.color2", st_color_class_color2}, /* dup */
366      {"collections.group.color_classes.color_class.color3", st_color_class_color3}, /* dup */
367      {"collections.group.parts.alias", st_collections_group_parts_alias },
368      {"collections.group.parts.image", st_images_image}, /* dup */
369      {"collections.group.parts.set.name", st_images_set_name},
370      {"collections.group.parts.set.image.image", st_images_set_image_image},
371      {"collections.group.parts.set.image.size", st_images_set_image_size},
372      {"collections.group.parts.images.image", st_images_image}, /* dup */
373      {"collections.group.parts.images.set.name", st_images_set_name},
374      {"collections.group.parts.images.set.image.image", st_images_set_image_image},
375      {"collections.group.parts.images.set.image.size", st_images_set_image_size},
376      {"collections.group.parts.font", st_fonts_font}, /* dup */
377      {"collections.group.parts.fonts.font", st_fonts_font}, /* dup */
378      {"collections.group.parts.styles.style.name", st_styles_style_name}, /* dup */
379      {"collections.group.parts.styles.style.base", st_styles_style_base}, /* dup */
380      {"collections.group.parts.styles.style.tag", st_styles_style_tag}, /* dup */
381      {"collections.group.parts.color_classes.color_class.name", st_color_class_name}, /* dup */
382      {"collections.group.parts.color_classes.color_class.color", st_color_class_color}, /* dup */
383      {"collections.group.parts.color_classes.color_class.color2", st_color_class_color2}, /* dup */
384      {"collections.group.parts.color_classes.color_class.color3", st_color_class_color3}, /* dup */
385      {"collections.group.parts.part.name", st_collections_group_parts_part_name},
386      {"collections.group.parts.part.api", st_collections_group_parts_part_api},
387      {"collections.group.parts.part.type", st_collections_group_parts_part_type},
388      {"collections.group.parts.part.insert_before", st_collections_group_parts_part_insert_before},
389      {"collections.group.parts.part.insert_after", st_collections_group_parts_part_insert_after},
390      {"collections.group.parts.part.effect", st_collections_group_parts_part_effect},
391      {"collections.group.parts.part.mouse_events", st_collections_group_parts_part_mouse_events},
392      {"collections.group.parts.part.repeat_events", st_collections_group_parts_part_repeat_events},
393      {"collections.group.parts.part.ignore_flags", st_collections_group_parts_part_ignore_flags},
394      {"collections.group.parts.part.scale", st_collections_group_parts_part_scale},
395      {"collections.group.parts.part.pointer_mode", st_collections_group_parts_part_pointer_mode},
396      {"collections.group.parts.part.precise_is_inside", st_collections_group_parts_part_precise_is_inside},
397      {"collections.group.parts.part.use_alternate_font_metrics", st_collections_group_parts_part_use_alternate_font_metrics},
398      {"collections.group.parts.part.clip_to", st_collections_group_parts_part_clip_to_id},
399      {"collections.group.parts.part.source", st_collections_group_parts_part_source},
400      {"collections.group.parts.part.source2", st_collections_group_parts_part_source2},
401      {"collections.group.parts.part.source3", st_collections_group_parts_part_source3},
402      {"collections.group.parts.part.source4", st_collections_group_parts_part_source4},
403      {"collections.group.parts.part.source5", st_collections_group_parts_part_source5},
404      {"collections.group.parts.part.source6", st_collections_group_parts_part_source6},
405      {"collections.group.parts.part.dragable.x", st_collections_group_parts_part_dragable_x},
406      {"collections.group.parts.part.dragable.y", st_collections_group_parts_part_dragable_y},
407      {"collections.group.parts.part.dragable.confine", st_collections_group_parts_part_dragable_confine},
408      {"collections.group.parts.part.dragable.events", st_collections_group_parts_part_dragable_events},
409      {"collections.group.parts.part.entry_mode", st_collections_group_parts_part_entry_mode},
410      {"collections.group.parts.part.select_mode", st_collections_group_parts_part_select_mode},
411      {"collections.group.parts.part.cursor_mode", st_collections_group_parts_part_cursor_mode},
412      {"collections.group.parts.part.multiline", st_collections_group_parts_part_multiline},
413      {"collections.group.parts.part.access", st_collections_group_parts_part_access},
414      {"collections.group.parts.part.image", st_images_image}, /* dup */
415      {"collections.group.parts.part.set.name", st_images_set_name},
416      {"collections.group.parts.part.set.image.image", st_images_set_image_image},
417      {"collections.group.parts.part.set.image.size", st_images_set_image_size},
418      {"collections.group.parts.part.images.image", st_images_image}, /* dup */
419      {"collections.group.parts.part.images.set.name", st_images_set_name},
420      {"collections.group.parts.part.images.set.image.image", st_images_set_image_image},
421      {"collections.group.parts.part.images.set.image.size", st_images_set_image_size},
422      {"collections.group.parts.part.font", st_fonts_font}, /* dup */
423      {"collections.group.parts.part.fonts.font", st_fonts_font}, /* dup */
424      {"collections.group.parts.part.styles.style.name", st_styles_style_name}, /* dup */
425      {"collections.group.parts.part.styles.style.base", st_styles_style_base}, /* dup */
426      {"collections.group.parts.part.styles.style.tag", st_styles_style_tag}, /* dup */
427      {"collections.group.parts.part.color_classes.color_class.name", st_color_class_name}, /* dup */
428      {"collections.group.parts.part.color_classes.color_class.color", st_color_class_color}, /* dup */
429      {"collections.group.parts.part.color_classes.color_class.color2", st_color_class_color2}, /* dup */
430      {"collections.group.parts.part.color_classes.color_class.color3", st_color_class_color3}, /* dup */
431      {"collections.group.parts.part.box.items.item.type", st_collections_group_parts_part_box_items_item_type},
432      {"collections.group.parts.part.box.items.item.name", st_collections_group_parts_part_box_items_item_name},
433      {"collections.group.parts.part.box.items.item.source", st_collections_group_parts_part_box_items_item_source},
434      {"collections.group.parts.part.box.items.item.min", st_collections_group_parts_part_box_items_item_min},
435      {"collections.group.parts.part.box.items.item.prefer", st_collections_group_parts_part_box_items_item_prefer},
436      {"collections.group.parts.part.box.items.item.max", st_collections_group_parts_part_box_items_item_max},
437      {"collections.group.parts.part.box.items.item.padding", st_collections_group_parts_part_box_items_item_padding},
438      {"collections.group.parts.part.box.items.item.align", st_collections_group_parts_part_box_items_item_align},
439      {"collections.group.parts.part.box.items.item.weight", st_collections_group_parts_part_box_items_item_weight},
440      {"collections.group.parts.part.box.items.item.aspect", st_collections_group_parts_part_box_items_item_aspect},
441      {"collections.group.parts.part.box.items.item.aspect_mode", st_collections_group_parts_part_box_items_item_aspect_mode},
442      {"collections.group.parts.part.box.items.item.options", st_collections_group_parts_part_box_items_item_options},
443      {"collections.group.parts.part.table.items.item.type", st_collections_group_parts_part_box_items_item_type}, /* dup */
444      {"collections.group.parts.part.table.items.item.name", st_collections_group_parts_part_box_items_item_name}, /* dup */
445      {"collections.group.parts.part.table.items.item.source", st_collections_group_parts_part_box_items_item_source}, /* dup */
446      {"collections.group.parts.part.table.items.item.min", st_collections_group_parts_part_box_items_item_min}, /* dup */
447      {"collections.group.parts.part.table.items.item.prefer", st_collections_group_parts_part_box_items_item_prefer}, /* dup */
448      {"collections.group.parts.part.table.items.item.max", st_collections_group_parts_part_box_items_item_max}, /* dup */
449      {"collections.group.parts.part.table.items.item.padding", st_collections_group_parts_part_box_items_item_padding}, /* dup */
450      {"collections.group.parts.part.table.items.item.align", st_collections_group_parts_part_box_items_item_align}, /* dup */
451      {"collections.group.parts.part.table.items.item.weight", st_collections_group_parts_part_box_items_item_weight}, /* dup */
452      {"collections.group.parts.part.table.items.item.aspect", st_collections_group_parts_part_box_items_item_aspect}, /* dup */
453      {"collections.group.parts.part.table.items.item.aspect_mode", st_collections_group_parts_part_box_items_item_aspect_mode}, /* dup */
454      {"collections.group.parts.part.table.items.item.options", st_collections_group_parts_part_box_items_item_options}, /* dup */
455      {"collections.group.parts.part.table.items.item.position", st_collections_group_parts_part_table_items_item_position},
456      {"collections.group.parts.part.table.items.item.span", st_collections_group_parts_part_table_items_item_span},
457      {"collections.group.parts.part.description.inherit", st_collections_group_parts_part_description_inherit},
458      {"collections.group.parts.part.description.source", st_collections_group_parts_part_description_source},
459      {"collections.group.parts.part.description.state", st_collections_group_parts_part_description_state},
460      {"collections.group.parts.part.description.visible", st_collections_group_parts_part_description_visible},
461      {"collections.group.parts.part.description.limit", st_collections_group_parts_part_description_limit},
462      {"collections.group.parts.part.description.align", st_collections_group_parts_part_description_align},
463      {"collections.group.parts.part.description.fixed", st_collections_group_parts_part_description_fixed},
464      {"collections.group.parts.part.description.min", st_collections_group_parts_part_description_min},
465      {"collections.group.parts.part.description.minmul", st_collections_group_parts_part_description_minmul},
466      {"collections.group.parts.part.description.max", st_collections_group_parts_part_description_max},
467      {"collections.group.parts.part.description.step", st_collections_group_parts_part_description_step},
468      {"collections.group.parts.part.description.aspect", st_collections_group_parts_part_description_aspect},
469      {"collections.group.parts.part.description.aspect_preference", st_collections_group_parts_part_description_aspect_preference},
470      {"collections.group.parts.part.description.rel1.relative", st_collections_group_parts_part_description_rel1_relative},
471      {"collections.group.parts.part.description.rel1.offset", st_collections_group_parts_part_description_rel1_offset},
472      {"collections.group.parts.part.description.rel1.to", st_collections_group_parts_part_description_rel1_to},
473      {"collections.group.parts.part.description.rel1.to_x", st_collections_group_parts_part_description_rel1_to_x},
474      {"collections.group.parts.part.description.rel1.to_y", st_collections_group_parts_part_description_rel1_to_y},
475      {"collections.group.parts.part.description.rel2.relative", st_collections_group_parts_part_description_rel2_relative},
476      {"collections.group.parts.part.description.rel2.offset", st_collections_group_parts_part_description_rel2_offset},
477      {"collections.group.parts.part.description.rel2.to", st_collections_group_parts_part_description_rel2_to},
478      {"collections.group.parts.part.description.rel2.to_x", st_collections_group_parts_part_description_rel2_to_x},
479      {"collections.group.parts.part.description.rel2.to_y", st_collections_group_parts_part_description_rel2_to_y},
480      {"collections.group.parts.part.description.image.normal", st_collections_group_parts_part_description_image_normal},
481      {"collections.group.parts.part.description.image.tween", st_collections_group_parts_part_description_image_tween},
482      {"collections.group.parts.part.description.image.image", st_images_image}, /* dup */
483      {"collections.group.parts.part.description.image.set.name", st_images_set_name},
484      {"collections.group.parts.part.description.image.set.image.image", st_images_set_image_image},
485      {"collections.group.parts.part.description.image.set.image.size", st_images_set_image_size},
486      {"collections.group.parts.part.description.image.images.image", st_images_image}, /* dup */
487      {"collections.group.parts.part.description.image.images.set.name", st_images_set_name},
488      {"collections.group.parts.part.description.image.images.set.image.image", st_images_set_image_image},
489      {"collections.group.parts.part.description.image.images.set.image.size", st_images_set_image_size},
490      {"collections.group.parts.part.description.image.border", st_collections_group_parts_part_description_image_border},
491      {"collections.group.parts.part.description.image.middle", st_collections_group_parts_part_description_image_middle},
492      {"collections.group.parts.part.description.image.border_scale", st_collections_group_parts_part_description_image_border_scale},
493      {"collections.group.parts.part.description.image.border_scale_by", st_collections_group_parts_part_description_image_border_scale_by},
494      {"collections.group.parts.part.description.image.scale_hint", st_collections_group_parts_part_description_image_scale_hint},
495      {"collections.group.parts.part.description.fill.smooth", st_collections_group_parts_part_description_fill_smooth},
496      {"collections.group.parts.part.description.fill.origin.relative", st_collections_group_parts_part_description_fill_origin_relative},
497      {"collections.group.parts.part.description.fill.origin.offset", st_collections_group_parts_part_description_fill_origin_offset},
498      {"collections.group.parts.part.description.fill.size.relative", st_collections_group_parts_part_description_fill_size_relative},
499      {"collections.group.parts.part.description.fill.size.offset", st_collections_group_parts_part_description_fill_size_offset},
500      {"collections.group.parts.part.description.fill.spread", st_collections_group_parts_part_description_fill_spread},
501      {"collections.group.parts.part.description.fill.type", st_collections_group_parts_part_description_fill_type},
502      {"collections.group.parts.part.description.color_class", st_collections_group_parts_part_description_color_class},
503      {"collections.group.parts.part.description.color", st_collections_group_parts_part_description_color},
504      {"collections.group.parts.part.description.color2", st_collections_group_parts_part_description_color2},
505      {"collections.group.parts.part.description.color3", st_collections_group_parts_part_description_color3},
506      {"collections.group.parts.part.description.text.text", st_collections_group_parts_part_description_text_text},
507      {"collections.group.parts.part.description.text.text_class", st_collections_group_parts_part_description_text_text_class},
508      {"collections.group.parts.part.description.text.font", st_collections_group_parts_part_description_text_font},
509      {"collections.group.parts.part.description.text.style", st_collections_group_parts_part_description_text_style},
510      {"collections.group.parts.part.description.text.repch", st_collections_group_parts_part_description_text_repch},
511      {"collections.group.parts.part.description.text.size", st_collections_group_parts_part_description_text_size},
512      {"collections.group.parts.part.description.text.size_range", st_collections_group_parts_part_description_text_size_range},
513      {"collections.group.parts.part.description.text.fit", st_collections_group_parts_part_description_text_fit},
514      {"collections.group.parts.part.description.text.min", st_collections_group_parts_part_description_text_min},
515      {"collections.group.parts.part.description.text.max", st_collections_group_parts_part_description_text_max},
516      {"collections.group.parts.part.description.text.align", st_collections_group_parts_part_description_text_align},
517      {"collections.group.parts.part.description.text.source", st_collections_group_parts_part_description_text_source},
518      {"collections.group.parts.part.description.text.text_source", st_collections_group_parts_part_description_text_text_source},
519      {"collections.group.parts.part.description.text.font", st_fonts_font}, /* dup */
520      {"collections.group.parts.part.description.text.fonts.font", st_fonts_font}, /* dup */
521      {"collections.group.parts.part.description.text.elipsis", st_collections_group_parts_part_description_text_elipsis},
522      {"collections.group.parts.part.description.text.ellipsis", st_collections_group_parts_part_description_text_elipsis},
523      {"collections.group.parts.part.description.box.layout", st_collections_group_parts_part_description_box_layout},
524      {"collections.group.parts.part.description.box.align", st_collections_group_parts_part_description_box_align},
525      {"collections.group.parts.part.description.box.padding", st_collections_group_parts_part_description_box_padding},
526      {"collections.group.parts.part.description.box.min", st_collections_group_parts_part_description_box_min},
527      {"collections.group.parts.part.description.table.homogeneous", st_collections_group_parts_part_description_table_homogeneous},
528      {"collections.group.parts.part.description.table.align", st_collections_group_parts_part_description_table_align},
529      {"collections.group.parts.part.description.table.padding", st_collections_group_parts_part_description_table_padding},
530      {"collections.group.parts.part.description.table.min", st_collections_group_parts_part_description_table_min},
531      {"collections.group.parts.part.description.map.perspective", st_collections_group_parts_part_description_map_perspective},
532      {"collections.group.parts.part.description.map.light", st_collections_group_parts_part_description_map_light},
533      {"collections.group.parts.part.description.map.rotation.center", st_collections_group_parts_part_description_map_rotation_center},
534      {"collections.group.parts.part.description.map.rotation.x", st_collections_group_parts_part_description_map_rotation_x},
535      {"collections.group.parts.part.description.map.rotation.y", st_collections_group_parts_part_description_map_rotation_y},
536      {"collections.group.parts.part.description.map.rotation.z", st_collections_group_parts_part_description_map_rotation_z},
537      {"collections.group.parts.part.description.map.on", st_collections_group_parts_part_description_map_on},
538      {"collections.group.parts.part.description.map.smooth", st_collections_group_parts_part_description_map_smooth},
539      {"collections.group.parts.part.description.map.alpha", st_collections_group_parts_part_description_map_alpha},
540      {"collections.group.parts.part.description.map.backface_cull", st_collections_group_parts_part_description_map_backface_cull},
541      {"collections.group.parts.part.description.map.perspective_on", st_collections_group_parts_part_description_map_perspective_on},
542      {"collections.group.parts.part.description.perspective.zplane", st_collections_group_parts_part_description_perspective_zplane},
543      {"collections.group.parts.part.description.perspective.focal", st_collections_group_parts_part_description_perspective_focal},
544      {"collections.group.parts.part.description.params.int", st_collections_group_parts_part_description_params_int},
545      {"collections.group.parts.part.description.params.double", st_collections_group_parts_part_description_params_double},
546      {"collections.group.parts.part.description.params.string", st_collections_group_parts_part_description_params_string},
547      {"collections.group.parts.part.description.params.bool", st_collections_group_parts_part_description_params_bool},
548      {"collections.group.parts.part.description.params.choice", st_collections_group_parts_part_description_params_choice},
549      {"collections.group.parts.part.description.images.image", st_images_image}, /* dup */
550      {"collections.group.parts.part.description.images.set.name", st_images_set_name},
551      {"collections.group.parts.part.description.images.set.image.image", st_images_set_image_image},
552      {"collections.group.parts.part.description.images.set.image.size", st_images_set_image_size},
553      {"collections.group.parts.part.description.font", st_fonts_font}, /* dup */
554      {"collections.group.parts.part.description.fonts.font", st_fonts_font}, /* dup */
555      {"collections.group.parts.part.description.styles.style.name", st_styles_style_name}, /* dup */
556      {"collections.group.parts.part.description.styles.style.base", st_styles_style_base}, /* dup */
557      {"collections.group.parts.part.description.styles.style.tag", st_styles_style_tag}, /* dup */
558      {"collections.group.parts.part.description.color_classes.color_class.name", st_color_class_name}, /* dup */
559      {"collections.group.parts.part.description.color_classes.color_class.color", st_color_class_color}, /* dup */
560      {"collections.group.parts.part.description.color_classes.color_class.color2", st_color_class_color2}, /* dup */
561      {"collections.group.parts.part.description.color_classes.color_class.color3", st_color_class_color3}, /* dup */
562      {"collections.group.parts.part.description.programs.image", st_images_image}, /* dup */
563      {"collections.group.parts.part.description.programs.set.name", st_images_set_name},
564      {"collections.group.parts.part.description.programs.set.image.image", st_images_set_image_image},
565      {"collections.group.parts.part.description.programs.set.image.size", st_images_set_image_size},
566      {"collections.group.parts.part.description.programs.images.image", st_images_image}, /* dup */
567      {"collections.group.parts.part.description.programs.images.set.name", st_images_set_name},
568      {"collections.group.parts.part.description.programs.images.set.image.image", st_images_set_image_image},
569      {"collections.group.parts.part.description.programs.images.set.image.size", st_images_set_image_size},
570      {"collections.group.parts.part.description.programs.font", st_fonts_font}, /* dup */
571      {"collections.group.parts.part.description.programs.fonts.font", st_fonts_font}, /* dup */
572      {"collections.group.parts.part.description.programs.program.name", st_collections_group_programs_program_name}, /* dup */
573      {"collections.group.parts.part.description.programs.program.signal", st_collections_group_programs_program_signal}, /* dup */
574      {"collections.group.parts.part.description.programs.program.source", st_collections_group_programs_program_source}, /* dup */
575      {"collections.group.parts.part.description.programs.program.in", st_collections_group_programs_program_in}, /* dup */
576      {"collections.group.parts.part.description.programs.program.action", st_collections_group_programs_program_action}, /* dup */
577      {"collections.group.parts.part.description.programs.program.transition", st_collections_group_programs_program_transition}, /* dup */
578      {"collections.group.parts.part.description.programs.program.target", st_collections_group_programs_program_target}, /* dup */
579      {"collections.group.parts.part.description.programs.program.after", st_collections_group_programs_program_after}, /* dup */
580      {"collections.group.parts.part.description.programs.program.api", st_collections_group_programs_program_api}, /* dup */
581      {"collections.group.parts.part.description.program.name", st_collections_group_programs_program_name}, /* dup */
582      {"collections.group.parts.part.description.program.signal", st_collections_group_programs_program_signal}, /* dup */
583      {"collections.group.parts.part.description.program.source", st_collections_group_programs_program_source}, /* dup */
584      {"collections.group.parts.part.description.program.in", st_collections_group_programs_program_in}, /* dup */
585      {"collections.group.parts.part.description.program.action", st_collections_group_programs_program_action}, /* dup */
586      {"collections.group.parts.part.description.program.transition", st_collections_group_programs_program_transition}, /* dup */
587      {"collections.group.parts.part.description.program.target", st_collections_group_programs_program_target}, /* dup */
588      {"collections.group.parts.part.description.program.after", st_collections_group_programs_program_after}, /* dup */
589      {"collections.group.parts.part.description.program.api", st_collections_group_programs_program_api}, /* dup */
590      {"collections.group.parts.part.programs.image", st_images_image}, /* dup */
591      {"collections.group.parts.part.programs.set.name", st_images_set_name},
592      {"collections.group.parts.part.programs.set.image.image", st_images_set_image_image},
593      {"collections.group.parts.part.programs.set.image.size", st_images_set_image_size},
594      {"collections.group.parts.part.programs.images.image", st_images_image}, /* dup */
595      {"collections.group.parts.part.programs.images.set.name", st_images_set_name},
596      {"collections.group.parts.part.programs.images.set.image.image", st_images_set_image_image},
597      {"collections.group.parts.part.programs.images.set.image.size", st_images_set_image_size},
598      {"collections.group.parts.part.programs.font", st_fonts_font}, /* dup */
599      {"collections.group.parts.part.programs.fonts.font", st_fonts_font}, /* dup */
600      {"collections.group.parts.part.programs.program.name", st_collections_group_programs_program_name}, /* dup */
601      {"collections.group.parts.part.programs.program.signal", st_collections_group_programs_program_signal}, /* dup */
602      {"collections.group.parts.part.programs.program.source", st_collections_group_programs_program_source}, /* dup */
603      {"collections.group.parts.part.programs.program.in", st_collections_group_programs_program_in}, /* dup */
604      {"collections.group.parts.part.programs.program.action", st_collections_group_programs_program_action}, /* dup */
605      {"collections.group.parts.part.programs.program.transition", st_collections_group_programs_program_transition}, /* dup */
606      {"collections.group.parts.part.programs.program.target", st_collections_group_programs_program_target}, /* dup */
607      {"collections.group.parts.part.programs.program.after", st_collections_group_programs_program_after}, /* dup */
608      {"collections.group.parts.part.programs.program.api", st_collections_group_programs_program_api}, /* dup */
609      {"collections.group.parts.part.program.name", st_collections_group_programs_program_name}, /* dup */
610      {"collections.group.parts.part.program.signal", st_collections_group_programs_program_signal}, /* dup */
611      {"collections.group.parts.part.program.source", st_collections_group_programs_program_source}, /* dup */
612      {"collections.group.parts.part.program.in", st_collections_group_programs_program_in}, /* dup */
613      {"collections.group.parts.part.program.action", st_collections_group_programs_program_action}, /* dup */
614      {"collections.group.parts.part.program.transition", st_collections_group_programs_program_transition}, /* dup */
615      {"collections.group.parts.part.program.target", st_collections_group_programs_program_target}, /* dup */
616      {"collections.group.parts.part.program.after", st_collections_group_programs_program_after}, /* dup */
617      {"collections.group.parts.part.program.api", st_collections_group_programs_program_api}, /* dup */
618      {"collections.group.parts.programs.image", st_images_image}, /* dup */
619      {"collections.group.parts.programs.set.name", st_images_set_name},
620      {"collections.group.parts.programs.set.image.image", st_images_set_image_image},
621      {"collections.group.parts.programs.set.image.size", st_images_set_image_size},
622      {"collections.group.parts.programs.images.image", st_images_image}, /* dup */
623      {"collections.group.parts.programs.images.set.name", st_images_set_name},
624      {"collections.group.parts.programs.images.set.image.image", st_images_set_image_image},
625      {"collections.group.parts.programs.images.set.image.size", st_images_set_image_size},
626      {"collections.group.parts.programs.font", st_fonts_font}, /* dup */
627      {"collections.group.parts.programs.fonts.font", st_fonts_font}, /* dup */
628      {"collections.group.parts.programs.program.name", st_collections_group_programs_program_name}, /* dup */
629      {"collections.group.parts.programs.program.signal", st_collections_group_programs_program_signal}, /* dup */
630      {"collections.group.parts.programs.program.source", st_collections_group_programs_program_source}, /* dup */
631      {"collections.group.parts.programs.program.filter", st_collections_group_programs_program_filter}, /* dup */
632      {"collections.group.parts.programs.program.in", st_collections_group_programs_program_in}, /* dup */
633      {"collections.group.parts.programs.program.action", st_collections_group_programs_program_action}, /* dup */
634      {"collections.group.parts.programs.program.transition", st_collections_group_programs_program_transition}, /* dup */
635      {"collections.group.parts.programs.program.target", st_collections_group_programs_program_target}, /* dup */
636      {"collections.group.parts.programs.program.after", st_collections_group_programs_program_after},
637      {"collections.group.parts.programs.program.api", st_collections_group_programs_program_api},
638      {"collections.group.parts.program.name", st_collections_group_programs_program_name}, /* dup */
639      {"collections.group.parts.program.signal", st_collections_group_programs_program_signal}, /* dup */
640      {"collections.group.parts.program.source", st_collections_group_programs_program_source}, /* dup */
641      {"collections.group.parts.program.filter", st_collections_group_programs_program_filter}, /* dup */
642      {"collections.group.parts.program.in", st_collections_group_programs_program_in}, /* dup */
643      {"collections.group.parts.program.action", st_collections_group_programs_program_action}, /* dup */
644      {"collections.group.parts.program.transition", st_collections_group_programs_program_transition}, /* dup */
645      {"collections.group.parts.program.target", st_collections_group_programs_program_target}, /* dup */
646      {"collections.group.parts.program.after", st_collections_group_programs_program_after}, /* dup */
647      {"collections.group.parts.program.api", st_collections_group_programs_program_api}, /* dup */
648      {"collections.group.program.name", st_collections_group_programs_program_name}, /* dup */
649      {"collections.group.program.signal", st_collections_group_programs_program_signal}, /* dup */
650      {"collections.group.program.source", st_collections_group_programs_program_source}, /* dup */
651      {"collections.group.program.filter", st_collections_group_programs_program_filter}, /* dup */
652      {"collections.group.program.in", st_collections_group_programs_program_in}, /* dup */
653      {"collections.group.program.action", st_collections_group_programs_program_action}, /* dup */
654      {"collections.group.program.transition", st_collections_group_programs_program_transition}, /* dup */
655      {"collections.group.program.target", st_collections_group_programs_program_target}, /* dup */
656      {"collections.group.program.after", st_collections_group_programs_program_after}, /* dup */
657      {"collections.group.program.api", st_collections_group_programs_program_api}, /* dup */
658      {"collections.group.programs.program.name", st_collections_group_programs_program_name},
659      {"collections.group.programs.program.signal", st_collections_group_programs_program_signal},
660      {"collections.group.programs.program.source", st_collections_group_programs_program_source},
661      {"collections.group.programs.program.filter", st_collections_group_programs_program_filter}, /* dup */
662      {"collections.group.programs.program.in", st_collections_group_programs_program_in},
663      {"collections.group.programs.program.action", st_collections_group_programs_program_action},
664      {"collections.group.programs.program.transition", st_collections_group_programs_program_transition},
665      {"collections.group.programs.program.target", st_collections_group_programs_program_target},
666      {"collections.group.programs.program.after", st_collections_group_programs_program_after},
667      {"collections.group.programs.program.api", st_collections_group_programs_program_api},
668      {"collections.group.programs.image", st_images_image}, /* dup */
669      {"collections.group.programs.set.name", st_images_set_name},
670      {"collections.group.programs.set.image.image", st_images_set_image_image},
671      {"collections.group.programs.set.image.size", st_images_set_image_size},
672      {"collections.group.programs.images.image", st_images_image}, /* dup */
673      {"collections.group.programs.images.set.name", st_images_set_name},
674      {"collections.group.programs.images.set.image.image", st_images_set_image_image},
675      {"collections.group.programs.images.set.image.size", st_images_set_image_size},
676      {"collections.group.programs.font", st_fonts_font}, /* dup */
677      {"collections.group.programs.fonts.font", st_fonts_font} /* dup */
678 };
679
680 New_Object_Handler object_handlers[] =
681 {
682      {"externals", NULL},
683      {"images", NULL},
684      {"images.set", ob_images_set},
685      {"images.set.image", ob_images_set_image},
686      {"fonts", NULL},
687      {"data", NULL},
688      {"styles", NULL},
689      {"styles.style", ob_styles_style},
690      {"color_classes", NULL},
691      {"color_classes.color_class", ob_color_class},
692      {"spectra", NULL},
693      {"collections", ob_collections},
694      {"collections.externals", NULL}, /* dup */
695      {"collections.set", ob_images_set}, /* dup */
696      {"collections.set.image", ob_images_set_image}, /* dup */
697      {"collections.images", NULL}, /* dup */
698      {"collections.images.set", ob_images_set}, /* dup */
699      {"collections.images.set.image", ob_images_set_image}, /* dup */
700      {"collections.fonts", NULL}, /* dup */
701      {"collections.styles", NULL}, /* dup */
702      {"collections.styles.style", ob_styles_style}, /* dup */
703      {"collections.color_classes", NULL}, /* dup */
704      {"collections.color_classes.color_class", ob_color_class}, /* dup */
705      {"collections.sounds", NULL},
706      {"collections.group.sounds", NULL}, /* dup */
707      {"collections.sounds.sample", NULL},
708      {"collections.group.sounds.sample", NULL}, /* dup */
709      {"collections.group", ob_collections_group},
710      {"collections.group.data", NULL},
711      {"collections.group.limits", NULL},
712      {"collections.group.script", ob_collections_group_script},
713      {"collections.group.lua_script", ob_collections_group_lua_script},
714      {"collections.group.externals", NULL}, /* dup */
715      {"collections.group.set", ob_images_set}, /* dup */
716      {"collections.group.set.image", ob_images_set_image}, /* dup */
717      {"collections.group.images", NULL}, /* dup */
718      {"collections.group.images.set", ob_images_set}, /* dup */
719      {"collections.group.images.set.image", ob_images_set_image}, /* dup */
720      {"collections.group.fonts", NULL}, /* dup */
721      {"collections.group.styles", NULL}, /* dup */
722      {"collections.group.styles.style", ob_styles_style}, /* dup */
723      {"collections.group.color_classes", NULL}, /* dup */
724      {"collections.group.color_classes.color_class", ob_color_class}, /* dup */
725      {"collections.group.parts", NULL},
726      {"collections.group.parts.set", ob_images_set}, /* dup */
727      {"collections.group.parts.set.image", ob_images_set_image}, /* dup */
728      {"collections.group.parts.images", NULL}, /* dup */
729      {"collections.group.parts.images.set", ob_images_set}, /* dup */
730      {"collections.group.parts.images.set.image", ob_images_set_image}, /* dup */
731      {"collections.group.parts.fonts", NULL}, /* dup */
732      {"collections.group.parts.styles", NULL}, /* dup */
733      {"collections.group.parts.styles.style", ob_styles_style}, /* dup */
734      {"collections.group.parts.color_classes", NULL}, /* dup */
735      {"collections.group.parts.color_classes.color_class", ob_color_class}, /* dup */
736      {"collections.group.parts.part", ob_collections_group_parts_part},
737      {"collections.group.parts.part.dragable", NULL},
738      {"collections.group.parts.part.set", ob_images_set}, /* dup */
739      {"collections.group.parts.part.set.image", ob_images_set_image}, /* dup */
740      {"collections.group.parts.part.images", NULL}, /* dup */
741      {"collections.group.parts.part.images.set", ob_images_set}, /* dup */
742      {"collections.group.parts.part.images.set.image", ob_images_set_image}, /* dup */
743      {"collections.group.parts.part.fonts", NULL}, /* dup */
744      {"collections.group.parts.part.styles", NULL}, /* dup */
745      {"collections.group.parts.part.styles.style", ob_styles_style}, /* dup */
746      {"collections.group.parts.part.color_classes", NULL}, /* dup */
747      {"collections.group.parts.part.color_classes.color_class", ob_color_class}, /* dup */
748      {"collections.group.parts.part.box", NULL},
749      {"collections.group.parts.part.box.items", NULL},
750      {"collections.group.parts.part.box.items.item", ob_collections_group_parts_part_box_items_item},
751      {"collections.group.parts.part.table", NULL},
752      {"collections.group.parts.part.table.items", NULL},
753      {"collections.group.parts.part.table.items.item", ob_collections_group_parts_part_box_items_item}, /* dup */
754      {"collections.group.parts.part.description", ob_collections_group_parts_part_description},
755      {"collections.group.parts.part.description.rel1", NULL},
756      {"collections.group.parts.part.description.rel2", NULL},
757      {"collections.group.parts.part.description.image", NULL}, /* dup */
758      {"collections.group.parts.part.description.image.set", ob_images_set}, /* dup */
759      {"collections.group.parts.part.description.image.set.image", ob_images_set_image}, /* dup */
760      {"collections.group.parts.part.description.image.images", NULL}, /* dup */
761      {"collections.group.parts.part.description.image.images.set", ob_images_set}, /* dup */
762      {"collections.group.parts.part.description.image.images.set.image", ob_images_set_image}, /* dup */
763      {"collections.group.parts.part.description.fill", NULL},
764      {"collections.group.parts.part.description.fill.origin", NULL},
765      {"collections.group.parts.part.description.fill.size", NULL},
766      {"collections.group.parts.part.description.text", NULL},
767      {"collections.group.parts.part.description.text.fonts", NULL}, /* dup */
768      {"collections.group.parts.part.description.images", NULL}, /* dup */
769      {"collections.group.parts.part.description.images.set", ob_images_set}, /* dup */
770      {"collections.group.parts.part.description.images.set.image", ob_images_set_image}, /* dup */
771      {"collections.group.parts.part.description.fonts", NULL}, /* dup */
772      {"collections.group.parts.part.description.styles", NULL}, /* dup */
773      {"collections.group.parts.part.description.styles.style", ob_styles_style}, /* dup */
774      {"collections.group.parts.part.description.box", NULL},
775      {"collections.group.parts.part.description.table", NULL},
776      {"collections.group.parts.part.description.map", NULL},
777      {"collections.group.parts.part.description.map.rotation", NULL},
778      {"collections.group.parts.part.description.perspective", NULL},
779      {"collections.group.parts.part.description.params", NULL},
780      {"collections.group.parts.part.description.color_classes", NULL}, /* dup */
781      {"collections.group.parts.part.description.color_classes.color_class", ob_color_class}, /* dup */
782      {"collections.group.parts.part.description.program", ob_collections_group_programs_program}, /* dup */
783      {"collections.group.parts.part.description.program.script", ob_collections_group_programs_program_script}, /* dup */
784      {"collections.group.parts.part.description.programs", NULL}, /* dup */
785      {"collections.group.parts.part.description.programs.set", ob_images_set}, /* dup */
786      {"collections.group.parts.part.description.programs.set.image", ob_images_set_image}, /* dup */
787      {"collections.group.parts.part.description.programs.images", NULL}, /* dup */
788      {"collections.group.parts.part.description.programs.images.set", ob_images_set},
789      {"collections.group.parts.part.description.programs.images.set.image", ob_images_set_image}, /* dup */
790      {"collections.group.parts.part.description.programs.fonts", NULL}, /* dup */
791      {"collections.group.parts.part.description.programs.program", ob_collections_group_programs_program}, /* dup */
792      {"collections.group.parts.part.description.programs.program.script", ob_collections_group_programs_program_script}, /* dup */
793      {"collections.group.parts.part.description.script", ob_collections_group_script}, /* dup */
794      {"collections.group.parts.part.program", ob_collections_group_programs_program}, /* dup */
795      {"collections.group.parts.part.program.script", ob_collections_group_programs_program_script}, /* dup */
796      {"collections.group.parts.part.programs", NULL}, /* dup */
797      {"collections.group.parts.part.programs.set", ob_images_set}, /* dup */
798      {"collections.group.parts.part.programs.set.image", ob_images_set_image}, /* dup */
799      {"collections.group.parts.part.programs.images", NULL}, /* dup */
800      {"collections.group.parts.part.programs.images.set", ob_images_set}, /* dup */
801      {"collections.group.parts.part.programs.images.set.image", ob_images_set_image}, /* dup */
802      {"collections.group.parts.part.programs.fonts", NULL}, /* dup */
803      {"collections.group.parts.part.programs.program", ob_collections_group_programs_program}, /* dup */
804      {"collections.group.parts.part.programs.program.script", ob_collections_group_programs_program_script}, /* dup */
805      {"collections.group.parts.part.script", ob_collections_group_script}, /* dup */
806      {"collections.group.parts.program", ob_collections_group_programs_program}, /* dup */
807      {"collections.group.parts.program.script", ob_collections_group_programs_program_script}, /* dup */
808      {"collections.group.parts.programs", NULL}, /* dup */
809      {"collections.group.parts.programs.set", ob_images_set}, /* dup */
810      {"collections.group.parts.programs.set.image", ob_images_set_image}, /* dup */
811      {"collections.group.parts.programs.images", NULL}, /* dup */
812      {"collections.group.parts.programs.images.set", ob_images_set}, /* dup */
813      {"collections.group.parts.programs.images.set.image", ob_images_set_image}, /* dup */
814      {"collections.group.parts.programs.fonts", NULL}, /* dup */
815      {"collections.group.parts.programs.program", ob_collections_group_programs_program}, /* dup */
816      {"collections.group.parts.programs.program.script", ob_collections_group_programs_program_script}, /* dup */
817      {"collections.group.parts.script", ob_collections_group_script}, /* dup */
818      {"collections.group.program", ob_collections_group_programs_program}, /* dup */
819      {"collections.group.program.script", ob_collections_group_programs_program_script}, /* dup */
820      {"collections.group.programs", NULL},
821      {"collections.group.programs.set", ob_images_set}, /* dup */
822      {"collections.group.programs.set.image", ob_images_set_image}, /* dup */
823      {"collections.group.programs.images", NULL}, /* dup */
824      {"collections.group.programs.images.set", ob_images_set}, /* dup */
825      {"collections.group.programs.images.set.image", ob_images_set_image}, /* dup */
826      {"collections.group.programs.fonts", NULL}, /* dup */
827      {"collections.group.programs.program", ob_collections_group_programs_program},
828      {"collections.group.programs.program.script", ob_collections_group_programs_program_script},
829      {"collections.group.programs.script", ob_collections_group_script} /* dup */
830 };
831
832 New_Nested_Handler nested_handlers[] = {
833      {"collections.group.parts", "part", NULL, edje_cc_handlers_hierarchy_pop }
834 };
835
836 /*****/
837
838 int
839 object_handler_num(void)
840 {
841    return sizeof(object_handlers) / sizeof (New_Object_Handler);
842 }
843
844 int
845 statement_handler_num(void)
846 {
847    return sizeof(statement_handlers) / sizeof (New_Object_Handler);
848 }
849
850 int
851 nested_handler_num(void)
852 {
853    return sizeof(nested_handlers) / sizeof (New_Nested_Handler);
854 }
855
856 static void
857 _edje_part_description_fill(Edje_Part_Description_Spec_Fill *fill)
858 {
859    fill->smooth = 1;
860    fill->pos_rel_x = FROM_DOUBLE(0.0);
861    fill->pos_abs_x = 0;
862    fill->rel_x = FROM_DOUBLE(1.0);
863    fill->abs_x = 0;
864    fill->pos_rel_y = FROM_DOUBLE(0.0);
865    fill->pos_abs_y = 0;
866    fill->rel_y = FROM_DOUBLE(1.0);
867    fill->abs_y = 0;
868    fill->angle = 0;
869    fill->spread = 0;
870    fill->type = EDJE_FILL_TYPE_SCALE;
871 }
872
873 static void
874 _edje_part_description_image_remove(Edje_Part_Description_Image *ed)
875 {
876    unsigned int j;
877
878    if (!ed) return;
879
880    data_queue_image_remove(&(ed->image.id), &(ed->image.set));
881
882    for (j = 0; j < ed->image.tweens_count; ++j)
883      data_queue_image_remove(&(ed->image.tweens[j]->id),
884                              &(ed->image.tweens[j]->set));
885 }
886
887 void
888 part_description_image_cleanup(Edje_Part *ep)
889 {
890    Edje_Part_Description_Image *ed;
891    unsigned int j;
892
893    if (ep->type != EDJE_PART_TYPE_IMAGE)
894      return ;
895
896    ed = (Edje_Part_Description_Image*) ep->default_desc;
897    _edje_part_description_image_remove(ed);
898
899    for (j = 0; j < ep->other.desc_count; j++)
900      {
901         ed = (Edje_Part_Description_Image*) ep->other.desc[j];
902         _edje_part_description_image_remove(ed);
903      }
904 }
905
906 static Edje_Part_Description_Common *
907 _edje_part_description_alloc(unsigned char type, const char *collection, const char *part)
908 {
909    Edje_Part_Description_Common *result = NULL;
910
911    switch (type)
912      {
913       case EDJE_PART_TYPE_SPACER:
914       case EDJE_PART_TYPE_RECTANGLE:
915       case EDJE_PART_TYPE_SWALLOW:
916       case EDJE_PART_TYPE_GROUP:
917          result = mem_alloc(SZ(Edje_Part_Description_Common));
918          break;
919       case EDJE_PART_TYPE_TEXT:
920       case EDJE_PART_TYPE_TEXTBLOCK:
921         {
922            Edje_Part_Description_Text *ed;
923
924            ed = mem_alloc(SZ(Edje_Part_Description_Text));
925
926            ed->text.color3.r = 0;
927            ed->text.color3.g = 0;
928            ed->text.color3.b = 0;
929            ed->text.color3.a = 128;
930            ed->text.align.x = FROM_DOUBLE(0.5);
931            ed->text.align.y = FROM_DOUBLE(0.5);
932            ed->text.id_source = -1;
933            ed->text.id_text_source = -1;
934
935            result = &ed->common;
936            break;
937         }
938       case EDJE_PART_TYPE_IMAGE:
939         {
940            Edje_Part_Description_Image *ed;
941
942            ed = mem_alloc(SZ(Edje_Part_Description_Image));
943
944            ed->image.id = -1;
945
946            _edje_part_description_fill(&ed->image.fill);
947
948            result = &ed->common;
949            break;
950         }
951       case EDJE_PART_TYPE_PROXY:
952         {
953            Edje_Part_Description_Proxy *ed;
954
955            ed = mem_alloc(SZ(Edje_Part_Description_Proxy));
956
957            ed->proxy.id = -1;
958
959            _edje_part_description_fill(&ed->proxy.fill);
960
961            result = &ed->common;
962            break;
963         }
964       case EDJE_PART_TYPE_BOX:
965         {
966            Edje_Part_Description_Box *ed;
967
968            ed = mem_alloc(SZ(Edje_Part_Description_Box));
969
970            ed->box.layout = NULL;
971            ed->box.alt_layout = NULL;
972            ed->box.align.x = FROM_DOUBLE(0.5);
973            ed->box.align.y = FROM_DOUBLE(0.5);
974            ed->box.padding.x = 0;
975            ed->box.padding.y = 0;
976
977            result = &ed->common;
978            break;
979         }
980       case EDJE_PART_TYPE_TABLE:
981         {
982            Edje_Part_Description_Table *ed;
983
984            ed = mem_alloc(SZ(Edje_Part_Description_Table));
985
986            ed->table.homogeneous = EDJE_OBJECT_TABLE_HOMOGENEOUS_NONE;
987            ed->table.align.x = FROM_DOUBLE(0.5);
988            ed->table.align.y = FROM_DOUBLE(0.5);
989            ed->table.padding.x = 0;
990            ed->table.padding.y = 0;
991
992            result = &ed->common;
993            break;
994         }
995       case EDJE_PART_TYPE_EXTERNAL:
996         {
997            Edje_Part_Description_External *ed;
998
999            ed = mem_alloc(SZ(Edje_Part_Description_External));
1000
1001            ed->external_params = NULL;
1002
1003            result = &ed->common;
1004            break;
1005         }
1006      }
1007
1008    if (!result)
1009      {
1010         ERR("Unknown type %i of part %s in collection %s.",
1011             type, part, collection);
1012         exit(-1);
1013      }
1014
1015    return result;
1016 }
1017
1018 static void
1019 _edje_program_check(const char *name, Edje_Program *me, Edje_Program **pgrms, unsigned int count)
1020 {
1021    Edje_Part_Collection *pc;
1022    unsigned int i;
1023    Edje_Program_Parser *epp;
1024
1025    pc = eina_list_data_get(eina_list_last(edje_collections));
1026
1027    for (i = 0; i < count; ++i)
1028      if (pgrms[i]->name)
1029        if (pgrms[i] != me && (!strcmp(name, pgrms[i]->name)))
1030          {
1031             epp = (Edje_Program_Parser *)pgrms[i];
1032             if (!epp->can_override)
1033               {
1034                  ERR("parse error %s:%i. There is already a program of the name %s",
1035                      file_in, line - 1, name);
1036                  exit(-1);
1037               }
1038             else
1039               {
1040                  _edje_program_remove(pc, me);
1041                  current_program = pgrms[i];
1042                  epp->can_override = EINA_FALSE;
1043                  return;
1044               }
1045          }
1046 }
1047
1048 static void
1049 _edje_program_copy(Edje_Program *ep, Edje_Program *ep2)
1050 {
1051    Edje_Part_Collection *pc;
1052    Edje_Program_Target *et, *et2;
1053    Edje_Program_After *pa, *pa2;
1054    Edje_Program_Parser *epp;
1055    Eina_List *l;
1056    char *name;
1057    char *copy;
1058
1059    pc = eina_list_data_get(eina_list_last(edje_collections));
1060
1061    #define STRDUP(x) x ? strdup(x) : NULL
1062    ep->name = STRDUP(ep2->name);
1063
1064    _edje_program_remove(pc, current_program);
1065    ep->signal = STRDUP(ep2->signal);
1066    ep->source = STRDUP(ep2->source);
1067    _edje_program_insert(pc, current_program);
1068
1069    ep->filter.part = STRDUP(ep2->filter.part);
1070    ep->filter.state = STRDUP(ep2->filter.state);
1071    ep->in.from = ep2->in.from;
1072    ep->in.range = ep2->in.range;
1073    ep->action = ep2->action;
1074    ep->state = STRDUP(ep2->state);
1075    ep->state2 = STRDUP(ep2->state2);
1076    ep->value = ep2->value;
1077    ep->value2 = ep2->value2;
1078    ep->tween.mode = ep2->tween.mode;
1079    ep->tween.time = ep2->tween.time;
1080    ep->tween.v1 = ep2->tween.v1;
1081    ep->tween.v2 = ep2->tween.v2;
1082    ep->sample_name = STRDUP(ep2->sample_name);
1083    ep->tone_name = STRDUP(ep2->tone_name);
1084    ep->duration = ep2->duration;
1085    ep->speed = ep2->speed;
1086
1087    EINA_LIST_FOREACH(ep2->targets, l, et2)
1088      {
1089         name = (char*) (et2 + 1);
1090         et = mem_alloc(SZ(Edje_Program_Target) + strlen(name) + 1);
1091         ep->targets = eina_list_append(ep->targets, et);
1092         copy = (char*) (et + 1);
1093
1094         memcpy(copy, name, strlen(name) + 1);
1095
1096         if (ep2->action == EDJE_ACTION_TYPE_STATE_SET)
1097           data_queue_copied_part_lookup(pc, &(et2->id), &(et->id));
1098         else if (ep2->action == EDJE_ACTION_TYPE_ACTION_STOP)
1099           data_queue_copied_program_lookup(pc, &(et2->id), &(et->id));
1100         else if (ep2->action == EDJE_ACTION_TYPE_SCRIPT)
1101           data_queue_copied_program_lookup(pc, &(et2->id), &(et->id));
1102         else if (ep2->action == EDJE_ACTION_TYPE_DRAG_VAL_SET)
1103           data_queue_copied_part_lookup(pc, &(et2->id), &(et->id));
1104         else if (ep2->action == EDJE_ACTION_TYPE_DRAG_VAL_STEP)
1105           data_queue_copied_part_lookup(pc, &(et2->id), &(et->id));
1106         else if (ep2->action == EDJE_ACTION_TYPE_DRAG_VAL_PAGE)
1107           data_queue_copied_part_lookup(pc, &(et2->id), &(et->id));
1108         else if (ep2->action == EDJE_ACTION_TYPE_FOCUS_SET)
1109
1110           data_queue_copied_part_lookup(pc, &(et2->id), &(et->id));
1111         else if (ep2->action == EDJE_ACTION_TYPE_FOCUS_OBJECT)
1112           data_queue_copied_part_lookup(pc, &(et2->id), &(et->id));
1113         else
1114           {
1115              ERR("parse error %s:%i. target may only be used after action",
1116                  file_in, line - 1);
1117              exit(-1);
1118           }
1119      }
1120
1121    EINA_LIST_FOREACH(ep2->after, l, pa2)
1122      {
1123         name = (char*) (pa2 + 1);
1124         pa = mem_alloc(SZ(Edje_Program_After) + strlen(name) + 1);
1125         ep->after = eina_list_append(ep->after, pa);
1126         copy = (char*) (pa + 1);
1127
1128         memcpy(copy, name, strlen(name) + 1);
1129
1130         data_queue_copied_program_lookup(pc, &(pa2->id), &(pa->id));
1131      }
1132
1133    ep->api.name = STRDUP(ep2->api.name);
1134    ep->api.description = STRDUP(ep2->api.description);
1135    data_queue_copied_part_lookup(pc, &(ep2->param.src), &(ep->param.src));
1136    data_queue_copied_part_lookup(pc, &(ep2->param.dst), &(ep->param.dst));
1137
1138    epp = (Edje_Program_Parser *)ep;
1139    epp->can_override = EINA_TRUE;
1140
1141    #undef STRDUP
1142 }
1143
1144 /*****/
1145
1146 /**
1147    @edcsection{toplevel,Top-Level blocks}
1148  */
1149
1150 /**
1151     @page edcref
1152
1153     @block
1154         externals
1155     @context
1156         externals {
1157            external: "name";
1158         }
1159     @description
1160         The "externals" block is used to list each external module file that will be used in others
1161         programs.
1162     @endblock
1163
1164     @property
1165         external
1166     @parameters
1167         [external filename]
1168     @effect
1169         Used to add a file to the externals list.
1170     @endproperty
1171  */
1172 static void
1173 st_externals_external(void)
1174 {
1175    External *ex;
1176
1177    check_arg_count(1);
1178
1179    if (!edje_file->external_dir)
1180      edje_file->external_dir = mem_alloc(SZ(Edje_External_Directory));
1181
1182    ex = mem_alloc(SZ(External));
1183    ex->name = parse_str(0);
1184      {
1185         Eina_List *l;
1186         External *lex;
1187
1188         EINA_LIST_FOREACH(externals, l, lex)
1189           {
1190              if (!strcmp(lex->name, ex->name))
1191                {
1192                   free(ex->name);
1193                   free(ex);
1194                   return;
1195                }
1196           }
1197      }
1198    externals = eina_list_append(externals, ex);
1199
1200    if (edje_file->external_dir)
1201      {
1202         edje_file->external_dir->entries_count++;
1203         edje_file->external_dir->entries = realloc(edje_file->external_dir->entries,
1204                                                    sizeof (Edje_External_Directory) * edje_file->external_dir->entries_count);
1205         memset(edje_file->external_dir->entries + edje_file->external_dir->entries_count - 1,
1206                0, sizeof (Edje_External_Directory));
1207         if (!edje_file->external_dir->entries)
1208           {
1209              ERR("not enough memory");
1210              exit(-1);
1211           }
1212
1213         edje_file->external_dir->entries[edje_file->external_dir->entries_count - 1].entry = mem_strdup(ex->name);
1214      }
1215 }
1216
1217 /**
1218     @page edcref
1219
1220     @block
1221         images
1222     @context
1223         images {
1224             image: "filename1.ext" COMP;
1225             image: "filename2.ext" LOSSY 99;
1226             set {
1227                name: "image_name_used";
1228                image {
1229                   image: "filename3.ext" LOSSY 90;
1230                   size: 201 201 500 500;
1231                }
1232                image {
1233                   image: "filename4.ext" COMP;
1234                   size: 51 51 200 200;
1235                }
1236                image {
1237                   image: "filename5.ext" COMP;
1238                   size: 11 11 50 50;
1239                }
1240                image {
1241                   image: "filename6.ext" RAW;
1242                   size: 0 0 10 10;
1243                }
1244             }
1245             ..
1246         }
1247     @description
1248         The "images" block is used to list each image file that will be used in
1249         the theme along with its compression method (if any).
1250         Besides the document's root, additional "images" blocks can be
1251         included inside other blocks, normally "collections", "group" and
1252         "part", easing maintenance of the file list when the theme is split
1253         among multiple files.
1254     @endblock
1255
1256     @property
1257         image
1258     @parameters
1259         [image file] [compression method] (compression level)
1260     @effect
1261         Used to include each image file. The full path to the directory holding
1262         the images can be defined later with edje_cc's "-id" option.
1263         Compression methods:
1264         @li RAW: Uncompressed.
1265         @li COMP: Lossless compression.
1266         @li LOSSY [0-100]: Lossy compression with quality from 0 to 100.
1267         @li USER: Do not embed the file, refer to the external file instead.
1268     @endproperty
1269  */
1270 static void
1271 st_images_image(void)
1272 {
1273    Edje_Image_Directory_Entry *img;
1274    const char *tmp;
1275    unsigned int i;
1276    int v;
1277
1278    check_min_arg_count(2);
1279
1280    if (!edje_file->image_dir)
1281      edje_file->image_dir = mem_alloc(SZ(Edje_Image_Directory));
1282
1283    tmp = parse_str(0);
1284
1285    for (i = 0; i < edje_file->image_dir->entries_count; ++i)
1286      if (!strcmp(edje_file->image_dir->entries[i].entry, tmp))
1287        {
1288           free((char*) tmp);
1289           return;
1290        }
1291
1292    edje_file->image_dir->entries_count++;
1293    edje_file->image_dir->entries = realloc(edje_file->image_dir->entries,
1294                                            sizeof (Edje_Image_Directory_Entry) * edje_file->image_dir->entries_count);
1295    memset(edje_file->image_dir->entries + edje_file->image_dir->entries_count - 1,
1296           0, sizeof (Edje_Image_Directory_Entry));
1297    if (!edje_file->image_dir->entries)
1298      {
1299         ERR("No enough memory.");
1300         exit(-1);
1301      }
1302
1303    img = edje_file->image_dir->entries + edje_file->image_dir->entries_count - 1;
1304
1305    img->entry = tmp;
1306    img->id = edje_file->image_dir->entries_count - 1;
1307    v = parse_enum(1,
1308                   "RAW", 0,
1309                   "COMP", 1,
1310                   "LOSSY", 2,
1311                   "USER", 3,
1312                   NULL);
1313    if (v == 0)
1314      {
1315         img->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_PERFECT;
1316         img->source_param = 0;
1317      }
1318    else if (v == 1)
1319      {
1320         img->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_PERFECT;
1321         img->source_param = 1;
1322      }
1323    else if (v == 2)
1324      {
1325         img->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY;
1326         img->source_param = 0;
1327      }
1328    else if (v == 3)
1329      {
1330         img->source_type = EDJE_IMAGE_SOURCE_TYPE_EXTERNAL;
1331         img->source_param = 0;
1332      }
1333    if (img->source_type != EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY)
1334         check_arg_count(2);
1335    else
1336      {
1337         img->source_param = parse_int_range(2, 0, 100);
1338         check_arg_count(3);
1339      }
1340 }
1341
1342 /**
1343     @page edcref
1344
1345     @block
1346         set
1347     @context
1348     set {
1349        name: "image_name_used";
1350        image {
1351           image: "filename3.ext" LOSSY 90;
1352           size: 201 201 500 500;
1353        }
1354        image {
1355           image: "filename4.ext" COMP;
1356           size: 51 51 200 200;
1357        }
1358        image {
1359           image: "filename5.ext" COMP;
1360           size: 11 11 50 50;
1361        }
1362        image {
1363           image: "filename6.ext" RAW;
1364           size: 0 0 10 10;
1365        }
1366     }
1367     @description
1368         The "set" block is used to define an image with different content depending on their size.
1369         Besides the document's root, additional "set" blocks can be
1370         included inside other blocks, normally "collections", "group" and
1371         "part", easing maintenance of the file list when the theme is split
1372         among multiple files.
1373     @endblock
1374  */
1375 static void
1376 ob_images_set(void)
1377 {
1378    if (!edje_file->image_dir)
1379      edje_file->image_dir = mem_alloc(SZ(Edje_Image_Directory));
1380
1381    edje_file->image_dir->sets_count++;
1382    edje_file->image_dir->sets = realloc(edje_file->image_dir->sets,
1383                                         sizeof (Edje_Image_Directory_Set) * edje_file->image_dir->sets_count);
1384    memset(edje_file->image_dir->sets + edje_file->image_dir->sets_count - 1,
1385           0, sizeof (Edje_Image_Directory_Set));
1386    if (!edje_file->image_dir->sets)
1387      {
1388         ERR("Not enough memory.");
1389         exit(-1);
1390      }
1391    edje_file->image_dir->sets[edje_file->image_dir->sets_count - 1].id = edje_file->image_dir->sets_count - 1;
1392 }
1393
1394 /**
1395     @page edcref
1396
1397     @property
1398         name
1399     @parameters
1400         [image name]
1401     @effect
1402         Define the name that refer to this image description.
1403     @endproperty
1404 */
1405 static void
1406 st_images_set_name(void)
1407 {
1408    check_arg_count(1);
1409
1410    edje_file->image_dir->sets[edje_file->image_dir->sets_count - 1].name = parse_str(0);
1411 }
1412
1413 /**
1414     @page edcref
1415
1416     @block
1417         image
1418     @description
1419         The "image" block inside a "set" block define the characteristic of an image.
1420         Every block will describe one image and the size rule to use it.
1421     @endblock
1422 **/
1423 static void
1424 ob_images_set_image(void)
1425 {
1426    Edje_Image_Directory_Set_Entry *entry;
1427    Edje_Image_Directory_Set *set;
1428
1429    set = edje_file->image_dir->sets + edje_file->image_dir->sets_count - 1;
1430
1431    entry = mem_alloc(SZ(Edje_Image_Directory_Set_Entry));
1432
1433    set->entries = eina_list_append(set->entries, entry);
1434 }
1435
1436 /**
1437     @page edcref
1438
1439     @property
1440         image
1441     @parameters
1442         [image file] [compression method] (compression level)
1443     @effect
1444         Used to include each image file. The full path to the directory holding
1445         the images can be defined later with edje_cc's "-id" option.
1446         Compression methods:
1447         @li RAW: Uncompressed.
1448         @li COMP: Lossless compression.
1449         @li LOSSY [0-100]: Lossy compression with quality from 0 to 100.
1450         @li USER: Do not embed the file, refer to the external file instead.
1451     @endproperty
1452 **/
1453 static void
1454 st_images_set_image_image(void)
1455 {
1456    Edje_Image_Directory_Set_Entry *entry;
1457    Edje_Image_Directory_Set *set;
1458    unsigned int i;
1459
1460    set = edje_file->image_dir->sets + edje_file->image_dir->sets_count - 1;
1461    entry = eina_list_data_get(eina_list_last(set->entries));
1462
1463    /* Add the image to the global pool with the same syntax. */
1464    st_images_image();
1465
1466    entry->name = parse_str(0);
1467
1468    for (i = 0; i < edje_file->image_dir->entries_count; ++i)
1469      if (!strcmp(edje_file->image_dir->entries[i].entry, entry->name))
1470        {
1471          entry->id = i;
1472          return;
1473        }
1474 }
1475
1476 /**
1477     @page edcref
1478
1479     @property
1480         size
1481     @parameters
1482         [minw minh maxw mawh]
1483     @effect
1484         Define the minimal and maximal size that will select the specified image.
1485     @endproperty
1486 */
1487 static void
1488 st_images_set_image_size(void)
1489 {
1490    Edje_Image_Directory_Set_Entry *entry;
1491    Edje_Image_Directory_Set *set;
1492
1493    set = edje_file->image_dir->sets + edje_file->image_dir->sets_count - 1;
1494    entry = eina_list_data_get(eina_list_last(set->entries));
1495
1496    entry->size.min.w = parse_int(0);
1497    entry->size.min.h = parse_int(1);
1498    entry->size.max.w = parse_int(2);
1499    entry->size.max.h = parse_int(3);
1500
1501    if (entry->size.min.w > entry->size.max.w
1502        || entry->size.min.h > entry->size.max.h)
1503      {
1504        ERR("parse error %s:%i. Image min and max size are not in the right order ([%i, %i] < [%i, %i])",
1505            file_in, line - 1,
1506            entry->size.min.w, entry->size.min.h,
1507            entry->size.max.w, entry->size.max.h);
1508        exit(-1);
1509      }
1510 }
1511
1512 /**
1513     @page edcref
1514
1515     @block
1516         fonts
1517     @context
1518         fonts {
1519             font: "filename1.ext" "fontname";
1520             font: "filename2.ext" "otherfontname";
1521             ..
1522         }
1523     @description
1524         The "fonts" block is used to list each font file with an alias used later
1525         in the theme. As with the "images" block, additional "fonts" blocks can
1526         be included inside other blocks.
1527     @endblock
1528
1529     @property
1530         font
1531     @parameters
1532         [font filename] [font alias]
1533     @effect
1534         Defines each font "file" and "alias", the full path to the directory
1535         holding the font files can be defined with edje_cc's "-fd" option.
1536     @endproperty
1537  */
1538 static void
1539 st_fonts_font(void)
1540 {
1541    Font *fn;
1542
1543    check_arg_count(2);
1544
1545    if (!edje_file->fonts)
1546      edje_file->fonts = eina_hash_string_small_new(free);
1547
1548    fn = mem_alloc(SZ(Font));
1549    fn->file = parse_str(0);
1550    fn->name = parse_str(1);
1551
1552    if (eina_hash_find(edje_file->fonts, fn->name))
1553      {
1554         free(fn->file);
1555         free(fn->name);
1556         free(fn);
1557         return;
1558      }
1559
1560    eina_hash_direct_add(edje_file->fonts, fn->name, fn);
1561 }
1562
1563 /**
1564     @page edcref
1565     @block
1566         data
1567     @context
1568         data {
1569             item: "key" "value";
1570             file: "otherkey" "filename.ext";
1571             ..
1572         }
1573     @description
1574         The "data" block is used to pass arbitrary parameters from the theme to
1575         the application. Unlike the "images" and "fonts" blocks, additional
1576         "data" blocks can only be included inside the "group" block.
1577     @endblock
1578
1579     @property
1580         item
1581     @parameters
1582         [parameter name] [parameter value]
1583     @effect
1584         Defines a new parameter, the value will be the string specified next to
1585         it.
1586     @endproperty
1587  */
1588 static void
1589 st_data_item(void)
1590 {
1591    Edje_String *es;
1592    char *key;
1593
1594    check_arg_count(2);
1595
1596    key = parse_str(0);
1597
1598    es = mem_alloc(SZ(Edje_String));
1599    es->str = parse_str(1);
1600
1601    if (!edje_file->data)
1602      edje_file->data = eina_hash_string_small_new(free);
1603
1604    /* FIXME: check if data already exist */
1605    eina_hash_direct_add(edje_file->data, key, es);
1606 }
1607
1608 /**
1609     @page edcref
1610     @property
1611         file
1612     @parameters
1613         [parameter name] [parameter filename]
1614     @effect
1615         Defines a new parameter, the value will be the contents of the
1616         specified file formated as a single string of text. This property only
1617         works with plain text files.
1618     @endproperty
1619  */
1620 static void
1621 st_data_file(void)
1622 {
1623    const char *data;
1624    const char *over;
1625    Edje_String *es;
1626    char *filename;
1627    char *value;
1628    char *key;
1629    int fd;
1630    int i;
1631    struct stat buf;
1632
1633    check_arg_count(2);
1634
1635    key = parse_str(0);
1636
1637    es = mem_alloc(SZ(Edje_String));
1638    filename = parse_str(1);
1639
1640    fd = open(filename, O_RDONLY | O_BINARY, S_IRUSR | S_IWUSR);
1641    if (fd < 0)
1642      {
1643         ERR("%s:%i when opening file \"%s\": \"%s\"",
1644             file_in, line, filename, strerror(errno));
1645         exit(-1);
1646      }
1647
1648    if (fstat(fd, &buf))
1649      {
1650         ERR("%s:%i when stating file \"%s\": \"%s\"",
1651             file_in, line, filename, strerror(errno));
1652         exit(-1);
1653      }
1654
1655    data = mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
1656    if (data == MAP_FAILED)
1657      {
1658         ERR("%s:%i when mapping file \"%s\": \"%s\"",
1659             file_in, line, filename, strerror(errno));
1660         exit(-1);
1661      }
1662
1663    over = data;
1664    for (i = 0; i < buf.st_size; ++i, ++over)
1665      if (*over == '\0')
1666        {
1667           ERR("%s:%i file \"%s\" is a binary file.", file_in, line, filename);
1668           exit(-1);
1669        }
1670
1671    value = malloc(sizeof (char) * buf.st_size + 1);
1672    snprintf(value, buf.st_size + 1, "%s", data);
1673
1674    munmap((void*)data, buf.st_size);
1675    close(fd);
1676
1677    es->str = value;
1678
1679    eina_hash_direct_add(edje_file->data, key, es);
1680
1681    free(filename);
1682 }
1683
1684 /**
1685     @page edcref
1686     @block
1687         color_classes
1688     @context
1689         color_classes {
1690             color_class {
1691                 name:  "colorclassname";
1692                 color:  [0-255] [0-255] [0-255] [0-255];
1693                 color2: [0-255] [0-255] [0-255] [0-255];
1694                 color3: [0-255] [0-255] [0-255] [0-255]
1695             }
1696             ..
1697         }
1698     @description
1699         The "color_classes" block contains a list of one or more "color_class"
1700         blocks. Each "color_class" allows the designer to name an arbitrary
1701         group of colors to be used in the theme, the application can use that
1702         name to alter the color values at runtime.
1703     @endblock
1704 */
1705 static void
1706 ob_color_class(void)
1707 {
1708    Edje_Color_Class *cc;
1709
1710    cc = mem_alloc(SZ(Edje_Color_Class));
1711    edje_file->color_classes = eina_list_append(edje_file->color_classes, cc);
1712
1713    cc->r = 0;
1714    cc->g = 0;
1715    cc->b = 0;
1716    cc->a = 0;
1717    cc->r2 = 0;
1718    cc->g2 = 0;
1719    cc->b2 = 0;
1720    cc->a2 = 0;
1721    cc->r3 = 0;
1722    cc->g3 = 0;
1723    cc->b3 = 0;
1724    cc->a3 = 0;
1725 }
1726
1727 /**
1728     @page edcref
1729
1730     @property
1731         name
1732     @parameters
1733         [color class name]
1734     @effect
1735         Sets the name for the color class, used as reference by both the theme
1736         and the application.
1737     @endproperty
1738 */
1739 static void
1740 st_color_class_name(void)
1741 {
1742    Edje_Color_Class *cc, *tcc;
1743    Eina_List *l;
1744
1745    cc = eina_list_data_get(eina_list_last(edje_file->color_classes));
1746    cc->name = parse_str(0);
1747    EINA_LIST_FOREACH(edje_file->color_classes, l, tcc)
1748      {
1749         if ((cc != tcc) && (!strcmp(cc->name, tcc->name)))
1750           {
1751              ERR("parse error %s:%i. There is already a color class named \"%s\"",
1752                  file_in, line - 1, cc->name);
1753              exit(-1);
1754           }
1755      }
1756 }
1757
1758 /**
1759     @page edcref
1760     @property
1761         color
1762     @parameters
1763         [red] [green] [blue] [alpha]
1764     @effect
1765         The main color.
1766     @endproperty
1767 */
1768 static void
1769 st_color_class_color(void)
1770 {
1771    Edje_Color_Class *cc;
1772
1773    check_arg_count(4);
1774
1775    cc = eina_list_data_get(eina_list_last(edje_file->color_classes));
1776    cc->r = parse_int_range(0, 0, 255);
1777    cc->g = parse_int_range(1, 0, 255);
1778    cc->b = parse_int_range(2, 0, 255);
1779    cc->a = parse_int_range(3, 0, 255);
1780 }
1781
1782 /**
1783     @page edcref
1784     @property
1785         color2
1786     @parameters
1787         [red] [green] [blue] [alpha]
1788     @effect
1789         Used as shadow in text and textblock parts.
1790     @endproperty
1791 */
1792 static void
1793 st_color_class_color2(void)
1794 {
1795    Edje_Color_Class *cc;
1796
1797    check_arg_count(4);
1798
1799    cc = eina_list_data_get(eina_list_last(edje_file->color_classes));
1800    cc->r2 = parse_int_range(0, 0, 255);
1801    cc->g2 = parse_int_range(1, 0, 255);
1802    cc->b2 = parse_int_range(2, 0, 255);
1803    cc->a2 = parse_int_range(3, 0, 255);
1804 }
1805
1806 /**
1807     @page edcref
1808     @property
1809         color3
1810     @parameters
1811         [red] [green] [blue] [alpha]
1812     @effect
1813         Used as outline in text and textblock parts.
1814     @endproperty
1815 */
1816 static void
1817 st_color_class_color3(void)
1818 {
1819    Edje_Color_Class *cc;
1820
1821    check_arg_count(4);
1822
1823    cc = eina_list_data_get(eina_list_last(edje_file->color_classes));
1824    cc->r3 = parse_int_range(0, 0, 255);
1825    cc->g3 = parse_int_range(1, 0, 255);
1826    cc->b3 = parse_int_range(2, 0, 255);
1827    cc->a3 = parse_int_range(3, 0, 255);
1828 }
1829
1830 /**
1831     @page edcref
1832     @block
1833         styles
1834     @context
1835         styles {
1836             style {
1837                 name: "stylename";
1838                 base: "..default style properties..";
1839
1840                 tag:  "tagname" "..style properties..";
1841                 ..
1842             }
1843             ..
1844         }
1845     @description
1846         The "styles" block contains a list of one or more "style" blocks. A
1847         "style" block is used to create style \<tags\> for advanced TEXTBLOCK
1848         formatting.
1849     @endblock
1850 */
1851 static void
1852 ob_styles_style(void)
1853 {
1854    Edje_Style *stl;
1855
1856    stl = mem_alloc(SZ(Edje_Style));
1857    edje_file->styles = eina_list_append(edje_file->styles, stl);
1858 }
1859
1860 /**
1861     @page edcref
1862     @property
1863         name
1864     @parameters
1865         [style name]
1866     @effect
1867         The name of  the style to be used as reference later in the theme.
1868     @endproperty
1869 */
1870 static void
1871 st_styles_style_name(void)
1872 {
1873    Edje_Style *stl, *tstl;
1874    Eina_List *l;
1875
1876    stl = eina_list_data_get(eina_list_last(edje_file->styles));
1877    stl->name = parse_str(0);
1878    EINA_LIST_FOREACH(edje_file->styles, l, tstl)
1879      {
1880         if (stl->name && tstl->name && (stl != tstl) && (!strcmp(stl->name, tstl->name)))
1881           {
1882              ERR("parse error %s:%i. There is already a style named \"%s\"",
1883                  file_in, line - 1, stl->name);
1884              exit(-1);
1885           }
1886      }
1887 }
1888
1889 /**
1890     @page edcref
1891     @property
1892         base
1893     @parameters
1894         [style properties string]
1895     @effect
1896         The default style properties that will be applied to the complete
1897         text.
1898     @endproperty
1899 */
1900 static void
1901 st_styles_style_base(void)
1902 {
1903    Edje_Style *stl;
1904    Edje_Style_Tag *tag;
1905
1906    stl = eina_list_data_get(eina_list_last(edje_file->styles));
1907    if (stl->tags)
1908      {
1909         ERR("parse error %s:%i. There is already a basic format for the style",
1910             file_in, line - 1);
1911         exit(-1);
1912      }
1913    tag = mem_alloc(SZ(Edje_Style_Tag));
1914    tag->key = mem_strdup("DEFAULT");
1915    tag->value = parse_str(0);
1916    stl->tags = eina_list_append(stl->tags, tag);
1917 }
1918
1919 /**
1920     @page edcref
1921     @property
1922         tag
1923     @parameters
1924         [tag name] [style properties string]
1925     @effect
1926         Style to be applied only to text between style \<tags\>..\</tags\>.
1927         When creating "paired" tags, like \<bold\>\</bold\>, A '+' should be added at the start of the style properties of the first part (\<bold\>).
1928         If the second part (\</bold\>) is also defined, a '-' should be prepended to it's style properties.
1929         This only applies to paired tags; Single tags, like \<tab\>, must not include a starting '+'.
1930     @endproperty
1931 */
1932 static void
1933 st_styles_style_tag(void)
1934 {
1935    Edje_Style *stl;
1936    Edje_Style_Tag *tag;
1937
1938    stl = eina_list_data_get(eina_list_last(edje_file->styles));
1939    tag = mem_alloc(SZ(Edje_Style_Tag));
1940    tag->key = parse_str(0);
1941    tag->value = parse_str(1);
1942    stl->tags = eina_list_append(stl->tags, tag);
1943 }
1944
1945 /**
1946     @page edcref
1947     @block
1948         collections
1949     @context
1950         collections {
1951             ..
1952             group { }
1953             group { }
1954             sounds { }
1955             ..
1956         }
1957     @description
1958         The "collections" block is used to list the groups that compose the
1959         theme. Additional "collections" blocks do not prevent overriding group
1960         names. The "sounds" block comprises of all sound definitions.
1961     @endblock
1962 */
1963 static void
1964 ob_collections(void)
1965 {
1966    if (!edje_file->collection)
1967      {
1968         edje_file->collection = eina_hash_string_small_new(NULL);
1969         edje_collections_lookup = eina_hash_int32_new(NULL);
1970      }
1971 }
1972 /**
1973     @page edcref
1974     @block
1975         sounds
1976     @context
1977         sounds {
1978            sample {
1979               name: "sound_file1" COMP;
1980               source: "sound_file1.wav";
1981            }
1982            sample {
1983               name: "sound_file2" LOSSY 0.4;
1984               source: "sound_file2.wav";
1985            }
1986            tone: "tone-1"  2300;
1987         }
1988
1989     @description
1990         The "sounds" block contains a list of one or more sound sample and tones items.
1991     @endblock
1992     @block
1993         sample
1994     @context
1995        sample {
1996           name: "sound_file1" RAW;
1997           source: "sound_file1.wav";
1998        }
1999        sample {
2000           name: "sound_file2" LOSSY 0.5;
2001           source: "sound_file2.wav";
2002        }
2003        sample {
2004           name: "sound_file3" COMP;
2005           source: "sound_file3.wav";
2006        }
2007        sample {
2008           name: "sound_file4" AS_IS;
2009           source: "sound_file1.wav";
2010        }
2011     @description
2012         The sample block defines the sound sample.
2013     @endblock
2014     @property
2015         name
2016     @parameters
2017         [sample name] [compression type] [if lossy, then quality]
2018     @effect
2019         Used to include each sound file. The full path to the directory holding
2020         the sounds can be defined later with edje_cc's "-sd" option.
2021         @li RAW: Uncompressed.
2022         @li COMP: Lossless compression.
2023         @li LOSSY [-0.1  - 1.0]: Lossy compression with quality from 0 to 1.0.
2024         @li AS_IS: Check for re-encoding, no compression/encoding, just write the file information as it is.
2025     @endproperty
2026     @since 1.1.0
2027  */
2028 static void
2029 st_collections_group_sound_sample_name(void)
2030 {
2031    Edje_Sound_Sample *sample;
2032    const char *tmp;
2033    unsigned int i;
2034    
2035    if (!edje_file->sound_dir)
2036      edje_file->sound_dir = mem_alloc(SZ(Edje_Sound_Directory));
2037    
2038    tmp = parse_str(0);
2039    
2040    for (i = 0; i < edje_file->sound_dir->samples_count; i++)
2041      {
2042         if (!strcmp(edje_file->sound_dir->samples[i].name, tmp))
2043           {
2044              free((char *)tmp);
2045              return;
2046           }
2047      }
2048    
2049    edje_file->sound_dir->samples_count++;
2050    edje_file->sound_dir->samples = 
2051      realloc(edje_file->sound_dir->samples,
2052              sizeof(Edje_Sound_Sample) * 
2053              edje_file->sound_dir->samples_count);
2054
2055    if (!edje_file->sound_dir->samples)
2056      {
2057         ERR("No enough memory.");
2058         exit(-1);
2059      }
2060    
2061    sample =
2062      edje_file->sound_dir->samples +
2063      edje_file->sound_dir->samples_count - 1;
2064    memset(sample, 0, sizeof (Edje_Sound_Sample));
2065    
2066    sample->name = tmp;
2067    sample->id = edje_file->sound_dir->samples_count - 1;
2068    sample->compression = parse_enum(1,
2069                                     "RAW", EDJE_SOUND_SOURCE_TYPE_INLINE_RAW,
2070                                     "COMP", EDJE_SOUND_SOURCE_TYPE_INLINE_COMP,
2071                                     "LOSSY", EDJE_SOUND_SOURCE_TYPE_INLINE_LOSSY,
2072                                     "AS_IS", EDJE_SOUND_SOURCE_TYPE_INLINE_AS_IS,
2073                                     NULL);
2074    
2075    if (sample->compression == EDJE_SOUND_SOURCE_TYPE_INLINE_LOSSY)
2076      {
2077         sample->quality = parse_float_range(2, 45.0, 1000.0);
2078         check_arg_count(3);
2079      }
2080    else
2081      check_arg_count(2);
2082
2083 }
2084
2085 /**
2086     @page edcref
2087     @property
2088         source
2089     @parameters
2090         [sound file name]
2091     @effect
2092         The Sound source file name (Source can be mono/stereo WAV file.
2093         Only files with 44.1 KHz sample rate supported now)
2094     @endproperty
2095     @since 1.1.0
2096  */
2097 static void
2098 st_collections_group_sound_sample_source(void)
2099 {
2100    Edje_Sound_Sample *sample;
2101
2102    if (!edje_file->sound_dir->samples)
2103      {
2104         ERR("Invalid sound sample source definition.");
2105         exit(-1);
2106      }
2107    
2108    sample = 
2109      edje_file->sound_dir->samples +
2110      edje_file->sound_dir->samples_count - 1;
2111    
2112    if (!sample)
2113      {
2114         ERR("Invalid sound sample source definition.");
2115         exit(-1);
2116      }
2117    sample->snd_src = parse_str(0);
2118    check_arg_count(1);
2119 }
2120
2121 /**
2122     @page edcref
2123     @property
2124         tone
2125     @parameters
2126         [tone name] [frequency]
2127     @effect
2128         sound of specific frequency
2129     @endproperty
2130     @since 1.1.0
2131  */
2132 static void
2133 st_collections_group_sound_tone(void)
2134 {
2135    Edje_Sound_Tone *tone;
2136    const char *tmp;
2137    unsigned int i;
2138    int value;
2139
2140    check_arg_count(2);
2141    
2142    if (!edje_file->sound_dir)
2143      edje_file->sound_dir = mem_alloc(SZ(Edje_Sound_Directory));
2144    
2145    tmp = parse_str(0);
2146    /* Audible range 20 to 20KHz */
2147    value = parse_int_range(1, 20, 20000);
2148    
2149    /* Check for Tone duplication */
2150    for (i = 0; i < edje_file->sound_dir->tones_count; i++)
2151      {
2152         if (!strcmp(edje_file->sound_dir->tones[i].name, tmp))
2153           {
2154              ERR("Tone name: %s already exist.", tmp);
2155              free((char *)tmp);
2156              exit(-1);
2157           }
2158         if (edje_file->sound_dir->tones[i].value == value)
2159           {
2160              ERR("Tone name %s with same frequency %d exist.",
2161                  edje_file->sound_dir->tones[i].name, value);
2162              exit(-1);
2163           }
2164      }
2165    edje_file->sound_dir->tones_count++;
2166    edje_file->sound_dir->tones = 
2167      realloc(edje_file->sound_dir->tones,
2168              sizeof (Edje_Sound_Tone) * 
2169              edje_file->sound_dir->tones_count);
2170    
2171    if (!edje_file->sound_dir->tones)
2172      {
2173         ERR("No enough memory.");
2174         exit(-1);
2175      }
2176    
2177    tone = edje_file->sound_dir->tones + edje_file->sound_dir->tones_count - 1;
2178    memset(tone, 0, sizeof (Edje_Sound_Tone));
2179    
2180    tone->name = tmp;
2181    tone->value = value;
2182    tone->id = edje_file->sound_dir->tones_count - 1;
2183 }
2184 /**
2185    @edcsection{group,Group sub blocks}
2186  */
2187
2188 /**
2189     @page edcref
2190     @block
2191         group
2192     @context
2193         collections {
2194             ..
2195             group {
2196                 name: "nameusedbytheapplication";
2197                 alias: "anothername";
2198                 min: width height;
2199                 max: width height;
2200
2201                 data { }
2202                 script { }
2203                 parts { }
2204                 programs { }
2205             }
2206             ..
2207         }
2208     @description
2209         A "group" block contains the list of parts and programs that compose a
2210         given Edje Object.
2211     @endblock
2212 */
2213 static void
2214 ob_collections_group(void)
2215 {
2216    Edje_Part_Collection *pc;
2217    Code *cd;
2218
2219    if (current_de && !current_de->entry)
2220      {
2221         ERR("A collection without a name was detected, that's not allowed.");
2222         exit(-1);
2223      }
2224
2225    current_de = mem_alloc(SZ(Edje_Part_Collection_Directory_Entry));
2226    current_de->id = eina_list_count(edje_collections);
2227
2228    eina_hash_add(edje_collections_lookup, &current_de->id, current_de);
2229
2230    pc = mem_alloc(SZ(Edje_Part_Collection));
2231    edje_collections = eina_list_append(edje_collections, pc);
2232    pc->id = current_de->id;
2233    pc->broadcast_signal = EINA_TRUE; /* This was the behaviour by default in Edje 1.1 */
2234
2235    cd = mem_alloc(SZ(Code));
2236    codes = eina_list_append(codes, cd);
2237 }
2238
2239 /**
2240     @page edcref
2241     @property
2242         name
2243     @parameters
2244         [group name]
2245     @effect
2246         The name that will be used by the application to load the resulting
2247         Edje object and to identify the group to swallow in a GROUP part. If a
2248         group with the same name exists already it will be completely overriden
2249         by the new group.
2250     @endproperty
2251 */
2252 static void
2253 st_collections_group_name(void)
2254 {
2255    Edje_Part_Collection_Directory_Entry *alias;
2256    Edje_Part_Collection_Directory_Entry *older;
2257    Edje_Part_Collection *current_pc;
2258    Eina_List *l = NULL;
2259
2260    check_arg_count(1);
2261
2262    current_pc = eina_list_data_get(eina_list_last(edje_collections));
2263
2264    current_de->entry = parse_str(0);
2265    current_pc->part = current_de->entry;
2266
2267    older = eina_hash_find(edje_file->collection, current_de->entry);
2268    if (older) eina_hash_del(edje_file->collection, current_de->entry, older);
2269    eina_hash_direct_add(edje_file->collection, current_de->entry, current_de);
2270    if (!older) return;
2271
2272    EINA_LIST_FOREACH(aliases, l, alias)
2273      if (strcmp(alias->entry, current_de->entry) == 0)
2274        {
2275           Edje_Part_Collection *pc;
2276
2277           pc = eina_list_nth(edje_collections, older->id);
2278           INF("overriding alias ('%s' => '%s') by group '%s'",
2279               alias->entry, pc->part,
2280               current_de->entry);
2281           aliases = eina_list_remove_list(aliases, l);
2282           free(alias);
2283           break;
2284        }
2285
2286 }
2287
2288 typedef struct _Edje_List_Foreach_Data Edje_List_Foreach_Data;
2289 struct _Edje_List_Foreach_Data
2290 {
2291    Eina_List *list;
2292 };
2293
2294 static Eina_Bool
2295 _edje_data_item_list_foreach(const Eina_Hash *hash __UNUSED__, const void *key, void *data __UNUSED__, void *fdata)
2296 {
2297    Edje_List_Foreach_Data *fd;
2298
2299    fd = fdata;
2300    fd->list = eina_list_append(fd->list, strdup(key));
2301
2302    return EINA_TRUE;
2303 }
2304
2305 /**
2306     @page edcref
2307     @property
2308         inherit
2309     @parameters
2310         [parent group name]
2311     @effect
2312         Parent group name for inheritance.
2313         Group "inherit" is used to inherit any predefined group and change
2314         some property which belongs to "part", "description", "items" or "program".
2315         The child group has the same property as parent group. If you specify the
2316         type again in an inherited part, it will cause an error (unless you plan
2317         to fix that).
2318     @endproperty
2319     @since 1.1.0
2320 */
2321 static void
2322 st_collections_group_inherit(void)
2323 {
2324    Edje_Part_Collection *pc, *pc2;
2325    Edje_Part *ep, *ep2;
2326    Edje_Part_Parser *epp, *epp2;
2327    Edje_Pack_Element *item, *item2;
2328    Edje_Pack_Element_Parser *pitem;
2329    Edje_Part_Description_Common *ed, *ed2;
2330    Edje_List_Foreach_Data fdata;
2331    Eina_List *l;
2332    char *parent_name;
2333    unsigned int i, j;
2334
2335    check_arg_count(1);
2336
2337    pc = eina_list_data_get(eina_list_last(edje_collections));
2338
2339    parent_name = parse_str(0);
2340
2341    EINA_LIST_FOREACH(edje_collections, l, pc2)
2342      {
2343         if (!strcmp(parent_name, pc2->part))
2344           break;
2345      }
2346    if (!pc2)
2347      {
2348         ERR("parse error %s:%i. There isn't a group with the name %s",
2349             file_in, line - 1, parent_name);
2350         exit(-1);
2351      }
2352    if (pc2 == pc)
2353      {
2354         ERR("parse error %s:%i. You are trying to inherit '%s' from itself. That's not possible."
2355             "If there is another group of the same name, you want to inherit from that group and have the"
2356             "same name as that group, there is a trick ! Just put the inherit before the directive that set"
2357             "the name !", file_in, line - 1, parent_name);
2358         exit(-1);
2359      }
2360
2361    if (pc2->data)
2362      {
2363         char *key, *data;
2364
2365         memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
2366         eina_hash_foreach(pc2->data,
2367                      _edje_data_item_list_foreach, &fdata);
2368
2369         if (!pc->data) pc->data = eina_hash_string_small_new(free);
2370         EINA_LIST_FREE(fdata.list, key)
2371           {
2372              data = eina_hash_find(pc2->data, key);
2373              eina_hash_direct_add(pc->data, key, data);
2374           }
2375      }
2376
2377    if (pc2->alias)
2378      {
2379         char *key, *alias;
2380
2381         memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
2382         eina_hash_foreach(pc2->alias,
2383                      _edje_data_item_list_foreach, &fdata);
2384         if (!pc->alias) pc->alias = eina_hash_string_small_new(free);
2385         EINA_LIST_FREE(fdata.list, key)
2386           {
2387              alias = eina_hash_find(pc2->alias, key);
2388              eina_hash_direct_add(pc->alias, key, alias);
2389           }
2390      }
2391    if (pc2->aliased)
2392      {
2393         char *key, *aliased;
2394
2395         memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
2396         eina_hash_foreach(pc2->aliased,
2397                           _edje_data_item_list_foreach, &fdata);
2398         if (!pc->aliased) pc->aliased = eina_hash_string_small_new(free);
2399         EINA_LIST_FREE(fdata.list, key)
2400           {
2401              aliased = eina_hash_find(pc2->aliased, key);
2402              eina_hash_direct_add(pc->aliased, key, aliased);
2403           }
2404      }
2405
2406    pc->prop.min.w = pc2->prop.min.w;
2407    pc->prop.min.h = pc2->prop.min.h;
2408    pc->prop.orientation = pc2->prop.orientation;
2409
2410    pc->lua_script_only = pc2->lua_script_only;
2411
2412    #define STRDUP(x) x ? strdup(x) : NULL
2413    for (i = 0 ; i < pc2->parts_count ; i++)
2414      {
2415         // copy the part
2416         edje_cc_handlers_part_make();
2417         ep = pc->parts[i];
2418         ep2 = pc2->parts[i];
2419         ep->name = STRDUP(ep2->name);
2420         ep->source = STRDUP(ep2->source);
2421         ep->source2 = STRDUP(ep2->source2);
2422         ep->source3 = STRDUP(ep2->source3);
2423         ep->source4 = STRDUP(ep2->source4);
2424         ep->source5 = STRDUP(ep2->source5);
2425         ep->source6 = STRDUP(ep2->source6);
2426
2427         data_queue_copied_part_lookup(pc, &(ep2->clip_to_id), &(ep->clip_to_id));
2428
2429         ep->type = ep2->type;
2430         ep->mouse_events = ep2->mouse_events;
2431         ep->repeat_events = ep2->repeat_events;
2432         ep->ignore_flags = ep2->ignore_flags;
2433         ep->scale = ep2->scale;
2434         ep->pointer_mode = ep2->pointer_mode;
2435         ep->precise_is_inside = ep2->precise_is_inside;
2436         ep->use_alternate_font_metrics = ep2->use_alternate_font_metrics;
2437         ep->effect = ep2->effect;
2438         ep->entry_mode = ep2->entry_mode;
2439         ep->select_mode = ep2->select_mode;
2440         ep->cursor_mode = ep2->cursor_mode;
2441         ep->multiline = ep2->multiline;
2442         ep->access = ep2->access;
2443         ep->dragable.x = ep2->dragable.x;
2444         ep->dragable.step_x = ep2->dragable.step_x;
2445         ep->dragable.count_x = ep2->dragable.count_x;
2446         ep->dragable.y = ep2->dragable.y;
2447         ep->dragable.step_y = ep2->dragable.step_y;
2448         ep->dragable.count_y = ep2->dragable.count_y;
2449         ep->nested_children_count = ep2->nested_children_count;
2450
2451         data_queue_copied_part_lookup(pc, &(ep2->dragable.confine_id), &(ep->dragable.confine_id));
2452         data_queue_copied_part_lookup(pc, &(ep2->dragable.event_id), &(ep->dragable.event_id));
2453
2454         epp = (Edje_Part_Parser *)ep;
2455         epp2 = (Edje_Part_Parser *)ep2;
2456         epp->reorder.insert_before = STRDUP(epp2->reorder.insert_before);
2457         epp->reorder.insert_after = STRDUP(epp2->reorder.insert_after);
2458         epp->can_override = EINA_TRUE;
2459
2460         for (j = 0 ; j < ep2->items_count ; j++)
2461           {
2462              ob_collections_group_parts_part_box_items_item();
2463              item = ep->items[j];
2464              item2 = ep2->items[j];
2465              item->type = item2->type;
2466              item->name = STRDUP(item2->name);
2467              item->source = STRDUP(item2->source);
2468              item->min.w = item2->min.w;
2469              item->min.h = item2->min.h;
2470              item->prefer.w = item2->prefer.w;
2471              item->prefer.h = item2->prefer.h;
2472              item->max.w = item2->max.w;
2473              item->max.h = item2->max.h;
2474              item->padding.l = item2->padding.l;
2475              item->padding.r = item2->padding.r;
2476              item->padding.t = item2->padding.t;
2477              item->padding.b = item2->padding.b;
2478              item->align.x = item2->align.x;
2479              item->align.y = item2->align.y;
2480              item->weight.x = item2->weight.x;
2481              item->weight.y = item2->weight.y;
2482              item->aspect.w = item2->aspect.w;
2483              item->aspect.h = item2->aspect.h;
2484              item->aspect.mode = item2->aspect.mode;
2485              item->options = STRDUP(item2->options);
2486              item->col = item2->col;
2487              item->row = item2->row;
2488              item->colspan = item2->colspan;
2489              item->rowspan = item2->rowspan;
2490
2491              pitem = (Edje_Pack_Element_Parser *)item;
2492              pitem->can_override = EINA_TRUE;
2493           }
2494
2495         ep->api.name = STRDUP(ep2->api.name);
2496         if (ep2->api.description) ep->api.description = STRDUP(ep2->api.description);
2497
2498         // copy default description
2499         ob_collections_group_parts_part_description();
2500         ed = ep->default_desc;
2501         parent_desc = ed2 = ep2->default_desc;
2502         ed->state.name = STRDUP(ed2->state.name);
2503         ed->state.value = ed2->state.value;
2504         st_collections_group_parts_part_description_inherit();
2505         parent_desc = NULL;
2506
2507         // copy other description
2508         for (j = 0 ; j < ep2->other.desc_count ; j++)
2509           {
2510              ob_collections_group_parts_part_description();
2511              ed = ep->other.desc[j];
2512              parent_desc = ed2 = ep2->other.desc[j];
2513              ed->state.name = STRDUP(ed2->state.name);
2514              ed->state.value = ed2->state.value;
2515              st_collections_group_parts_part_description_inherit();
2516              parent_desc = NULL;
2517           }
2518      }
2519
2520    //copy programs
2521    for (j = 0 ; j < pc2->programs.fnmatch_count ; j++)
2522      {
2523         ob_collections_group_programs_program();
2524         _edje_program_copy(current_program, pc2->programs.fnmatch[j]);
2525      }
2526    for (j = 0 ; j < pc2->programs.strcmp_count ; j++)
2527      {
2528         ob_collections_group_programs_program();
2529         _edje_program_copy(current_program, pc2->programs.strcmp[j]);
2530      }
2531    for (j = 0 ; j < pc2->programs.strncmp_count ; j++)
2532      {
2533         ob_collections_group_programs_program();
2534         _edje_program_copy(current_program, pc2->programs.strncmp[j]);
2535      }
2536    for (j = 0 ; j < pc2->programs.strrncmp_count ; j++)
2537      {
2538         ob_collections_group_programs_program();
2539         _edje_program_copy(current_program, pc2->programs.strrncmp[j]);
2540      }
2541    for (j = 0 ; j < pc2->programs.nocmp_count ; j++)
2542      {
2543         ob_collections_group_programs_program();
2544         _edje_program_copy(current_program, pc2->programs.nocmp[j]);
2545      }
2546
2547    Code *cd, *cd2;
2548    Code_Program *cp, *cp2;
2549    Edje_Part_Collection_Directory_Entry *de;
2550
2551    de = eina_hash_find(edje_file->collection, pc2->part);
2552    cd2 = eina_list_nth(codes, de->id);
2553    cd = eina_list_data_get(eina_list_last(codes));
2554
2555    EINA_LIST_FOREACH(cd2->programs, l, cp2)
2556      {
2557         cp = mem_alloc(SZ(Code_Program));
2558
2559         cp->l1 = cp2->l1;
2560         cp->l2 = cp2->l2;
2561         cp->script = STRDUP(cp2->script);
2562         cd->is_lua = cd2->is_lua;
2563         cd->shared = cd2->shared;
2564         cd->programs = eina_list_append(cd->programs, cp);
2565         data_queue_copied_anonymous_lookup(pc, &(cp2->id), &(cp->id));
2566      }
2567
2568    free(parent_name);
2569    #undef STRDUP
2570 }
2571
2572 /**
2573     @page edcref
2574     @property
2575         script_only
2576     @parameters
2577         [on/off]
2578     @effect
2579         The flag (on/off) as to if this group is defined ONLY by script
2580         callbacks such as init(), resize() and shutdown()
2581     @endproperty
2582 */
2583 static void
2584 st_collections_group_script_only(void)
2585 {
2586    Edje_Part_Collection *pc;
2587
2588    check_arg_count(1);
2589
2590    pc = eina_list_data_get(eina_list_last(edje_collections));
2591    pc->lua_script_only = parse_bool(0);
2592 }
2593
2594 /**
2595     @page edcref
2596     @property
2597         alias
2598     @parameters
2599         [aditional group name]
2600     @effect
2601         Additional name to serve as identifier. Defining multiple aliases is
2602         supported.
2603     @endproperty
2604 */
2605 static void
2606 st_collections_group_alias(void)
2607 {
2608    Edje_Part_Collection_Directory_Entry *alias;
2609    Edje_Part_Collection_Directory_Entry *tmp;
2610    Eina_List *l;
2611
2612    check_arg_count(1);
2613
2614    alias = mem_alloc(SZ(Edje_Part_Collection_Directory_Entry));
2615    alias->id = current_de->id;
2616    alias->entry = parse_str(0);
2617
2618    EINA_LIST_FOREACH(aliases, l, tmp)
2619      if (strcmp(alias->entry, tmp->entry) == 0)
2620        {
2621           Edje_Part_Collection *pc;
2622
2623           pc = eina_list_nth(edje_collections, tmp->id);
2624           INF("overriding alias ('%s' => '%s') to ('%s' => '%s')",
2625               tmp->entry, pc->part,
2626               alias->entry, current_de->entry);
2627           aliases = eina_list_remove_list(aliases, l);
2628           free(tmp);
2629           break;
2630        }
2631
2632    aliases = eina_list_append(aliases, alias);
2633 }
2634
2635 /**
2636     @page edcref
2637     @property
2638         min
2639     @parameters
2640         [width] [height]
2641     @effect
2642         The minimum size for the container defined by the composition of the
2643         parts. It is not enforced.
2644     @endproperty
2645 */
2646 static void
2647 st_collections_group_min(void)
2648 {
2649    Edje_Part_Collection *pc;
2650
2651    check_arg_count(2);
2652
2653    pc = eina_list_data_get(eina_list_last(edje_collections));
2654    pc->prop.min.w = parse_int_range(0, 0, 0x7fffffff);
2655    pc->prop.min.h = parse_int_range(1, 0, 0x7fffffff);
2656 }
2657
2658 /**
2659     @page edcref
2660     @property
2661         max
2662     @parameters
2663         [width] [height]
2664     @effect
2665         The maximum size for the container defined by the totality of the
2666         parts. It is not enforced.
2667     @endproperty
2668 */
2669 static void
2670 st_collections_group_max(void)
2671 {
2672    Edje_Part_Collection *pc;
2673
2674    check_arg_count(2);
2675
2676    pc = eina_list_data_get(eina_list_last(edje_collections));
2677    pc->prop.max.w = parse_int_range(0, 0, 0x7fffffff);
2678    pc->prop.max.h = parse_int_range(1, 0, 0x7fffffff);
2679 }
2680
2681 /**
2682    @page edcref
2683    @property
2684        broadcast_signal
2685    @parameters
2686        [broadcast]
2687    @effect
2688        Signal got automatically broadcasted to all sub group part. Default to
2689        true since 1.1.
2690    @endproperty
2691 */
2692 static void
2693 st_collections_group_broadcast_signal(void)
2694 {
2695    Edje_Part_Collection *pc;
2696
2697    check_arg_count(1);
2698
2699    pc = eina_list_data_get(eina_list_last(edje_collections));
2700    pc->broadcast_signal = parse_bool(0);
2701 }
2702
2703 /**
2704     @page edcref
2705     @block
2706         script
2707     @context
2708         ..
2709         group {
2710             script {
2711                 //embryo script
2712             }
2713             ..
2714             program {
2715                 script {
2716                     //embryo script
2717                 }
2718             }
2719             ..
2720         }
2721         ..
2722     @description
2723         This block is used to "inject" embryo scripts to a given Edje theme and
2724         it functions in two modalities. When it's included inside a "program"
2725         block, the script will be executed every time the program is run, on
2726         the other hand, when included directly into a "group", "part" or
2727         "description" block, it will be executed once at load time, in the
2728         load order.
2729     @endblock
2730 */
2731 static void
2732 ob_collections_group_script(void)
2733 {
2734    Code *cd;
2735
2736    cd = eina_list_data_get(eina_list_last(codes));
2737
2738    if (!is_verbatim()) track_verbatim(1);
2739    else
2740      {
2741         char *s;
2742
2743         s = get_verbatim();
2744         if (s)
2745           {
2746              cd->l1 = get_verbatim_line1();
2747              cd->l2 = get_verbatim_line2();
2748              if (cd->shared)
2749                {
2750                   ERR("parse error %s:%i. There is already an existing script section for the group",
2751                       file_in, line - 1);
2752                   exit(-1);
2753                }
2754              cd->shared = s;
2755              cd->original = strdup(s);
2756              cd->is_lua = 0;
2757              set_verbatim(NULL, 0, 0);
2758           }
2759      }
2760 }
2761
2762 static void
2763 ob_collections_group_lua_script(void)
2764 {
2765    Code *cd;
2766
2767    cd = eina_list_data_get(eina_list_last(codes));
2768
2769    if (!is_verbatim()) track_verbatim(1);
2770    else
2771      {
2772         char *s;
2773
2774         s = get_verbatim();
2775         if (s)
2776           {
2777              cd->l1 = get_verbatim_line1();
2778              cd->l2 = get_verbatim_line2();
2779              if (cd->shared)
2780                {
2781                   ERR("parse error %s:%i. There is already an existing script section for the group",
2782                       file_in, line - 1);
2783                   exit(-1);
2784                }
2785              cd->shared = s;
2786              cd->is_lua = 1;
2787              set_verbatim(NULL, 0, 0);
2788           }
2789      }
2790 }
2791
2792 static void
2793 st_collections_group_data_item(void)
2794 {
2795    Edje_Part_Collection *pc;
2796    Edje_String *es;
2797    char *key;
2798
2799    check_arg_count(2);
2800
2801    pc = eina_list_data_get(eina_list_last(edje_collections));
2802
2803    if (!pc->data)
2804      pc->data = eina_hash_string_small_new(free);
2805
2806    key = parse_str(0);
2807
2808    es = mem_alloc(SZ(Edje_String));
2809    es->str = parse_str(1);
2810
2811    if (eina_hash_find(pc->data, key))
2812      eina_hash_modify(pc->data, key, es);
2813    else
2814      eina_hash_direct_add(pc->data, key, es);
2815 }
2816
2817 /**
2818     @page edcref
2819     @property
2820         orientation
2821     @parameters
2822     enum AUTO, LTR, RTL
2823     @effect
2824         This defines GROUP orientation.
2825         This is useful if you want match interface orientation with language.
2826         AUTO  - Follow system defs.
2827         LTR  - suitable for Left To Right Languages (latin)
2828         RTL - suitable for Right To Left Languages (Hebrew, Arabic interface)
2829     @endproperty
2830 */
2831 static void
2832 st_collections_group_orientation(void)
2833 {
2834    Edje_Part_Collection *pc;
2835
2836    check_arg_count(1);
2837
2838    pc = eina_list_data_get(eina_list_last(edje_collections));
2839    pc->prop.orientation = parse_enum(0,
2840          "AUTO", EDJE_ORIENTATION_AUTO,
2841          "LTR", EDJE_ORIENTATION_LTR,
2842          "RTL", EDJE_ORIENTATION_RTL,
2843          NULL);
2844 }
2845
2846 /**
2847     @page edcref
2848     @block
2849         limits
2850     @context
2851         group {
2852             limits {
2853                 vertical: "limit_name" height_barrier;
2854                 horizontal: "limit_name" width_barrier;
2855                 ..
2856             }
2857             ..
2858         }
2859         ..
2860     @description
2861         This block is used to trigger some signal when the Edje object is resized.
2862     @endblock
2863
2864     @page edcref
2865     @property
2866         vertical
2867     @parameters
2868         [name] [height barrier]
2869     @effect
2870         It will send a signal: "limit,name,over" when the object is resized and pass
2871         the limit by growing over it. And it will send: "limit,name,below" when
2872         it pass below that limit.
2873         This limit will be applied on the y absis and is expressed in pixels.
2874     @endproperty
2875 */
2876 static void
2877 st_collections_group_limits_vertical(void)
2878 {
2879    Edje_Part_Collection *pc;
2880    Edje_Limit *el;
2881
2882    check_arg_count(2);
2883
2884    el = mem_alloc(SZ(Edje_Limit));
2885
2886    pc = eina_list_data_get(eina_list_last(edje_collections));
2887    pc->limits.vertical_count++;
2888    pc->limits.vertical = realloc(pc->limits.vertical, pc->limits.vertical_count * sizeof (Edje_Limit *));
2889    if (!pc->limits.vertical || !el)
2890      {
2891         ERR("Not enough memory.");
2892         exit(-1);
2893      }
2894
2895    pc->limits.vertical[pc->limits.vertical_count - 1] = el;
2896
2897    el->name = parse_str(0);
2898    el->value = parse_int_range(1, 1, 0xffff);
2899 }
2900
2901 /**
2902     @page edcref
2903     @property
2904         horizontal
2905     @parameters
2906         [name] [width barrier]
2907     @effect
2908         It will send a signal: "limit,name,over" when the object is resized and pass
2909         the limit by growing over it. And it will send: "limit,name,below" when
2910         it pass below that limit.
2911         This limit will be applied on the x absis and is expressed in pixels.
2912     @endproperty
2913 */
2914 static void
2915 st_collections_group_limits_horizontal(void)
2916 {
2917    Edje_Part_Collection *pc;
2918    Edje_Limit *el;
2919
2920    check_arg_count(2);
2921
2922    el = mem_alloc(SZ(Edje_Limit));
2923
2924    pc = eina_list_data_get(eina_list_last(edje_collections));
2925    pc->limits.horizontal_count++;
2926    pc->limits.horizontal = realloc(pc->limits.horizontal, pc->limits.horizontal_count * sizeof (Edje_Limit *));
2927    if (!pc->limits.horizontal || !el)
2928      {
2929         ERR("Not enough memory.");
2930         exit(-1);
2931      }
2932
2933    pc->limits.horizontal[pc->limits.horizontal_count - 1] = el;
2934
2935    el->name = parse_str(0);
2936    el->value = parse_int_range(1, 1, 0xffff);
2937 }
2938
2939 /**
2940     @page edcref
2941     @block
2942         parts
2943     @context
2944         group {
2945             parts {
2946                 alias: "theme_part_path" "real_part_path";
2947                 ..
2948             }
2949         }
2950     @description
2951         Alias of part give a chance to let the designer put the real one
2952         in a box or reuse one from a GROUP or inside a BOX.
2953     @endblock
2954 */
2955 static void
2956 st_collections_group_parts_alias(void)
2957 {
2958    Edje_Part_Collection *pc;
2959    const char *alias;
2960    const char *aliased;
2961
2962    check_arg_count(2);
2963
2964    pc = eina_list_data_get(eina_list_last(edje_collections));
2965
2966    alias = parse_str(0);
2967    aliased = parse_str(1);
2968
2969    if (!pc->alias) pc->alias = eina_hash_string_small_new(NULL);
2970    eina_hash_add(pc->alias, alias, aliased);
2971
2972    if (!pc->aliased) pc->aliased = eina_hash_string_small_new(NULL);
2973    eina_hash_add(pc->aliased, aliased, alias);
2974 }
2975
2976
2977 /**
2978     @page edcref
2979     @block
2980         part
2981     @context
2982         group {
2983             parts {
2984                 ..
2985                 part {
2986                     name: "partname";
2987                     type: IMAGE;
2988                     mouse_events:  1;
2989                     repeat_events: 0;
2990                     ignore_flags: NONE;
2991                     clip_to: "anotherpart";
2992                     source:  "groupname";
2993                     pointer_mode: AUTOGRAB;
2994                     use_alternate_font_metrics: 0;
2995
2996                     description { }
2997                     dragable { }
2998                     items { }
2999                 }
3000                 ..
3001             }
3002         }
3003     @description
3004         Parts are used to represent the most basic design elements of the
3005         theme, for example, a part can represent a line in a border or a label
3006         on a button.
3007     @endblock
3008 */
3009 static Edje_Part *
3010 edje_cc_handlers_part_make(void)
3011 {  /* Doing ob_collections_group_parts_part() job, without hierarchy */
3012    Edje_Part_Collection *pc;
3013    Edje_Part *ep;
3014    Edje_Part_Parser *epp;
3015
3016    ep = mem_alloc(SZ(Edje_Part_Parser));
3017
3018    pc = eina_list_data_get(eina_list_last(edje_collections));
3019    pc->parts_count++;
3020    pc->parts = realloc(pc->parts, pc->parts_count * sizeof (Edje_Part *));
3021    if (!pc->parts)
3022      {
3023         ERR("Not enough memory.");
3024         exit(-1);
3025      }
3026    current_part = pc->parts[pc->parts_count - 1] = ep;
3027
3028    ep->id = pc->parts_count - 1;
3029    ep->type = EDJE_PART_TYPE_IMAGE;
3030    ep->mouse_events = 1;
3031    ep->repeat_events = 0;
3032    ep->ignore_flags = EVAS_EVENT_FLAG_NONE;
3033    ep->scale = 0;
3034    ep->pointer_mode = EVAS_OBJECT_POINTER_MODE_AUTOGRAB;
3035    ep->precise_is_inside = 0;
3036    ep->use_alternate_font_metrics = 0;
3037    ep->access = 0;
3038    ep->clip_to_id = -1;
3039    ep->dragable.confine_id = -1;
3040    ep->dragable.event_id = -1;
3041    ep->items = NULL;
3042    ep->nested_children_count = 0;
3043
3044    epp = (Edje_Part_Parser *)ep;
3045    epp->reorder.insert_before = NULL;
3046    epp->reorder.insert_after = NULL;
3047    epp->reorder.before = NULL;
3048    epp->reorder.after = NULL;
3049    epp->reorder.linked_prev = 0;
3050    epp->reorder.linked_next = 0;
3051    epp->reorder.done = EINA_FALSE;
3052    epp->can_override = EINA_FALSE;
3053
3054    return ep;
3055 }
3056
3057 static void
3058 ob_collections_group_parts_part(void)
3059 {
3060    Edje_Part *cp = current_part;  /* Save to restore on pop    */
3061    Edje_Part *ep = edje_cc_handlers_part_make(); /* This changes current_part */
3062    Edje_Part *prnt;
3063
3064    /* Add this new part to hierarchy stack (removed part finished parse) */
3065    edje_cc_handlers_hierarchy_push(ep, cp);
3066
3067    prnt = edje_cc_handlers_hierarchy_parent_get();
3068    if (prnt)  /* This is the child of parent in stack */
3069      prnt->nested_children_count++;
3070 }
3071
3072 /**
3073     @page edcref
3074     @property
3075         name
3076     @parameters
3077         [part name]
3078     @effect
3079         The part's name will be used as reference in the theme's relative
3080         positioning system, by programs and in some cases by the application.
3081         It must be unique within the group.
3082     @endproperty
3083 */
3084 static void
3085 st_collections_group_parts_part_name(void)
3086 {
3087    Edje_Part_Collection *pc;
3088    Edje_Part *ep;
3089    Edje_Part_Parser *epp;
3090
3091    check_arg_count(1);
3092
3093    pc = eina_list_data_get(eina_list_last(edje_collections));
3094    ep = current_part;
3095    ep->name = parse_str(0);
3096
3097    if (ep->name)
3098      {
3099         unsigned int i;
3100
3101         for (i = 0; i < (pc->parts_count - 1); i++)
3102           {  /* Compare name only if did NOT updated ep from hircy pop */
3103              if ((ep != pc->parts[i]) &&
3104                    (pc->parts[i]->name &&
3105                     (!strcmp(pc->parts[i]->name, ep->name))))
3106                {
3107                   epp = (Edje_Part_Parser *)pc->parts[i];
3108                   if (!epp->can_override)
3109                     {
3110                        ERR("parse error %s:%i. There is already a part of the name %s",
3111                            file_in, line - 1, ep->name);
3112                        exit(-1);
3113                     }
3114                   else
3115                     {
3116                        free(ep);
3117                        pc->parts_count--;
3118                        pc->parts = realloc(pc->parts, pc->parts_count * sizeof (Edje_Part *));
3119                        current_part = pc->parts[i];
3120                        edje_cc_handlers_hierarchy_rename(ep, current_part);
3121                        ep = current_part;
3122                        epp->can_override = EINA_FALSE;
3123                        break;
3124                     }
3125                }
3126           }
3127      }
3128 }
3129
3130 /**
3131     @page edcref
3132     @property
3133         type
3134     @parameters
3135         [TYPE]
3136     @effect
3137         Set the type (all caps) from among the available types, it's set to
3138         IMAGE by default. Valid types:
3139             @li RECT
3140             @li TEXT
3141             @li IMAGE
3142             @li SWALLOW
3143             @li TEXTBLOCK
3144             @li GROUP
3145             @li BOX
3146             @li TABLE
3147             @li EXTERNAL
3148             @li PROXY
3149             @li SPACER
3150     @endproperty
3151 */
3152 static void
3153 st_collections_group_parts_part_type(void)
3154 {
3155    unsigned int type;
3156
3157    check_arg_count(1);
3158
3159    type = parse_enum(0,
3160                      "NONE", EDJE_PART_TYPE_NONE,
3161                      "RECT", EDJE_PART_TYPE_RECTANGLE,
3162                      "TEXT", EDJE_PART_TYPE_TEXT,
3163                      "IMAGE", EDJE_PART_TYPE_IMAGE,
3164                      "SWALLOW", EDJE_PART_TYPE_SWALLOW,
3165                      "TEXTBLOCK", EDJE_PART_TYPE_TEXTBLOCK,
3166                      "GROUP", EDJE_PART_TYPE_GROUP,
3167                      "BOX", EDJE_PART_TYPE_BOX,
3168                      "TABLE", EDJE_PART_TYPE_TABLE,
3169                      "EXTERNAL", EDJE_PART_TYPE_EXTERNAL,
3170                      "PROXY", EDJE_PART_TYPE_PROXY,
3171                      "SPACER", EDJE_PART_TYPE_SPACER,
3172                      NULL);
3173
3174    /* handle type change of inherited part */
3175    if (type != current_part->type)
3176      {
3177         Edje_Part_Description_Common *new, *previous;
3178         Edje_Part_Collection *pc;
3179         Edje_Part *ep;
3180         unsigned int i;
3181
3182         /* we don't free old part as we don't remove all reference to them */
3183         part_description_image_cleanup(current_part);
3184
3185         pc = eina_list_data_get(eina_list_last(edje_collections));
3186         ep = current_part;
3187
3188         previous = ep->default_desc;
3189         if (previous)
3190           {
3191              new = _edje_part_description_alloc(type, pc->part, ep->name);
3192              memcpy(new, previous, sizeof (Edje_Part_Description_Common));
3193
3194              ep->default_desc = new;
3195           }
3196
3197         for (i = 0; i < ep->other.desc_count; i++)
3198           {
3199              previous = ep->other.desc[i];
3200              new = _edje_part_description_alloc(type, pc->part, ep->name);
3201              memcpy(new, previous, sizeof (Edje_Part_Description_Common));
3202              ep->other.desc[i] = new;
3203           }
3204      }
3205
3206    current_part->type = type;
3207 }
3208
3209 /**
3210     @page edcref
3211     @property
3212         part
3213     @parameters
3214         [part declaration]
3215     @effect
3216     @code
3217         group {
3218             parts {
3219                 part {
3220                     name: "parent_rect";
3221                     type: RECT;
3222                     description { }
3223                     part {
3224                         name: "nested_rect";
3225                         type: RECT;
3226                         description { }
3227                     }
3228                 }
3229                 ..
3230             }
3231         }
3232     @endcode
3233         Nested parts adds hierarchy to edje.
3234         Nested part inherits it's location relatively to the parent part.
3235         To declare a nested part just start a new part within current part decl.
3236         You must define parent part name before adding nested parts.
3237     @endproperty
3238     @since 1.7.0
3239 */
3240
3241 /**
3242     @page edcref
3243     @property
3244         insert_before
3245     @parameters
3246         [another part's name]
3247     @effect
3248         The part's name which this part is inserted before. One part cannot
3249         have both insert_before and insert_after. One part cannot refer
3250         more than one by insert_before.
3251     @endproperty
3252     @since 1.1.0
3253 */
3254 static void
3255 st_collections_group_parts_part_insert_before(void)
3256 {
3257    Edje_Part_Parser *epp;
3258    check_arg_count(1);
3259
3260    epp = (Edje_Part_Parser *)current_part;
3261    epp->reorder.insert_before = parse_str(0);
3262 }
3263
3264 /**
3265     @page edcref
3266     @property
3267         insert_after
3268     @parameters
3269         [another part's name]
3270     @effect
3271         The part's name which this part is inserted after. One part cannot
3272         have both insert_before and insert_after. One part cannot refer
3273         more than one by insert_after.
3274     @endproperty
3275     @since 1.1.0
3276 */
3277 static void
3278 st_collections_group_parts_part_insert_after(void)
3279 {
3280    Edje_Part_Parser *epp;
3281    check_arg_count(1);
3282
3283    epp = (Edje_Part_Parser *)current_part;
3284    epp->reorder.insert_after = parse_str(0);
3285 }
3286
3287 /**
3288     @page edcref
3289     @property
3290         mouse_events
3291     @parameters
3292         [1 or 0]
3293     @effect
3294         Specifies whether the part will emit signals, although it is named
3295         "mouse_events", disabling it (0) will prevent the part from emitting
3296         any type of signal at all. It's set to 1 by default.
3297     @endproperty
3298 */
3299 static void
3300 st_collections_group_parts_part_mouse_events(void)
3301 {
3302    check_arg_count(1);
3303
3304    current_part->mouse_events = parse_bool(0);
3305 }
3306
3307 /**
3308     @page edcref
3309     @property
3310         repeat_events
3311     @parameters
3312         [1 or 0]
3313     @effect
3314         Specifies whether a part echoes a mouse event to other parts below the
3315         pointer (1), or not (0). It's set to 0 by default.
3316     @endproperty
3317 */
3318 static void
3319 st_collections_group_parts_part_repeat_events(void)
3320 {
3321    check_arg_count(1);
3322
3323    current_part->repeat_events = parse_bool(0);
3324 }
3325
3326 /**
3327     @page edcref
3328     @property
3329         ignore_flags
3330     @parameters
3331         [FLAG] ...
3332     @effect
3333         Specifies whether events with the given flags should be ignored,
3334         i.e., will not have the signals emitted to the parts. Multiple flags
3335         must be separated by spaces, the effect will be ignoring all events
3336         with one of the flags specified. Possible flags:
3337             @li NONE (default value, no event will be ignored)
3338             @li ON_HOLD
3339     @endproperty
3340 */
3341 static void
3342 st_collections_group_parts_part_ignore_flags(void)
3343 {
3344    check_min_arg_count(1);
3345
3346    current_part->ignore_flags = parse_flags(0,
3347                                   "NONE", EVAS_EVENT_FLAG_NONE,
3348                                   "ON_HOLD", EVAS_EVENT_FLAG_ON_HOLD,
3349                                   NULL);
3350 }
3351
3352 /**
3353     @page edcref
3354     @property
3355         scale
3356     @parameters
3357         [1 or 0]
3358     @effect
3359         Specifies whether the part will scale its size with an edje scaling
3360         factor. By default scale is off (0) and the default scale factor is
3361         1.0 - that means no scaling. This would be used to scale properties
3362         such as font size, min/max size of the part, and possibly can be used
3363         to scale based on DPI of the target device. The reason to be selective
3364         is that some things work well being scaled, others do not, so the
3365         designer gets to choose what works best.
3366     @endproperty
3367 */
3368 static void
3369 st_collections_group_parts_part_scale(void)
3370 {
3371    check_arg_count(1);
3372
3373    current_part->scale = parse_bool(0);
3374 }
3375
3376 /**
3377     @page edcref
3378     @property
3379         pointer_mode
3380     @parameters
3381         [MODE]
3382     @effect
3383         Sets the mouse pointer behavior for a given part. The default value is
3384         AUTOGRAB. Aviable modes:
3385             @li AUTOGRAB, when the part is clicked and the button remains
3386                 pressed, the part will be the source of all future mouse
3387                 signals emitted, even outside the object, until the button is
3388                 released.
3389             @li NOGRAB, the effect will be limited to the part's container.
3390     @endproperty
3391 */
3392 static void
3393 st_collections_group_parts_part_pointer_mode(void)
3394 {
3395    check_arg_count(1);
3396
3397    current_part->pointer_mode = parse_enum(0,
3398                                  "AUTOGRAB", EVAS_OBJECT_POINTER_MODE_AUTOGRAB,
3399                                  "NOGRAB", EVAS_OBJECT_POINTER_MODE_NOGRAB,
3400                                  NULL);
3401 }
3402
3403 /**
3404     @page edcref
3405     @property
3406         precise_is_inside
3407     @parameters
3408         [1 or 0]
3409     @effect
3410         Enables precise point collision detection for the part, which is more
3411         resource intensive. Disabled by default.
3412     @endproperty
3413 */
3414 static void
3415 st_collections_group_parts_part_precise_is_inside(void)
3416 {
3417    check_arg_count(1);
3418
3419    current_part->precise_is_inside = parse_bool(0);
3420 }
3421
3422 /**
3423     @page edcref
3424     @property
3425         use_alternate_font_metrics
3426     @parameters
3427         [1 or 0]
3428     @effect
3429         Only affects text and textblock parts, when enabled Edje will use
3430         different size measurement functions. Disabled by default. (note from
3431         the author: I don't know what this is exactly useful for?)
3432     @endproperty
3433 */
3434 static void
3435 st_collections_group_parts_part_use_alternate_font_metrics(void)
3436 {
3437    check_arg_count(1);
3438
3439    current_part->use_alternate_font_metrics = parse_bool(0);
3440 }
3441
3442 /**
3443     @page edcref
3444     @property
3445         clip_to
3446     @parameters
3447         [another part's name]
3448     @effect
3449         Only renders the area of part that coincides with another part's
3450         container. Overflowing content will not be displayed. Note that
3451         the part being clipped to can only be a rectangle part.
3452     @endproperty
3453 */
3454 static void
3455 st_collections_group_parts_part_clip_to_id(void)
3456 {
3457    Edje_Part_Collection *pc;
3458
3459    check_arg_count(1);
3460
3461    pc = eina_list_data_get(eina_list_last(edje_collections));
3462      {
3463         char *name;
3464
3465         name = parse_str(0);
3466         data_queue_part_lookup(pc, name, &(current_part->clip_to_id));
3467         free(name);
3468      }
3469 }
3470
3471 /**
3472     @page edcref
3473     @property
3474         source
3475     @parameters
3476         [another group's name]
3477     @effect
3478         Only available to GROUP or TEXTBLOCK parts. Swallows the specified 
3479         group into the part's container if a GROUP. If TEXTBLOCK it is used
3480         for the group to be loaded and used for selection display UNDER the
3481         selected text. source2 is used for on top of the selected text, if
3482         source2 is specified.
3483     @endproperty
3484 */
3485 static void
3486 st_collections_group_parts_part_source(void)
3487 {
3488    check_arg_count(1);
3489
3490    //FIXME: validate this somehow (need to decide on the format also)
3491    current_part->source = parse_str(0);
3492    data_queue_group_lookup(current_part->source, current_part);
3493 }
3494
3495 /**
3496     @page edcref
3497     @property
3498         source2
3499     @parameters
3500         [another group's name]
3501     @effect
3502         Only available to TEXTBLOCK parts. It is used for the group to be 
3503         loaded and used for selection display OVER the selected text. source
3504         is used for under of the selected text, if source is specified.
3505     @endproperty
3506 */
3507 static void
3508 st_collections_group_parts_part_source2(void)
3509 {
3510    check_arg_count(1);
3511
3512    //FIXME: validate this somehow (need to decide on the format also)
3513    current_part->source2 = parse_str(0);
3514    data_queue_group_lookup(current_part->source2, current_part);
3515 }
3516
3517 /**
3518     @page edcref
3519     @property
3520         source3
3521     @parameters
3522         [another group's name]
3523     @effect
3524         Only available to TEXTBLOCK parts. It is used for the group to be 
3525         loaded and used for cursor display UNDER the cursor position. source4
3526         is used for over the cursor text, if source4 is specified.
3527     @endproperty
3528 */
3529 static void
3530 st_collections_group_parts_part_source3(void)
3531 {
3532    check_arg_count(1);
3533
3534    //FIXME: validate this somehow (need to decide on the format also)
3535    current_part->source3 = parse_str(0);
3536    data_queue_group_lookup(current_part->source3, current_part);
3537 }
3538
3539 /**
3540     @page edcref
3541     @property
3542         source4
3543     @parameters
3544         [another group's name]
3545     @effect
3546         Only available to TEXTBLOCK parts. It is used for the group to be 
3547         loaded and used for cursor display OVER the cursor position. source3
3548         is used for under the cursor text, if source4 is specified.
3549     @endproperty
3550 */
3551 static void
3552 st_collections_group_parts_part_source4(void)
3553 {
3554    check_arg_count(1);
3555
3556    //FIXME: validate this somehow (need to decide on the format also)
3557    current_part->source4 = parse_str(0);
3558    data_queue_group_lookup(current_part->source4, current_part);
3559 }
3560
3561 /**
3562     @page edcref
3563     @property
3564         source5
3565     @parameters
3566         [another group's name]
3567     @effect
3568         Only available to TEXTBLOCK parts. It is used for the group to be 
3569         loaded and used for anchors display UNDER the anchor position. source6
3570         is used for over the anchors text, if source6 is specified.
3571     @endproperty
3572 */
3573 static void
3574 st_collections_group_parts_part_source5(void)
3575 {
3576    check_arg_count(1);
3577
3578    //FIXME: validate this somehow (need to decide on the format also)
3579    current_part->source5 = parse_str(0);
3580    data_queue_group_lookup(current_part->source5, current_part);
3581 }
3582
3583 /**
3584     @page edcref
3585     @property
3586         source6
3587     @parameters
3588         [another group's name]
3589     @effect
3590         Only available to TEXTBLOCK parts. It is used for the group to be 
3591         loaded and used for anchor display OVER the anchor position. source5
3592         is used for under the anchor text, if source6 is specified.
3593     @endproperty
3594 */
3595 static void
3596 st_collections_group_parts_part_source6(void)
3597 {
3598    check_arg_count(1);
3599
3600    //FIXME: validate this somehow (need to decide on the format also)
3601    current_part->source6 = parse_str(0);
3602    data_queue_group_lookup(current_part->source6, current_part);
3603 }
3604
3605 /**
3606     @page edcref
3607
3608     @property
3609         effect
3610     @parameters
3611         [EFFECT]
3612         (optional) [SHADOW DIRECTION]
3613     @effect
3614         Causes Edje to draw the selected effect among:
3615         @li PLAIN
3616         @li OUTLINE
3617         @li SOFT_OUTLINE
3618         @li SHADOW
3619         @li SOFT_SHADOW
3620         @li OUTLINE_SHADOW
3621         @li OUTLINE_SOFT_SHADOW
3622         @li FAR_SHADOW
3623         @li FAR_SOFT_SHADOW
3624         @li GLOW
3625
3626         Shadow directions (default if not given is BOTTOM_RIGHT):
3627         @li BOTTOM_RIGHT
3628         @li BOTTOM
3629         @li BOTTOM_LEFT
3630         @li LEFT
3631         @li TOP_LEFT
3632         @li TOP
3633         @li TOP_RIGHT
3634         @li RIGHT
3635     @endproperty
3636 */
3637 static void
3638 st_collections_group_parts_part_effect(void)
3639 {
3640    check_min_arg_count(1);
3641
3642    current_part->effect = parse_enum(0,
3643                "NONE", EDJE_TEXT_EFFECT_NONE,
3644                "PLAIN", EDJE_TEXT_EFFECT_PLAIN,
3645                "OUTLINE", EDJE_TEXT_EFFECT_OUTLINE,
3646                "SOFT_OUTLINE", EDJE_TEXT_EFFECT_SOFT_OUTLINE,
3647                "SHADOW", EDJE_TEXT_EFFECT_SHADOW,
3648                "SOFT_SHADOW", EDJE_TEXT_EFFECT_SOFT_SHADOW,
3649                "OUTLINE_SHADOW", EDJE_TEXT_EFFECT_OUTLINE_SHADOW,
3650                "OUTLINE_SOFT_SHADOW", EDJE_TEXT_EFFECT_OUTLINE_SOFT_SHADOW,
3651                "FAR_SHADOW", EDJE_TEXT_EFFECT_FAR_SHADOW,
3652                "FAR_SOFT_SHADOW", EDJE_TEXT_EFFECT_FAR_SOFT_SHADOW,
3653                "GLOW", EDJE_TEXT_EFFECT_GLOW,
3654                NULL);
3655    if (get_arg_count() >= 2)
3656      {
3657         unsigned char shadow;
3658         
3659         shadow = parse_enum(1,
3660                "BOTTOM_RIGHT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_BOTTOM_RIGHT,
3661                "BOTTOM", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_BOTTOM,
3662                "BOTTOM_LEFT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_BOTTOM_LEFT,
3663                "LEFT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_LEFT,
3664                "TOP_LEFT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_TOP_LEFT,
3665                "TOP", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_TOP,
3666                "TOP_RIGHT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_TOP_RIGHT,
3667                "RIGHT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_RIGHT,
3668                NULL);
3669         EDJE_TEXT_EFFECT_SHADOW_DIRECTION_SET(current_part->effect, shadow);
3670      }
3671 }
3672
3673 /**
3674     @page edcref
3675     @property
3676         entry_mode
3677     @parameters
3678         [MODE]
3679     @effect
3680         Sets the edit mode for a textblock part to one of:
3681         @li NONE
3682         @li PLAIN
3683         @li EDITABLE
3684         @li PASSWORD
3685         It causes the part be editable if the edje object has the keyboard
3686         focus AND the part has the edje focus (or selectable always
3687         regardless of focus) and in the event of password mode, not
3688         selectable and all text chars replaced with *'s but editable and
3689         pastable.
3690     @endproperty
3691 */
3692 static void
3693 st_collections_group_parts_part_entry_mode(void)
3694 {
3695    check_arg_count(1);
3696
3697    current_part->entry_mode = parse_enum(0,
3698                                "NONE", EDJE_ENTRY_EDIT_MODE_NONE,
3699                                "PLAIN", EDJE_ENTRY_EDIT_MODE_SELECTABLE,
3700                                "EDITABLE", EDJE_ENTRY_EDIT_MODE_EDITABLE,
3701                                "PASSWORD", EDJE_ENTRY_EDIT_MODE_PASSWORD,
3702                                NULL);
3703 }
3704
3705 /**
3706     @page edcref
3707     @property
3708         select_mode
3709     @parameters
3710         [MODE]
3711     @effect
3712         Sets the selection mode for a textblock part to one of:
3713         @li DEFAULT selection mode is what you would expect on any desktop. Press
3714         mouse, drag and release to end.
3715         @li EXPLICIT mode requires the application
3716         controlling the edje object has to explicitly begin and end selection
3717         modes, and the selection itself is dragable at both ends.
3718     @endproperty
3719 */
3720 static void
3721 st_collections_group_parts_part_select_mode(void)
3722 {
3723    check_arg_count(1);
3724
3725    current_part->select_mode = parse_enum(0,
3726                                 "DEFAULT", EDJE_ENTRY_SELECTION_MODE_DEFAULT,
3727                                 "EXPLICIT", EDJE_ENTRY_SELECTION_MODE_EXPLICIT,
3728                                 "BLOCK_HANDLE", EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE,
3729                                 NULL);
3730 }
3731
3732 /**
3733     @page edcref
3734     @property
3735         cursor_mode
3736     @parameters
3737         [MODE]
3738     @effect
3739         Sets the cursor mode for a textblock part to one of:
3740         @li UNDER cursor mode means the cursor will draw below the character pointed
3741         at. That's the default.
3742         @li BEFORE cursor mode means the cursor is drawn as a vertical line before
3743         the current character, just like many other GUI toolkits handle it.
3744     @endproperty
3745 */
3746 static void
3747 st_collections_group_parts_part_cursor_mode(void)
3748 {
3749    check_arg_count(1);
3750
3751    current_part->cursor_mode = parse_enum(0,
3752                                 "UNDER", EDJE_ENTRY_CURSOR_MODE_UNDER,
3753                                 "BEFORE", EDJE_ENTRY_CURSOR_MODE_BEFORE,
3754                                 NULL);
3755 }
3756
3757 /**
3758     @page edcref
3759     @property
3760         multiline
3761     @parameters
3762         [1 or 0]
3763     @effect
3764         It causes a textblock that is editable to allow multiple lines for
3765         editing.
3766     @endproperty
3767 */
3768 static void
3769 st_collections_group_parts_part_multiline(void)
3770 {
3771    check_arg_count(1);
3772
3773    current_part->multiline = parse_bool(0);
3774 }
3775
3776 /**
3777     @page edcref
3778     @property
3779         access 
3780     @parameters
3781         [1 or 0]
3782     @effect
3783         Specifies whether the part will use accessibility feature (1),
3784         or not (0). It's set to 0 by default.
3785     @endproperty
3786 */
3787 static void
3788 st_collections_group_parts_part_access(void)
3789 {
3790    check_arg_count(1);
3791
3792    current_part->access = parse_bool(0);
3793 }
3794
3795 /**
3796     @page edcref
3797     @block
3798         dragable
3799     @context
3800         part {
3801             ..
3802             dragable {
3803                 confine: "another part";
3804                 events:  "another dragable part";
3805                 x: 0 0 0;
3806                 y: 0 0 0;
3807             }
3808             ..
3809         }
3810     @description
3811         When this block is used the resulting part can be dragged around the
3812         interface, do not confuse with external drag & drop. By default Edje
3813         (and most applications) will attempt to use the minimal size possible
3814         for a dragable part. If the min property is not set in the description
3815         the part will be (most likely) set to 0px width and 0px height, thus
3816         invisible.
3817     @endblock
3818
3819     @property
3820         x
3821     @parameters
3822         [enable/disable] [step] [count]
3823     @effect
3824         Used to setup dragging events for the X axis. The first parameter is
3825         used to enable (1 or -1) and disable (0) dragging along the axis. When
3826         enabled, 1 will set the starting point at 0.0 and -1 at 1.0. The second
3827         parameter takes any integer and will limit movement to values
3828         divisible by it, causing the part to jump from position to position.
3829         The third parameter, (question from the author: What is count for?).
3830     @endproperty
3831 */
3832 static void
3833 st_collections_group_parts_part_dragable_x(void)
3834 {
3835    check_arg_count(3);
3836
3837    current_part->dragable.x = parse_int_range(0, -1, 1);
3838    current_part->dragable.step_x = parse_int_range(1, 0, 0x7fffffff);
3839    current_part->dragable.count_x = parse_int_range(2, 0, 0x7fffffff);
3840 }
3841
3842 /**
3843     @page edcref
3844     @property
3845         y
3846     @parameters
3847         [enable/disable] [step] [count]
3848     @effect
3849         Used to setup dragging events for the Y axis. The first parameter is
3850         used to enable (1 or -1) and disable (0) dragging along the axis. When
3851         enabled, 1 will set the starting point at 0.0 and -1 at 1.0. The second
3852         parameter takes any integer and will limit movement to values
3853         divisibles by it, causing the part to jump from position to position.
3854         The third parameter, (question from the author: What is count for?).
3855     @endproperty
3856 */
3857 static void
3858 st_collections_group_parts_part_dragable_y(void)
3859 {
3860    check_arg_count(3);
3861
3862    current_part->dragable.y = parse_int_range(0, -1, 1);
3863    current_part->dragable.step_y = parse_int_range(1, 0, 0x7fffffff);
3864    current_part->dragable.count_y = parse_int_range(2, 0, 0x7fffffff);
3865 }
3866
3867 /**
3868     @page edcref
3869     @property
3870         confine
3871     @parameters
3872         [another part's name]
3873     @effect
3874         When set, limits the movement of the dragged part to another part's
3875         container. When you use confine don't forget to set a min size for the
3876         part, or the draggie will not show up.
3877     @endproperty
3878 */
3879 static void
3880 st_collections_group_parts_part_dragable_confine(void)
3881 {
3882    Edje_Part_Collection *pc;
3883
3884    check_arg_count(1);
3885
3886    pc = eina_list_data_get(eina_list_last(edje_collections));
3887      {
3888         char *name;
3889
3890         name = parse_str(0);
3891         data_queue_part_lookup(pc, name, &(current_part->dragable.confine_id));
3892         free(name);
3893      }
3894 }
3895
3896 /**
3897     @page edcref
3898     @property
3899         events
3900     @parameters
3901         [another dragable part's name]
3902     @effect
3903         It causes the part to forward the drag events to another part, thus
3904         ignoring them for itself.
3905     @endproperty
3906 */
3907 static void
3908 st_collections_group_parts_part_dragable_events(void)
3909 {
3910    Edje_Part_Collection *pc;
3911
3912    check_arg_count(1);
3913
3914    pc = eina_list_data_get(eina_list_last(edje_collections));
3915      {
3916         char *name;
3917
3918         name = parse_str(0);
3919         data_queue_part_lookup(pc, name, &(current_part->dragable.event_id));
3920         free(name);
3921      }
3922 }
3923
3924 /**
3925     @page edcref
3926     @block
3927         items
3928     @context
3929         part {
3930             ..
3931             box {
3932                 items {
3933                     item {
3934                         type: TYPE;
3935                         source: "some source";
3936                         min: 1 1;
3937                         max: 100 100;
3938                         padding: 1 1 2 2;
3939                     }
3940                     item {
3941                         type: TYPE;
3942                         source: "some other source";
3943                         name: "some name";
3944                         align: 1.0 0.5;
3945                     }
3946                     ..
3947                 }
3948             }
3949             ..
3950         }
3951     @description
3952         On a part of type BOX, this block can be used to set other groups
3953         as elements of the box. These can be mixed with external objects set
3954         by the application through the edje_object_part_box_* API.
3955     @endblock
3956 */
3957 static void ob_collections_group_parts_part_box_items_item(void)
3958 {
3959    Edje_Part *ep;
3960    Edje_Pack_Element *item;
3961    Edje_Pack_Element_Parser *pitem;
3962
3963    ep = current_part;
3964
3965    if ((ep->type != EDJE_PART_TYPE_BOX) && (ep->type != EDJE_PART_TYPE_TABLE))
3966      {
3967         ERR("parse error %s:%i. box attributes in non-BOX or TABLE part.",
3968             file_in, line - 1);
3969         exit(-1);
3970      }
3971
3972    ep->items_count++;
3973    ep->items = realloc(ep->items, sizeof (Edje_Pack_Element*) * ep->items_count);
3974    if (!ep->items)
3975      {
3976         ERR("Not enough memory.");
3977         exit(-1);
3978      }
3979
3980    item = mem_alloc(SZ(Edje_Pack_Element_Parser));
3981    current_item = ep->items[ep->items_count - 1] = item;
3982    item->type = EDJE_PART_TYPE_GROUP;
3983    item->name = NULL;
3984    item->source = NULL;
3985    item->min.w = 0;
3986    item->min.h = 0;
3987    item->prefer.w = 0;
3988    item->prefer.h = 0;
3989    item->max.w = -1;
3990    item->max.h = -1;
3991    item->padding.l = 0;
3992    item->padding.r = 0;
3993    item->padding.t = 0;
3994    item->padding.b = 0;
3995    item->align.x = FROM_DOUBLE(0.5);
3996    item->align.y = FROM_DOUBLE(0.5);
3997    item->weight.x = FROM_DOUBLE(0.0);
3998    item->weight.y = FROM_DOUBLE(0.0);
3999    item->aspect.w = 0;
4000    item->aspect.h = 0;
4001    item->aspect.mode = EDJE_ASPECT_CONTROL_NONE;
4002    item->options = NULL;
4003    item->col = -1;
4004    item->row = -1;
4005    item->colspan = 1;
4006    item->rowspan = 1;
4007    pitem = (Edje_Pack_Element_Parser *)item;
4008    pitem->can_override = EINA_FALSE;
4009 }
4010
4011 /**
4012     @page edcref
4013     @property
4014         type
4015     @parameters
4016         Only GROUP for now (defaults to it)
4017     @effect
4018         Sets the type of the object this item will hold.
4019     @endproperty
4020 */
4021 static void st_collections_group_parts_part_box_items_item_type(void)
4022 {
4023    check_arg_count(1);
4024
4025      {
4026         char *s;
4027
4028         s = parse_str(0);
4029         if (strcmp(s, "GROUP"))
4030           {
4031              ERR("parse error %s:%i. token %s not one of: GROUP.",
4032                  file_in, line - 1, s);
4033              exit(-1);
4034           }
4035         /* FIXME: handle the enum, once everything else is supported */
4036         current_item->type = EDJE_PART_TYPE_GROUP;
4037      }
4038 }
4039
4040 /**
4041     @page edcref
4042     @property
4043         name
4044     @parameters
4045         [name for the object]
4046     @effect
4047         Sets the name of the object via evas_object_name_set().
4048     @endproperty
4049 */
4050 static void st_collections_group_parts_part_box_items_item_name(void)
4051 {
4052    Edje_Part *ep;
4053    Edje_Pack_Element *item;
4054    Edje_Pack_Element_Parser *pitem;
4055
4056    check_arg_count(1);
4057
4058    ep = current_part;
4059    item = ep->items[ep->items_count - 1];
4060
4061    item->name = parse_str(0);
4062
4063      {
4064         unsigned int i;
4065
4066         for (i = 0; i < ep->items_count - 1; ++i)
4067           {
4068              if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item->name)))
4069                {
4070                   pitem = (Edje_Pack_Element_Parser *)ep->items[i];
4071                   if (!pitem->can_override)
4072                     {
4073                        ERR("parse error %s:%i. There is already a item of the name %s",
4074                            file_in, line - 1, item->name);
4075                        exit(-1);
4076                     }
4077                   else
4078                     {
4079                        free(item);
4080                        ep->items_count--;
4081                        ep->items = realloc(ep->items, ep->items_count * sizeof (Edje_Pack_Element *));
4082                        current_item = ep->items[i];
4083                        pitem->can_override = EINA_FALSE;
4084                     }
4085                }
4086           }
4087      }
4088 }
4089
4090 /**
4091     @page edcref
4092     @property
4093         source
4094     @parameters
4095         [another group's name]
4096     @effect
4097         Sets the group this object will be made from.
4098     @endproperty
4099 */
4100 static void st_collections_group_parts_part_box_items_item_source(void)
4101 {
4102    check_arg_count(1);
4103
4104    current_item->source = parse_str(0);
4105    data_queue_group_lookup(current_item->source, current_part);
4106 }
4107
4108 /**
4109     @page edcref
4110     @property
4111         min
4112     @parameters
4113         [width] [height]
4114     @effect
4115         Sets the minimum size hints for this object.
4116     @endproperty
4117 */
4118 static void st_collections_group_parts_part_box_items_item_min(void)
4119 {
4120    check_arg_count(2);
4121
4122    current_item->min.w = parse_int_range(0, 0, 0x7ffffff);
4123    current_item->min.h = parse_int_range(1, 0, 0x7ffffff);
4124 }
4125
4126 /**
4127     @page edcref
4128     @property
4129         prefer
4130     @parameters
4131         [width] [height]
4132     @effect
4133         Sets the preferred size hints for this object.
4134     @endproperty
4135 */
4136 static void st_collections_group_parts_part_box_items_item_prefer(void)
4137 {
4138    check_arg_count(2);
4139
4140    current_item->prefer.w = parse_int_range(0, 0, 0x7ffffff);
4141    current_item->prefer.h = parse_int_range(1, 0, 0x7ffffff);
4142 }
4143 /**
4144     @page edcref
4145     @property
4146         max
4147     @parameters
4148         [width] [height]
4149     @effect
4150         Sets the maximum size hints for this object.
4151     @endproperty
4152 */
4153 static void st_collections_group_parts_part_box_items_item_max(void)
4154 {
4155    check_arg_count(2);
4156
4157    current_item->max.w = parse_int_range(0, 0, 0x7ffffff);
4158    current_item->max.h = parse_int_range(1, 0, 0x7ffffff);
4159 }
4160
4161 /**
4162     @page edcref
4163     @property
4164         padding
4165     @parameters
4166         [left] [right] [top] [bottom]
4167     @effect
4168         Sets the padding hints for this object.
4169     @endproperty
4170 */
4171 static void st_collections_group_parts_part_box_items_item_padding(void)
4172 {
4173    check_arg_count(4);
4174
4175    current_item->padding.l = parse_int_range(0, 0, 0x7ffffff);
4176    current_item->padding.r = parse_int_range(1, 0, 0x7ffffff);
4177    current_item->padding.t = parse_int_range(2, 0, 0x7ffffff);
4178    current_item->padding.b = parse_int_range(3, 0, 0x7ffffff);
4179 }
4180
4181 /**
4182     @page edcref
4183     @property
4184         align
4185     @parameters
4186         [x] [y]
4187     @effect
4188         Sets the alignment hints for this object.
4189     @endproperty
4190 */
4191 static void st_collections_group_parts_part_box_items_item_align(void)
4192 {
4193    check_arg_count(2);
4194
4195    current_item->align.x = FROM_DOUBLE(parse_float_range(0, -1.0, 1.0));
4196    current_item->align.y = FROM_DOUBLE(parse_float_range(1, -1.0, 1.0));
4197 }
4198
4199 /**
4200     @page edcref
4201     @property
4202         weight
4203     @parameters
4204         [x] [y]
4205     @effect
4206         Sets the weight hints for this object.
4207     @endproperty
4208 */
4209 static void st_collections_group_parts_part_box_items_item_weight(void)
4210 {
4211    check_arg_count(2);
4212
4213    current_item->weight.x = FROM_DOUBLE(parse_float_range(0, 0.0, 99999.99));
4214    current_item->weight.y = FROM_DOUBLE(parse_float_range(1, 0.0, 99999.99));
4215 }
4216
4217 /**
4218     @page edcref
4219     @property
4220         aspect
4221     @parameters
4222         [w] [h]
4223     @effect
4224         Sets the aspect width and height hints for this object.
4225     @endproperty
4226 */
4227 static void st_collections_group_parts_part_box_items_item_aspect(void)
4228 {
4229    check_arg_count(2);
4230
4231    current_item->aspect.w = parse_int_range(0, 0, 0x7fffffff);
4232    current_item->aspect.h = parse_int_range(1, 0, 0x7fffffff);
4233 }
4234
4235 /**
4236     @page edcref
4237     @property
4238         aspect_mode
4239     @parameters
4240         NONE, NEITHER, HORIZONTAL, VERTICAL, BOTH
4241     @effect
4242         Sets the aspect control hints for this object.
4243     @endproperty
4244 */
4245 static void st_collections_group_parts_part_box_items_item_aspect_mode(void)
4246 {
4247    check_arg_count(1);
4248
4249    current_item->aspect.mode = parse_enum(0,
4250                                   "NONE", EDJE_ASPECT_CONTROL_NONE,
4251                                   "NEITHER", EDJE_ASPECT_CONTROL_NEITHER,
4252                                   "HORIZONTAL", EDJE_ASPECT_CONTROL_HORIZONTAL,
4253                                   "VERTICAL", EDJE_ASPECT_CONTROL_VERTICAL,
4254                                   "BOTH", EDJE_ASPECT_CONTROL_BOTH,
4255                                   NULL);
4256 }
4257
4258 /**
4259     @page edcref
4260     @property
4261         options
4262     @parameters
4263         [extra options]
4264     @effect
4265         Sets extra options for the object. Unused for now.
4266     @endproperty
4267 */
4268 static void st_collections_group_parts_part_box_items_item_options(void)
4269 {
4270    check_arg_count(1);
4271
4272    current_item->options = parse_str(0);
4273 }
4274
4275 /**
4276     @page edcref
4277     @property
4278         position
4279     @parameters
4280         [col] [row]
4281     @effect
4282         Sets the position this item will have in the table.
4283         This is required for parts of type TABLE.
4284     @endproperty
4285 */
4286 static void st_collections_group_parts_part_table_items_item_position(void)
4287 {
4288    check_arg_count(2);
4289
4290    if (current_part->type != EDJE_PART_TYPE_TABLE)
4291      {
4292         ERR("parse error %s:%i. table attributes in non-TABLE part.",
4293             file_in, line - 1);
4294         exit(-1);
4295      }
4296
4297    current_item->col = parse_int_range(0, 0, 0xffff);
4298    current_item->row = parse_int_range(1, 0, 0xffff);
4299 }
4300
4301 /**
4302     @page edcref
4303     @property
4304         span
4305     @parameters
4306         [col] [row]
4307     @effect
4308         Sets how many columns/rows this item will use.
4309         Defaults to 1 1.
4310     @endproperty
4311 */
4312 static void st_collections_group_parts_part_table_items_item_span(void)
4313 {
4314    check_arg_count(2);
4315
4316    if (current_part->type != EDJE_PART_TYPE_TABLE)
4317      {
4318         ERR("parse error %s:%i. table attributes in non-TABLE part.",
4319             file_in, line - 1);
4320         exit(-1);
4321      }
4322
4323    current_item->colspan = parse_int_range(0, 1, 0xffff);
4324    current_item->rowspan = parse_int_range(1, 1, 0xffff);
4325 }
4326
4327 /**
4328    @edcsection{description,State description sub blocks}
4329  */
4330
4331 /**
4332     @page edcref
4333     @block
4334         description
4335     @context
4336         description {
4337             inherit: "another_description" INDEX;
4338             state: "description_name" INDEX;
4339             visible: 1;
4340             min: 0 0;
4341             max: -1 -1;
4342             align: 0.5 0.5;
4343             fixed: 0 0;
4344             step: 0 0;
4345             aspect: 1 1;
4346
4347             rel1 {
4348                 ..
4349             }
4350
4351             rel2 {
4352                 ..
4353             }
4354         }
4355     @description
4356         Every part can have one or more description blocks. Each description is
4357         used to define style and layout properties of a part in a given
4358         "state".
4359     @endblock
4360 */
4361 static void
4362 ob_collections_group_parts_part_description(void)
4363 {  /* Allocate and set desc, set relative part hierarchy if needed */
4364    Edje_Part_Collection *pc;
4365    Edje_Part *ep;
4366    Edje_Part_Description_Common *ed;
4367
4368    pc = eina_list_data_get(eina_list_last(edje_collections));
4369    ep = current_part;
4370
4371    ed = _edje_part_description_alloc(ep->type, pc->part, ep->name);
4372
4373    ed->rel1.id_x = -1;
4374    ed->rel1.id_y = -1;
4375    ed->rel2.id_x = -1;
4376    ed->rel2.id_y = -1;
4377
4378    if (!ep->default_desc)
4379      {
4380         current_desc = ep->default_desc = ed;
4381
4382           {  /* Get the ptr of the part above current part in hierarchy */
4383              Edje_Part *node = edje_cc_handlers_hierarchy_parent_get();
4384              if (node)  /* Make relative according to part hierarchy */
4385                edje_cc_handlers_hierarchy_set(node);
4386           }
4387      }
4388    else
4389      {
4390         ep->other.desc_count++;
4391         ep->other.desc = realloc(ep->other.desc,
4392                                  sizeof (Edje_Part_Description_Common*) * ep->other.desc_count);
4393         current_desc = ep->other.desc[ep->other.desc_count - 1] = ed;
4394      }
4395
4396    ed->visible = 1;
4397    ed->limit = 0;
4398    ed->align.x = FROM_DOUBLE(0.5);
4399    ed->align.y = FROM_DOUBLE(0.5);
4400    ed->min.w = 0;
4401    ed->min.h = 0;
4402    ed->fixed.w = 0;
4403    ed->fixed.h = 0;
4404    ed->max.w = -1;
4405    ed->max.h = -1;
4406    ed->rel1.relative_x = FROM_DOUBLE(0.0);
4407    ed->rel1.relative_y = FROM_DOUBLE(0.0);
4408    ed->rel1.offset_x = 0;
4409    ed->rel1.offset_y = 0;
4410    ed->rel2.relative_x = FROM_DOUBLE(1.0);
4411    ed->rel2.relative_y = FROM_DOUBLE(1.0);
4412    ed->rel2.offset_x = -1;
4413    ed->rel2.offset_y = -1;
4414    ed->color_class = NULL;
4415    ed->color.r = 255;
4416    ed->color.g = 255;
4417    ed->color.b = 255;
4418    ed->color.a = 255;
4419    ed->color2.r = 0;
4420    ed->color2.g = 0;
4421    ed->color2.b = 0;
4422    ed->color2.a = 255;
4423    ed->map.id_persp = -1;
4424    ed->map.id_light = -1;
4425    ed->map.rot.id_center = -1;
4426    ed->map.rot.x = FROM_DOUBLE(0.0);
4427    ed->map.rot.y = FROM_DOUBLE(0.0);
4428    ed->map.rot.z = FROM_DOUBLE(0.0);
4429    ed->map.on = 0;
4430    ed->map.smooth = 1;
4431    ed->map.alpha = 1;
4432    ed->map.backcull = 0;
4433    ed->map.persp_on = 0;
4434    ed->persp.zplane = 0;
4435    ed->persp.focal = 1000;
4436    ed->minmul.have = 1;
4437    ed->minmul.w = FROM_INT(1);
4438    ed->minmul.h = FROM_INT(1);
4439 }
4440
4441 /**
4442     @page edcref
4443     @property
4444         inherit
4445     @parameters
4446         [another description's name] [another description's index]
4447     @effect
4448         When set, the description will inherit all the properties from the
4449         named description. The properties defined in this part will override
4450         the inherited properties, reducing the amount of necessary code for
4451         simple state changes. Note: inheritance in Edje is single level only.
4452     @endproperty
4453 */
4454 static void
4455 st_collections_group_parts_part_description_inherit(void)
4456 {
4457    Edje_Part_Collection *pc;
4458    Edje_Part *ep;
4459    Edje_Part_Description_Common *ed, *parent = NULL;
4460    Edje_Part_Image_Id *iid;
4461    char *parent_name;
4462    const char *state_name;
4463    double parent_val, state_val;
4464
4465    pc = eina_list_data_get(eina_list_last(edje_collections));
4466    ep = current_part;
4467    ed = current_desc;
4468
4469    if (!ed->state.name)
4470      {
4471         ERR("parse error %s:%i. inherit may only be used after state",
4472             file_in, line - 1);
4473         exit(-1);
4474      }
4475
4476    parent = parent_desc;
4477    if (!parent)
4478      {
4479         check_min_arg_count(1);
4480
4481         /* inherit may not be used in the default description */
4482         if (!ep->other.desc_count)
4483           {
4484              ERR("parse error %s:%i. "
4485                  "inherit may not be used in the default description",
4486                  file_in, line - 1);
4487              exit(-1);
4488           }
4489
4490         /* find the description that we inherit from */
4491         parent_name = parse_str(0);
4492         if (get_arg_count() == 2)
4493           parent_val = parse_float_range(1, 0.0, 1.0);
4494         else
4495           parent_val = 0.0;
4496
4497         if (!strcmp (parent_name, "default") && parent_val == 0.0)
4498           parent = ep->default_desc;
4499         else
4500           {
4501              Edje_Part_Description_Common *d;
4502              double min_dst = 999.0;
4503              unsigned int i;
4504
4505              if (!strcmp(parent_name, "default"))
4506                {
4507                   parent = ep->default_desc;
4508                   min_dst = ABS(ep->default_desc->state.value - parent_val);
4509                }
4510
4511              for (i = 0; i < ep->other.desc_count; ++i)
4512                {
4513                   d = ep->other.desc[i];
4514
4515                   if (!strcmp (d->state.name, parent_name))
4516                     {
4517
4518                        double dst;
4519
4520                        dst = ABS(d->state.value - parent_val);
4521                        if (dst < min_dst)
4522                          {
4523                             parent = d;
4524                             min_dst = dst;
4525                          }
4526                     }
4527                }
4528           }
4529
4530         if (!parent)
4531           {
4532              ERR("parse error %s:%i. "
4533                  "cannot find referenced part %s state %s %lf",
4534                  file_in, line - 1, ep->name, parent_name, parent_val);
4535              exit(-1);
4536           }
4537
4538         free(parent_name);
4539      }
4540    /* now do a full copy, only state info will be kept */
4541    state_name = ed->state.name;
4542    state_val = ed->state.value;
4543
4544    *ed = *parent;
4545
4546    ed->state.name = state_name;
4547    ed->state.value = state_val;
4548
4549    data_queue_copied_part_lookup(pc, &parent->rel1.id_x, &ed->rel1.id_x);
4550    data_queue_copied_part_lookup(pc, &parent->rel1.id_y, &ed->rel1.id_y);
4551    data_queue_copied_part_lookup(pc, &parent->rel2.id_x, &ed->rel2.id_x);
4552    data_queue_copied_part_lookup(pc, &parent->rel2.id_y, &ed->rel2.id_y);
4553
4554    data_queue_copied_part_lookup(pc, &parent->map.id_persp, &ed->map.id_persp);
4555    data_queue_copied_part_lookup(pc, &parent->map.id_light, &ed->map.id_light);
4556    data_queue_copied_part_lookup(pc, &parent->map.rot.id_center, &ed->map.rot.id_center);
4557
4558    /* make sure all the allocated memory is getting copied, not just
4559     * referenced
4560     */
4561 #define STRDUP(x) x ? strdup(x) : NULL
4562
4563    ed->color_class = STRDUP(ed->color_class);
4564    switch (ep->type)
4565      {
4566       case EDJE_PART_TYPE_SPACER:
4567       case EDJE_PART_TYPE_RECTANGLE:
4568       case EDJE_PART_TYPE_SWALLOW:
4569       case EDJE_PART_TYPE_GROUP:
4570          /* Nothing todo, this part only have a common description. */
4571          break;
4572       case EDJE_PART_TYPE_TEXT:
4573       case EDJE_PART_TYPE_TEXTBLOCK:
4574            {
4575               Edje_Part_Description_Text *ted = (Edje_Part_Description_Text*) ed;
4576               Edje_Part_Description_Text *tparent = (Edje_Part_Description_Text*) parent;
4577
4578               ted->text = tparent->text;
4579
4580               ted->text.text.str = STRDUP(ted->text.text.str);
4581               ted->text.text_class = STRDUP(ted->text.text_class);
4582               ted->text.font.str = STRDUP(ted->text.font.str);
4583
4584               data_queue_copied_part_lookup(pc, &(tparent->text.id_source), &(ted->text.id_source));
4585               data_queue_copied_part_lookup(pc, &(tparent->text.id_text_source), &(ted->text.id_text_source));
4586
4587               break;
4588            }
4589       case EDJE_PART_TYPE_IMAGE:
4590            {
4591               Edje_Part_Description_Image *ied = (Edje_Part_Description_Image *) ed;
4592               Edje_Part_Description_Image *iparent = (Edje_Part_Description_Image *) parent;
4593               unsigned int i;
4594
4595               ied->image = iparent->image;
4596
4597               data_queue_image_remove(&ied->image.id, &ied->image.set);
4598               data_queue_copied_image_lookup(&iparent->image.id, &ied->image.id, &ied->image.set);
4599
4600               ied->image.tweens = calloc(iparent->image.tweens_count,
4601                                          sizeof (Edje_Part_Image_Id*));
4602               for (i = 0; i < iparent->image.tweens_count; i++)
4603                 {
4604                    Edje_Part_Image_Id *iid_new;
4605
4606                    iid = iparent->image.tweens[i];
4607
4608                    iid_new = mem_alloc(SZ(Edje_Part_Image_Id));
4609                    data_queue_image_remove(&ied->image.id, &ied->image.set);
4610                    data_queue_copied_image_lookup(&(iid->id), &(iid_new->id), &(iid_new->set));
4611                    ied->image.tweens[i] = iid_new;
4612                 }
4613
4614               break;
4615            }
4616       case EDJE_PART_TYPE_PROXY:
4617            {
4618               Edje_Part_Description_Proxy *ped = (Edje_Part_Description_Proxy*) ed;
4619               Edje_Part_Description_Proxy *pparent = (Edje_Part_Description_Proxy*) parent;
4620
4621               data_queue_copied_part_lookup(pc, &(pparent->proxy.id), &(ped->proxy.id));
4622
4623               break;
4624            }
4625       case EDJE_PART_TYPE_BOX:
4626            {
4627               Edje_Part_Description_Box *bed = (Edje_Part_Description_Box *) ed;
4628               Edje_Part_Description_Box *bparent = (Edje_Part_Description_Box *) parent;
4629
4630               bed->box = bparent->box;
4631
4632               break;
4633            }
4634       case EDJE_PART_TYPE_TABLE:
4635            {
4636               Edje_Part_Description_Table *ted = (Edje_Part_Description_Table *) ed;
4637               Edje_Part_Description_Table *tparent = (Edje_Part_Description_Table *) parent;
4638
4639               ted->table = tparent->table;
4640
4641               break;
4642            }
4643       case EDJE_PART_TYPE_EXTERNAL:
4644            {
4645               Edje_Part_Description_External *eed = (Edje_Part_Description_External *) ed;
4646               Edje_Part_Description_External *eparent = (Edje_Part_Description_External *) parent;
4647
4648               if (eparent->external_params)
4649                 {
4650                    Eina_List *l;
4651                    Edje_External_Param *param, *new_param;
4652
4653                    eed->external_params = NULL;
4654                    EINA_LIST_FOREACH(eparent->external_params, l, param)
4655                      {
4656                         new_param = mem_alloc(SZ(Edje_External_Param));
4657                         *new_param = *param;
4658                         eed->external_params = eina_list_append(eed->external_params, new_param);
4659                      }
4660                 }
4661               break;
4662            }
4663      }
4664
4665 #undef STRDUP
4666 }
4667
4668 /**
4669     @page edcref
4670
4671     @property
4672         source
4673     @parameters
4674         [another part's name]
4675     @effect
4676         Causes the part to use another part content as the content of this part.
4677         Only work with PROXY part.
4678     @endproperty
4679 */
4680 static void
4681 st_collections_group_parts_part_description_source(void)
4682 {
4683    Edje_Part_Collection *pc;
4684    Edje_Part_Description_Proxy *ed;
4685    char *name;
4686
4687    check_arg_count(1);
4688
4689    pc = eina_list_data_get(eina_list_last(edje_collections));
4690
4691    if (current_part->type != EDJE_PART_TYPE_PROXY)
4692      {
4693         ERR("parse error %s:%i. source attributes in non-PROXY part.",
4694             file_in, line - 1);
4695         exit(-1);
4696      }
4697
4698    ed = (Edje_Part_Description_Proxy*) current_desc;
4699
4700    name = parse_str(0);
4701
4702    data_queue_part_lookup(pc, name, &(ed->proxy.id));
4703    free(name);
4704 }
4705
4706 /**
4707     @page edcref
4708     @property
4709         state
4710     @parameters
4711         [a name for the description] [an index]
4712     @effect
4713         Sets a name used to identify a description inside a given part.
4714         Multiple descriptions are used to declare different states of the same
4715         part, like "clicked" or "invisible". All states declarations are also
4716         coupled with an index number between 0.0 and 1.0. All parts must have
4717         at least one description named "default 0.0".
4718     @endproperty
4719 */
4720 static void
4721 st_collections_group_parts_part_description_state(void)
4722 {
4723    Edje_Part *ep;
4724    Edje_Part_Description_Common *ed;
4725    char *s;
4726
4727    check_min_arg_count(1);
4728
4729    ep = current_part;
4730
4731    ed = ep->default_desc;
4732    if (ep->other.desc_count) ed = ep->other.desc[ep->other.desc_count - 1];
4733
4734    s = parse_str(0);
4735    if (!strcmp (s, "custom"))
4736      {
4737         ERR("parse error %s:%i. invalid state name: '%s'.",
4738             file_in, line - 1, s);
4739         exit(-1);
4740      }
4741
4742    ed->state.name = s;
4743    if (get_arg_count() == 1)
4744      ed->state.value = 0.0;
4745    else
4746      ed->state.value = parse_float_range(1, 0.0, 1.0);
4747
4748    if (ed != ep->default_desc)
4749      {
4750         if ((ep->default_desc->state.name && !strcmp(s, ep->default_desc->state.name) && ed->state.value == ep->default_desc->state.value) ||
4751             (!ep->default_desc->state.name && !strcmp(s, "default") && ed->state.value == ep->default_desc->state.value))
4752           {
4753              if (ep->type == EDJE_PART_TYPE_IMAGE)
4754                _edje_part_description_image_remove((Edje_Part_Description_Image*) ed);
4755
4756              free(ed);
4757              ep->other.desc_count--;
4758              ep->other.desc = realloc(ep->other.desc,
4759                                       sizeof (Edje_Part_Description_Common*) * ep->other.desc_count);
4760              current_desc = ep->default_desc;
4761           }
4762         else if (ep->other.desc_count)
4763           {
4764              unsigned int i;
4765              for (i = 0; i < ep->other.desc_count - 1; ++i)
4766                {
4767                   if (!strcmp(s, ep->other.desc[i]->state.name) && ed->state.value == ep->other.desc[i]->state.value)
4768                     {
4769                        if (ep->type == EDJE_PART_TYPE_IMAGE)
4770                          _edje_part_description_image_remove((Edje_Part_Description_Image*) ed);
4771
4772                        free(ed);
4773                        ep->other.desc_count--;
4774                        ep->other.desc = realloc(ep->other.desc,
4775                                                 sizeof (Edje_Part_Description_Common*) * ep->other.desc_count);
4776                        current_desc = ep->other.desc[i];
4777                        break;
4778                     }
4779                }
4780           }
4781      }
4782 }
4783
4784 /**
4785     @page edcref
4786     @property
4787         visible
4788     @parameters
4789         [0 or 1]
4790     @effect
4791         Takes a boolean value specifying whether part is visible (1) or not
4792         (0). Non-visible parts do not emit signals. The default value is 1.
4793     @endproperty
4794 */
4795 static void
4796 st_collections_group_parts_part_description_visible(void)
4797 {
4798    check_arg_count(1);
4799
4800    if (current_part->type == EDJE_PART_TYPE_SPACER)
4801      {
4802        ERR("parse error %s:%i. SPACER part can't have a visibility defined",
4803            file_in, line - 1);
4804        exit(-1);
4805      }
4806
4807    current_desc->visible = parse_bool(0);
4808 }
4809 /**
4810     @page edcref
4811     @property
4812         limit
4813     @parameters
4814         [NONE, WIDTH, HEIGHT or BOTH]
4815     @effect
4816         Emit a signal when the part size change from zero or to a zero size
4817         ('limit,width,over', 'limit,width,zero'). By default no signal are
4818         emitted.
4819     @endproperty
4820     @since 1.7.0
4821 */
4822 static void
4823 st_collections_group_parts_part_description_limit(void)
4824 {
4825    check_arg_count(1);
4826
4827    current_desc->limit = parse_enum(0,
4828                                     "NONE", 0,
4829                                     "WIDTH", 1,
4830                                     "HEIGHT", 2,
4831                                     "BOTH", 3);
4832
4833    if (current_desc->limit)
4834      {
4835         Edje_Part_Collection *pc;
4836         int count;
4837
4838         pc = eina_list_data_get(eina_list_last(edje_collections));
4839         count = pc->limits.parts_count++;
4840         pc->limits.parts = realloc(pc->limits.parts,
4841                                    pc->limits.parts_count * sizeof (Edje_Part_Limit));
4842         data_queue_part_lookup(pc, current_part->name,
4843                                &(pc->limits.parts[count].part));
4844      }
4845 }
4846
4847 /**
4848     @page edcref
4849     @property
4850         align
4851     @parameters
4852         [X axis] [Y axis]
4853     @effect
4854         When the displayed object's size is smaller than its container, this
4855         property moves it relatively along both axis inside its container. The
4856         default value is "0.5 0.5".
4857     @endproperty
4858 */
4859 static void
4860 st_collections_group_parts_part_description_align(void)
4861 {
4862    check_arg_count(2);
4863
4864    current_desc->align.x = FROM_DOUBLE(parse_float_range(0, 0.0, 1.0));
4865    current_desc->align.y = FROM_DOUBLE(parse_float_range(1, 0.0, 1.0));
4866 }
4867
4868 /**
4869     @page edcref
4870     @property
4871         fixed
4872     @parameters
4873         [width, 0 or 1] [height, 0 or 1]
4874     @effect
4875         This affects the minimum size calculation. See
4876         edje_object_size_min_calc() and edje_object_size_min_restricted_calc().
4877         This tells the min size calculation routine that this part does not
4878         change size in width or height (1 for it doesn't, 0 for it does), so
4879         the routine should not try and expand or contract the part.
4880     @endproperty
4881 */
4882 static void
4883 st_collections_group_parts_part_description_fixed(void)
4884 {
4885    check_arg_count(2);
4886
4887    current_desc->fixed.w = parse_float_range(0, 0, 1);
4888    current_desc->fixed.h = parse_float_range(1, 0, 1);
4889 }
4890
4891 /**
4892     @page edcref
4893     @property
4894         min
4895     @parameters
4896         [width] [height] or SOURCE
4897     @effect
4898         The minimum size of the state.
4899
4900         When min is defined to SOURCE, it will look at the original
4901         image size and enforce it minimal size to match at least the
4902         original one. The part must be an IMAGE or a GROUP part.
4903     @endproperty
4904 */
4905 static void
4906 st_collections_group_parts_part_description_min(void)
4907 {
4908    check_min_arg_count(1);
4909
4910    if (is_param(1)) {
4911       current_desc->min.w = parse_float_range(0, 0, 0x7fffffff);
4912       current_desc->min.h = parse_float_range(1, 0, 0x7fffffff);
4913    } else {
4914       char *tmp;
4915
4916       tmp = parse_str(0);
4917       if ((current_part->type != EDJE_PART_TYPE_IMAGE && current_part->type != EDJE_PART_TYPE_GROUP) ||
4918           !tmp || strcmp(tmp, "SOURCE") != 0)
4919         {
4920            ERR("parse error %s:%i. "
4921                "Only IMAGE and GROUP part can have a min: SOURCE; defined",
4922                file_in, line - 1);
4923            exit(-1);
4924         }
4925
4926       current_desc->min.limit = EINA_TRUE;
4927    }
4928 }
4929
4930 /**
4931     @page edcref
4932     @property
4933         minmul
4934     @parameters
4935         [width multipler] [height multiplier]
4936     @effect
4937         A multiplier FORCIBLY applied to whatever minimum size is only during
4938         minimum size calculation.
4939     @endproperty
4940     @since 1.2
4941 */
4942 static void
4943 st_collections_group_parts_part_description_minmul(void)
4944 {
4945    check_arg_count(2);
4946
4947    current_desc->minmul.w = FROM_DOUBLE(parse_float_range(0, 0, 999999));
4948    current_desc->minmul.h = FROM_DOUBLE(parse_float_range(1, 0, 999999));
4949 }
4950
4951 /**
4952     @page edcref
4953     @property
4954         max
4955     @parameters
4956         [width] [height] or SOURCE
4957     @effect
4958         The maximum size of the state. A size of -1.0 means that it will be ignored in one direction.
4959
4960         When max is set to SOURCE, edje will enforce the part to be
4961         not more than the original image size. The part must be an
4962         IMAGE part.
4963     @endproperty
4964 */
4965 static void
4966 st_collections_group_parts_part_description_max(void)
4967 {
4968    check_min_arg_count(1);
4969
4970    if (is_param(1)) {
4971       current_desc->max.w = parse_float_range(0, -1.0, 0x7fffffff);
4972       current_desc->max.h = parse_float_range(1, -1.0, 0x7fffffff);
4973    } else {
4974       char *tmp;
4975
4976       tmp = parse_str(0);
4977       if (current_part->type != EDJE_PART_TYPE_IMAGE ||
4978           !tmp || strcmp(tmp, "SOURCE") != 0)
4979         {
4980            ERR("parse error %s:%i. "
4981                "Only IMAGE part can have a max: SOURCE; defined",
4982                file_in, line - 1);
4983            exit(-1);
4984         }
4985
4986       current_desc->max.limit = EINA_TRUE;
4987    }
4988 }
4989
4990 /**
4991     @page edcref
4992     @property
4993         step
4994     @parameters
4995         [width] [height]
4996     @effect
4997         Restricts resizing of each dimension to values divisibles by its value.
4998         This causes the part to jump from value to value while resizing. The
4999         default value is "0 0" disabling stepping.
5000     @endproperty
5001 */
5002 static void
5003 st_collections_group_parts_part_description_step(void)
5004 {
5005    check_arg_count(2);
5006
5007    current_desc->step.x = parse_float_range(0, 0, 0x7fffffff);
5008    current_desc->step.y = parse_float_range(1, 0, 0x7fffffff);
5009 }
5010
5011 /**
5012     @page edcref
5013     @property
5014         aspect
5015     @parameters
5016         [min] [max]
5017     @effect
5018         Normally width and height can be resized to any values independently.
5019         The aspect property forces the width to height ratio to be kept between
5020         the minimum and maximum set. For example, "1.0 1.0" will increase the
5021         width a pixel for every pixel added to height. The default value is
5022         "0.0 0.0" disabling aspect.
5023     @endproperty
5024 */
5025 static void
5026 st_collections_group_parts_part_description_aspect(void)
5027 {
5028    check_arg_count(2);
5029
5030    current_desc->aspect.min = FROM_DOUBLE(parse_float_range(0, 0.0, 999999999.0));
5031    current_desc->aspect.max = FROM_DOUBLE(parse_float_range(1, 0.0, 999999999.0));
5032 }
5033
5034 /**
5035     @page edcref
5036     @property
5037         aspect_preference
5038     @parameters
5039         [DIMENSION]
5040     @effect
5041         Sets the scope of the "aspect" property to a given dimension. Available
5042         options are BOTH, VERTICAL, HORIZONTAL, SOURCE and NONE
5043     @endproperty
5044 */
5045 static void
5046 st_collections_group_parts_part_description_aspect_preference(void)
5047 {
5048    check_arg_count(1);
5049
5050    current_desc->aspect.prefer =  parse_enum(0,
5051                                    "NONE", EDJE_ASPECT_PREFER_NONE,
5052                                    "VERTICAL", EDJE_ASPECT_PREFER_VERTICAL,
5053                                    "HORIZONTAL", EDJE_ASPECT_PREFER_HORIZONTAL,
5054                                    "BOTH", EDJE_ASPECT_PREFER_BOTH,
5055                                    "SOURCE", EDJE_ASPECT_PREFER_SOURCE,
5056                                    NULL);
5057 }
5058
5059 /**
5060     @page edcref
5061     @property
5062         color_class
5063     @parameters
5064         [color class name]
5065     @effect
5066         The part will use the color values of the named color_class, these
5067         values can be overrided by the "color", "color2" and "color3"
5068         properties set below.
5069     @endproperty
5070 */
5071 static void
5072 st_collections_group_parts_part_description_color_class(void)
5073 {
5074    check_arg_count(1);
5075
5076    if (current_part->type == EDJE_PART_TYPE_SPACER)
5077      {
5078        ERR("parse error %s:%i. SPACER part can't have a color defined",
5079            file_in, line - 1);
5080        exit(-1);
5081      }
5082
5083    current_desc->color_class = parse_str(0);
5084 }
5085
5086 /**
5087     @page edcref
5088     @property
5089         color
5090     @parameters
5091         [red] [green] [blue] [alpha]
5092     @effect
5093         Sets the main color to the specified values (between 0 and 255).
5094     @endproperty
5095 */
5096 static void
5097 st_collections_group_parts_part_description_color(void)
5098 {
5099    check_arg_count(4);
5100
5101    if (current_part->type == EDJE_PART_TYPE_SPACER)
5102      {
5103        ERR("parse error %s:%i. SPACER part can't have a color defined",
5104            file_in, line - 1);
5105        exit(-1);
5106      }
5107
5108    current_desc->color.r = parse_int_range(0, 0, 255);
5109    current_desc->color.g = parse_int_range(1, 0, 255);
5110    current_desc->color.b = parse_int_range(2, 0, 255);
5111    current_desc->color.a = parse_int_range(3, 0, 255);
5112 }
5113
5114 /**
5115     @page edcref
5116     @property
5117         color2
5118     @parameters
5119         [red] [green] [blue] [alpha]
5120     @effect
5121         Sets the text shadow color to the specified values (0 to 255).
5122     @endproperty
5123 */
5124 static void
5125 st_collections_group_parts_part_description_color2(void)
5126 {
5127    check_arg_count(4);
5128
5129    if (current_part->type == EDJE_PART_TYPE_SPACER)
5130      {
5131        ERR("parse error %s:%i. SPACER part can't have a color defined",
5132            file_in, line - 1);
5133        exit(-1);
5134      }
5135
5136    current_desc->color2.r = parse_int_range(0, 0, 255);
5137    current_desc->color2.g = parse_int_range(1, 0, 255);
5138    current_desc->color2.b = parse_int_range(2, 0, 255);
5139    current_desc->color2.a = parse_int_range(3, 0, 255);
5140 }
5141
5142 /**
5143     @page edcref
5144     @property
5145         color3
5146     @parameters
5147         [red] [green] [blue] [alpha]
5148     @effect
5149         Sets the text outline color to the specified values (0 to 255).
5150     @endproperty
5151 */
5152 static void
5153 st_collections_group_parts_part_description_color3(void)
5154 {
5155    Edje_Part_Collection *pc;
5156    Edje_Part_Description_Text *ed;
5157
5158    check_arg_count(4);
5159
5160    pc = eina_list_data_get(eina_list_last(edje_collections));
5161
5162    if (current_part->type != EDJE_PART_TYPE_TEXT
5163        && current_part->type != EDJE_PART_TYPE_TEXTBLOCK)
5164      {
5165         ERR("Setting color3 in part %s from %s not of type TEXT or TEXTBLOCK.",
5166             current_part->name, pc->part);
5167         exit(-1);
5168      }
5169
5170    ed = (Edje_Part_Description_Text*)current_desc;
5171
5172    ed->text.color3.r = parse_int_range(0, 0, 255);
5173    ed->text.color3.g = parse_int_range(1, 0, 255);
5174    ed->text.color3.b = parse_int_range(2, 0, 255);
5175    ed->text.color3.a = parse_int_range(3, 0, 255);
5176 }
5177
5178 /**
5179     @page edcref
5180     @block
5181         rel1/rel2
5182     @context
5183         description {
5184             ..
5185             rel1 {
5186                 relative: 0.0 0.0;
5187                 offset:     0   0;
5188             }
5189             ..
5190             rel2 {
5191                 relative: 1.0 1.0;
5192                 offset:    -1  -1;
5193             }
5194             ..
5195         }
5196     @description
5197         The rel1 and rel2 blocks are used to define the position of each corner
5198         of the part's container. With rel1 being the left-up corner and rel2
5199         being the right-down corner.
5200     @endblock
5201
5202     @property
5203         relative
5204     @parameters
5205         [X axis] [Y axis]
5206     @effect
5207         Moves a corner to a relative position inside the container of the
5208         relative "to" part. Values from 0.0 (0%, beginning) to 1.0 (100%, end)
5209         of each axis.
5210     @endproperty
5211 */
5212 static void
5213 st_collections_group_parts_part_description_rel1_relative(void)
5214 {
5215    check_arg_count(2);
5216
5217    current_desc->rel1.relative_x = FROM_DOUBLE(parse_float(0));
5218    current_desc->rel1.relative_y = FROM_DOUBLE(parse_float(1));
5219 }
5220
5221 /**
5222     @page edcref
5223     @property
5224         offset
5225     @parameters
5226         [X axis] [Y axis]
5227     @effect
5228         Affects the corner position a fixed number of pixels along each axis.
5229     @endproperty
5230 */
5231 static void
5232 st_collections_group_parts_part_description_rel1_offset(void)
5233 {
5234    check_arg_count(2);
5235
5236    current_desc->rel1.offset_x = parse_int(0);
5237    current_desc->rel1.offset_y = parse_int(1);
5238 }
5239
5240 /**
5241     @page edcref
5242     @property
5243         to
5244     @parameters
5245         [another part's name]
5246     @effect
5247         Causes a corner to be positioned relatively to another part's
5248         container. Setting to "" will un-set this value for inherited
5249         parts.
5250     @endproperty
5251 */
5252 static void
5253 st_collections_group_parts_part_description_rel1_to_set(const char *name)
5254 {
5255    Edje_Part_Collection *pc;
5256    pc = eina_list_data_get(eina_list_last(edje_collections));
5257    data_queue_part_lookup(pc, name, &(current_desc->rel1.id_x));
5258    data_queue_part_lookup(pc, name, &(current_desc->rel1.id_y));
5259 }
5260
5261 static void
5262 st_collections_group_parts_part_description_rel1_to(void)
5263 {
5264    check_arg_count(1);
5265
5266    {
5267       char *name;
5268       name = parse_str(0);
5269       st_collections_group_parts_part_description_rel1_to_set(name);
5270       free(name);
5271    }
5272 }
5273
5274 /**
5275     @page edcref
5276     @property
5277         to_x
5278     @parameters
5279         [another part's name]
5280     @effect
5281         Causes a corner to be positioned relatively to the X axis of another
5282         part's container. Simply put affects the first parameter of "relative".
5283         Setting to "" will un-set this value for inherited parts.
5284     @endproperty
5285 */
5286 static void
5287 st_collections_group_parts_part_description_rel1_to_x(void)
5288 {
5289    Edje_Part_Collection *pc;
5290
5291    check_arg_count(1);
5292
5293    pc = eina_list_data_get(eina_list_last(edje_collections));
5294
5295    {
5296       char *name;
5297
5298       name = parse_str(0);
5299       data_queue_part_lookup(pc, name, &(current_desc->rel1.id_x));
5300       free(name);
5301    }
5302 }
5303
5304 /**
5305     @page edcref
5306     @property
5307         to_y
5308     @parameters
5309         [another part's name]
5310     @effect
5311         Causes a corner to be positioned relatively to the Y axis of another
5312         part's container. Simply put, affects the second parameter of
5313         "relative". Setting to "" will un-set this value for inherited parts.
5314     @endproperty
5315 */
5316 static void
5317 st_collections_group_parts_part_description_rel1_to_y(void)
5318 {
5319    Edje_Part_Collection *pc;
5320
5321    check_arg_count(1);
5322
5323    pc = eina_list_data_get(eina_list_last(edje_collections));
5324
5325    {
5326       char *name;
5327
5328       name = parse_str(0);
5329       data_queue_part_lookup(pc, name, &(current_desc->rel1.id_y));
5330       free(name);
5331    }
5332 }
5333
5334 static void
5335 st_collections_group_parts_part_description_rel2_relative(void)
5336 {
5337    check_arg_count(2);
5338
5339    current_desc->rel2.relative_x = FROM_DOUBLE(parse_float(0));
5340    current_desc->rel2.relative_y = FROM_DOUBLE(parse_float(1));
5341 }
5342
5343 static void
5344 st_collections_group_parts_part_description_rel2_offset(void)
5345 {
5346    check_arg_count(2);
5347
5348    current_desc->rel2.offset_x = parse_int(0);
5349    current_desc->rel2.offset_y = parse_int(1);
5350 }
5351
5352 static void
5353 st_collections_group_parts_part_description_rel2_to_set(const char *name)
5354 {
5355    Edje_Part_Collection *pc;
5356    pc = eina_list_data_get(eina_list_last(edje_collections));
5357    data_queue_part_lookup(pc, name, &(current_desc->rel2.id_x));
5358    data_queue_part_lookup(pc, name, &(current_desc->rel2.id_y));
5359 }
5360
5361 static void
5362 st_collections_group_parts_part_description_rel2_to(void)
5363 {
5364    check_arg_count(1);
5365
5366    {
5367       char *name;
5368       name = parse_str(0);
5369       st_collections_group_parts_part_description_rel2_to_set(name);
5370       free(name);
5371    }
5372 }
5373
5374 static void
5375 st_collections_group_parts_part_description_rel2_to_x(void)
5376 {
5377    Edje_Part_Collection *pc;
5378
5379    check_arg_count(1);
5380
5381    pc = eina_list_data_get(eina_list_last(edje_collections));
5382
5383    {
5384       char *name;
5385
5386       name = parse_str(0);
5387       data_queue_part_lookup(pc, name, &(current_desc->rel2.id_x));
5388       free(name);
5389    }
5390 }
5391
5392 static void
5393 st_collections_group_parts_part_description_rel2_to_y(void)
5394 {
5395    Edje_Part_Collection *pc;
5396
5397    check_arg_count(1);
5398
5399    pc = eina_list_data_get(eina_list_last(edje_collections));
5400
5401    {
5402       char *name;
5403
5404       name = parse_str(0);
5405       data_queue_part_lookup(pc, name, &(current_desc->rel2.id_y));
5406       free(name);
5407    }
5408 }
5409
5410 /**
5411    @edcsection{description_image,Image state description sub blocks}
5412  */
5413
5414 /**
5415     @page edcref
5416     @block
5417         image
5418     @context
5419         description {
5420             ..
5421             image {
5422                 normal: "filename.ext";
5423                 tween:  "filename2.ext";
5424                 ..
5425                 tween:  "filenameN.ext";
5426                 border:  left right top bottom;
5427                 middle:  0/1/NONE/DEFAULT/SOLID;
5428             }
5429             ..
5430         }
5431     @description
5432     @endblock
5433
5434     @property
5435         normal
5436     @parameters
5437         [image's filename]
5438     @effect
5439         Name of image to be used as previously declared in the  images block.
5440         In an animation, this is the first and last image displayed. It's
5441         required in any image part
5442     @endproperty
5443 */
5444 static void
5445 st_collections_group_parts_part_description_image_normal(void)
5446 {
5447    Edje_Part_Description_Image *ed;
5448
5449    check_arg_count(1);
5450
5451    if (current_part->type != EDJE_PART_TYPE_IMAGE)
5452      {
5453         ERR("parse error %s:%i. "
5454             "image attributes in non-IMAGE part.",
5455             file_in, line - 1);
5456         exit(-1);
5457      }
5458
5459    ed = (Edje_Part_Description_Image*) current_desc;
5460
5461    {
5462       char *name;
5463
5464       name = parse_str(0);
5465       data_queue_image_remove(&(ed->image.id), &(ed->image.set));
5466       data_queue_image_lookup(name, &(ed->image.id), &(ed->image.set));
5467       free(name);
5468    }
5469 }
5470
5471 /**
5472     @page edcref
5473     @property
5474         tween
5475     @parameters
5476         [image's filename]
5477     @effect
5478         Name of an image to be used in an animation loop, an image block can
5479         have none, one or multiple tween declarations. Images are displayed in
5480         the order they are listed, during the transition to the state they are
5481         declared in; the "normal" image is the final state.
5482     @endproperty
5483 */
5484 static void
5485 st_collections_group_parts_part_description_image_tween(void)
5486 {
5487    Edje_Part_Description_Image *ed;
5488
5489    check_arg_count(1);
5490
5491    if (current_part->type != EDJE_PART_TYPE_IMAGE)
5492      {
5493         ERR("parse error %s:%i. image attributes in non-IMAGE part.",
5494             file_in, line - 1);
5495         exit(-1);
5496      }
5497
5498    ed = (Edje_Part_Description_Image*) current_desc;
5499
5500    {
5501       char *name;
5502       Edje_Part_Image_Id *iid;
5503
5504       iid = mem_alloc(SZ(Edje_Part_Image_Id));
5505       ed->image.tweens_count++;
5506       ed->image.tweens = realloc(ed->image.tweens,
5507                                  sizeof (Edje_Part_Image_Id*) * ed->image.tweens_count);
5508       ed->image.tweens[ed->image.tweens_count - 1] = iid;
5509       name = parse_str(0);
5510       data_queue_image_remove(&(iid->id), &(iid->set));
5511       data_queue_image_lookup(name, &(iid->id), &(iid->set));
5512       free(name);
5513    }
5514 }
5515
5516 /**
5517     @page edcref
5518     @property
5519         border
5520     @parameters
5521         [left] [right] [top] [bottom]
5522     @effect
5523         If set, the area (in pixels) of each side of the image will be
5524         displayed as a fixed size border, from the side -> inwards, preventing
5525         the corners from being changed on a resize.
5526     @endproperty
5527 */
5528 static void
5529 st_collections_group_parts_part_description_image_border(void)
5530 {
5531    Edje_Part_Description_Image *ed;
5532
5533    check_arg_count(4);
5534
5535    if (current_part->type != EDJE_PART_TYPE_IMAGE)
5536      {
5537         ERR("parse error %s:%i. image attributes in non-IMAGE part.",
5538             file_in, line - 1);
5539         exit(-1);
5540      }
5541
5542    ed = (Edje_Part_Description_Image*) current_desc;
5543
5544    ed->image.border.l = parse_int_range(0, 0, 0x7fffffff);
5545    ed->image.border.r = parse_int_range(1, 0, 0x7fffffff);
5546    ed->image.border.t = parse_int_range(2, 0, 0x7fffffff);
5547    ed->image.border.b = parse_int_range(3, 0, 0x7fffffff);
5548 }
5549
5550 /**
5551     @page edcref
5552     @property
5553         middle
5554     @parameters
5555         0, 1, NONE, DEFAULT, SOLID
5556     @effect
5557         If border is set, this value tells Edje if the rest of the
5558         image (not covered by the defined border) will be displayed or not
5559         or be assumed to be solid (without alpha). The default is 1/DEFAULT.
5560     @endproperty
5561 */
5562 static void
5563 st_collections_group_parts_part_description_image_middle(void)
5564 {
5565    Edje_Part_Description_Image *ed;
5566
5567    check_arg_count(1);
5568
5569    if (current_part->type != EDJE_PART_TYPE_IMAGE)
5570      {
5571         ERR("parse error %s:%i. image attributes in non-IMAGE part.",
5572             file_in, line - 1);
5573         exit(-1);
5574      }
5575
5576    ed = (Edje_Part_Description_Image*) current_desc;
5577
5578    ed->image.border.no_fill =  parse_enum(0,
5579                                           "1", 0,
5580                                           "DEFAULT", 0,
5581                                           "0", 1,
5582                                           "NONE", 1,
5583                                           "SOLID", 2,
5584                                           NULL);
5585 }
5586
5587 /**
5588     @page edcref
5589     @property
5590         border_scale_by
5591     @parameters
5592         0.0 or bigger (0.0 or 1.0 to turn it off)
5593     @effect
5594         If border scaling is enabled then normally the OUTPUT border sizes
5595         (e.g. if 3 pixels on the left edge are set as a border, then normally
5596         at scale 1.0, those 3 columns will always be the exact 3 columns of
5597         output, or at scale 2.0 they will be 6 columns, or 0.33 they will merge
5598         into a single column). This property multiplies the input scale
5599         factor by this multiplier, allowing the creation of "supersampled"
5600         borders to make much higher resolution outputs possible by always using
5601         the highest resolution artwork and then runtime scaling it down.
5602     @endproperty
5603 */
5604 static void
5605 st_collections_group_parts_part_description_image_border_scale_by(void)
5606 {
5607    Edje_Part_Description_Image *ed;
5608
5609    check_arg_count(1);
5610
5611    if (current_part->type != EDJE_PART_TYPE_IMAGE)
5612      {
5613         ERR("parse error %s:%i. image attributes in non-IMAGE part.",
5614             file_in, line - 1);
5615         exit(-1);
5616      }
5617
5618    ed = (Edje_Part_Description_Image*) current_desc;
5619
5620    ed->image.border.scale_by = FROM_DOUBLE(parse_float_range(0, 0.0, 999999999.0));
5621 }
5622
5623 /**
5624     @page edcref
5625     @property
5626         border_scale
5627     @parameters
5628         0, 1
5629     @effect
5630         If border is set, this value tells Edje if the border should be scaled
5631         by the object/global edje scale factors
5632     @endproperty
5633 */
5634 static void
5635 st_collections_group_parts_part_description_image_border_scale(void)
5636 {
5637    Edje_Part_Description_Image *ed;
5638
5639    check_arg_count(1);
5640
5641    if (current_part->type != EDJE_PART_TYPE_IMAGE)
5642      {
5643         ERR("parse error %s:%i. image attributes in non-IMAGE part.",
5644             file_in, line - 1);
5645         exit(-1);
5646      }
5647
5648    ed = (Edje_Part_Description_Image*) current_desc;
5649
5650    ed->image.border.scale =  parse_enum(0,
5651                                         "0", 0,
5652                                         "1", 1,
5653                                         NULL);
5654 }
5655
5656 /**
5657     @page edcref
5658     @property
5659         scale_hint
5660     @parameters
5661         0, NONE, DYNAMIC, STATIC
5662     @effect
5663         Sets the evas image scale hint letting the engine more effectively save
5664         cached copies of the scaled image if it makes sense
5665     @endproperty
5666 */
5667 static void
5668 st_collections_group_parts_part_description_image_scale_hint(void)
5669 {
5670    Edje_Part_Description_Image *ed;
5671
5672    check_arg_count(1);
5673
5674    if (current_part->type != EDJE_PART_TYPE_IMAGE)
5675      {
5676         ERR("parse error %s:%i. image attributes in non-IMAGE part.",
5677             file_in, line - 1);
5678         exit(-1);
5679      }
5680
5681    ed = (Edje_Part_Description_Image*) current_desc;
5682
5683    ed->image.scale_hint =  parse_enum(0,
5684                                       "NONE", EVAS_IMAGE_SCALE_HINT_NONE,
5685                                       "DYNAMIC", EVAS_IMAGE_SCALE_HINT_DYNAMIC,
5686                                       "STATIC", EVAS_IMAGE_SCALE_HINT_STATIC,
5687                                       "0", EVAS_IMAGE_SCALE_HINT_NONE,
5688                                       NULL);
5689 }
5690
5691 /**
5692     @page edcref
5693     @block
5694         fill
5695     @context
5696         description {
5697             ..
5698             fill {
5699                 smooth: 0-1;
5700                 origin {
5701                     relative: X-axis Y-axis;
5702                     offset:   X-axis Y-axis;
5703                 }
5704                 size {
5705                     relative: width  height;
5706                     offset:   width  height;
5707                 }
5708             }
5709             ..
5710         }
5711     @description
5712         The fill method is an optional block that defines the way an IMAGE part
5713         is going to be displayed inside its container.
5714         It can be used for tiling (repeating the image) or displaying only
5715         part of an image. See @ref evas_object_image_fill_set() documentation
5716         for more details.
5717     @endblock
5718
5719     @property
5720         smooth
5721     @parameters
5722         [0 or 1]
5723     @effect
5724         The smooth property takes a boolean value to decide if the image will
5725         be smoothed on scaling (1) or not (0). The default value is 1.
5726     @endproperty
5727 */
5728 static void
5729 st_collections_group_parts_part_description_fill_smooth(void)
5730 {
5731    Edje_Part_Description_Spec_Fill *fill;
5732
5733    check_arg_count(1);
5734
5735    switch (current_part->type)
5736      {
5737       case EDJE_PART_TYPE_IMAGE:
5738         {
5739            Edje_Part_Description_Image *ed;
5740
5741            ed = (Edje_Part_Description_Image*) current_desc;
5742
5743            fill = &ed->image.fill;
5744            break;
5745         }
5746       case EDJE_PART_TYPE_PROXY:
5747         {
5748            Edje_Part_Description_Proxy *ed;
5749
5750            ed = (Edje_Part_Description_Proxy*) current_desc;
5751
5752            fill = &ed->proxy.fill;
5753            break;
5754         }
5755       default:
5756         {
5757            ERR("parse error %s:%i. "
5758                "image and proxy attributes in non-IMAGE, non-PROXY `%s` part (%i).",
5759                file_in, line - 1, current_part->name, current_part->type);
5760            exit(-1);
5761         }
5762      }
5763
5764    fill->smooth = parse_bool(0);
5765 }
5766
5767 /**
5768     @page edcref
5769
5770     @property
5771         spread
5772     @parameters
5773         TODO
5774     @effect
5775         TODO
5776     @endproperty
5777 */
5778 static void
5779 st_collections_group_parts_part_description_fill_spread(void)
5780 {
5781 #if 0
5782    Edje_Part_Collection *pc;
5783    Edje_Part *ep;
5784    Edje_Part_Description_Image *ed;
5785 #endif
5786
5787    check_arg_count(1);
5788
5789    /* XXX this will need to include IMAGES when spread support is added to evas images */
5790    {
5791       ERR("parse error %s:%i. fill.spread not supported yet.",
5792           file_in, line - 1);
5793       exit(-1);
5794    }
5795
5796 #if 0
5797    pc = eina_list_data_get(eina_list_last(edje_collections));
5798
5799    ep = pc->parts[pc->parts_count - 1];
5800
5801    if (ep->type != EDJE_PART_TYPE_IMAGE)
5802      {
5803         ERR("parse error %s:%i. image attributes in non-IMAGE part.",
5804             file_in, line - 1);
5805         exit(-1);
5806      }
5807
5808    ed = (Edje_Part_Description_Image*) ep->default_desc;
5809    if (ep->other.desc_count) ed = (Edje_Part_Description_Image*)  ep->other.desc[ep->other.desc_count - 1];
5810
5811    ed->image.fill.spread = parse_int_range(0, 0, 1);
5812 #endif
5813 }
5814
5815 /**
5816     @page edcref
5817
5818     @property
5819         type
5820     @parameters
5821         TODO
5822     @effect
5823         TODO
5824     @endproperty
5825 */
5826 static void
5827 st_collections_group_parts_part_description_fill_type(void)
5828 {
5829    Edje_Part_Description_Spec_Fill *fill;
5830
5831    check_arg_count(1);
5832
5833    switch (current_part->type)
5834      {
5835       case EDJE_PART_TYPE_IMAGE:
5836         {
5837            Edje_Part_Description_Image *ed;
5838
5839            ed = (Edje_Part_Description_Image*) current_desc;
5840
5841            fill = &ed->image.fill;
5842            break;
5843         }
5844       case EDJE_PART_TYPE_PROXY:
5845         {
5846            Edje_Part_Description_Proxy *ed;
5847
5848            ed = (Edje_Part_Description_Proxy*) current_desc;
5849
5850            fill = &ed->proxy.fill;
5851            break;
5852         }
5853       default:
5854         {
5855            ERR("parse error %s:%i. "
5856                "image and proxy attributes in non-IMAGE, non-PROXY part.",
5857                file_in, line - 1);
5858            exit(-1);
5859         }
5860      }
5861
5862    fill->type = parse_enum(0,
5863                            "SCALE", EDJE_FILL_TYPE_SCALE,
5864                            "TILE", EDJE_FILL_TYPE_TILE,
5865                            NULL);
5866 }
5867
5868 /**
5869     @page edcref
5870     @block
5871         origin
5872     @context
5873         description {
5874             ..
5875             fill {
5876                 ..
5877                 origin {
5878                     relative: 0.0 0.0;
5879                     offset:   0   0;
5880                 }
5881                 ..
5882             }
5883             ..
5884         }
5885     @description
5886         The origin block is used to place the starting point, inside the
5887         displayed element, that will be used to render the tile. By default,
5888         the origin is set at the element's left-up corner.
5889     @endblock
5890
5891     @property
5892         relative
5893     @parameters
5894         [X axis] [Y axis]
5895     @effect
5896         Sets the starting point relatively to displayed element's content.
5897     @endproperty
5898 */
5899 static void
5900 st_collections_group_parts_part_description_fill_origin_relative(void)
5901 {
5902    Edje_Part_Description_Spec_Fill *fill;
5903
5904    check_arg_count(2);
5905
5906    switch (current_part->type)
5907      {
5908       case EDJE_PART_TYPE_IMAGE:
5909         {
5910            Edje_Part_Description_Image *ed;
5911
5912            ed = (Edje_Part_Description_Image*) current_desc;
5913
5914            fill = &ed->image.fill;
5915            break;
5916         }
5917       case EDJE_PART_TYPE_PROXY:
5918         {
5919            Edje_Part_Description_Proxy *ed;
5920
5921            ed = (Edje_Part_Description_Proxy*) current_desc;
5922
5923            fill = &ed->proxy.fill;
5924            break;
5925         }
5926       default:
5927         {
5928            ERR("parse error %s:%i. "
5929                "image and proxy attributes in non-IMAGE, non-PROXY part.",
5930                file_in, line - 1);
5931            exit(-1);
5932         }
5933      }
5934
5935    fill->pos_rel_x = FROM_DOUBLE(parse_float_range(0, -999999999.0, 999999999.0));
5936    fill->pos_rel_y = FROM_DOUBLE(parse_float_range(1, -999999999.0, 999999999.0));
5937 }
5938
5939 /**
5940     @page edcref
5941     @property
5942         offset
5943     @parameters
5944         [X axis] [Y axis]
5945     @effect
5946         Affects the starting point a fixed number of pixels along each axis.
5947     @endproperty
5948 */
5949 static void
5950 st_collections_group_parts_part_description_fill_origin_offset(void)
5951 {
5952    Edje_Part_Description_Spec_Fill *fill;
5953
5954    check_arg_count(2);
5955
5956    switch (current_part->type)
5957      {
5958       case EDJE_PART_TYPE_IMAGE:
5959         {
5960            Edje_Part_Description_Image *ed;
5961
5962            ed = (Edje_Part_Description_Image*) current_desc;
5963
5964            fill = &ed->image.fill;
5965            break;
5966         }
5967       case EDJE_PART_TYPE_PROXY:
5968         {
5969            Edje_Part_Description_Proxy *ed;
5970
5971            ed = (Edje_Part_Description_Proxy*) current_desc;
5972
5973            fill = &ed->proxy.fill;
5974            break;
5975         }
5976       default:
5977         {
5978            ERR("parse error %s:%i. "
5979                "image and proxy attributes in non-IMAGE, non-PROXY part.",
5980                file_in, line - 1);
5981            exit(-1);
5982         }
5983      }
5984
5985    fill->pos_abs_x = parse_int(0);
5986    fill->pos_abs_y = parse_int(1);
5987 }
5988
5989 /**
5990     @page edcref
5991     @block
5992         size
5993     @context
5994         description {
5995             ..
5996             fill {
5997                 ..
5998                 size {
5999                     relative: 1.0 1.0;
6000                     offset:  -1  -1;
6001                 }
6002                 ..
6003             }
6004             ..
6005         }
6006     @description
6007         The size block defines the tile size of the content that will be
6008         displayed.
6009     @endblock
6010
6011     @property
6012         relative
6013     @parameters
6014         [width] [height]
6015     @effect
6016         Takes a pair of decimal values that represent the percentual value
6017         of the original size of the element. For example, "0.5 0.5" represents
6018         half the size, while "2.0 2.0" represents the double. The default
6019         value is "1.0 1.0".
6020     @endproperty
6021 */
6022 static void
6023 st_collections_group_parts_part_description_fill_size_relative(void)
6024 {
6025    Edje_Part_Description_Spec_Fill *fill;
6026
6027    check_arg_count(2);
6028
6029    switch (current_part->type)
6030      {
6031       case EDJE_PART_TYPE_IMAGE:
6032         {
6033            Edje_Part_Description_Image *ed;
6034
6035            ed = (Edje_Part_Description_Image*) current_desc;
6036
6037            fill = &ed->image.fill;
6038            break;
6039         }
6040       case EDJE_PART_TYPE_PROXY:
6041         {
6042            Edje_Part_Description_Proxy *ed;
6043
6044            ed = (Edje_Part_Description_Proxy*) current_desc;
6045
6046            fill = &ed->proxy.fill;
6047            break;
6048         }
6049       default:
6050         {
6051            ERR("parse error %s:%i. "
6052                "image and proxy attributes in non-IMAGE, non-PROXY part.",
6053                file_in, line - 1);
6054            exit(-1);
6055         }
6056      }
6057
6058    fill->rel_x = FROM_DOUBLE(parse_float_range(0, 0.0, 999999999.0));
6059    fill->rel_y = FROM_DOUBLE(parse_float_range(1, 0.0, 999999999.0));
6060 }
6061
6062 /**
6063     @page edcref
6064     @property
6065         offset
6066     @parameters
6067         [X axis] [Y axis]
6068     @effect
6069         Affects the size of the tile a fixed number of pixels along each axis.
6070     @endproperty
6071 */
6072 static void
6073 st_collections_group_parts_part_description_fill_size_offset(void)
6074 {
6075    Edje_Part_Description_Spec_Fill *fill;
6076
6077    check_arg_count(2);
6078
6079    switch (current_part->type)
6080      {
6081       case EDJE_PART_TYPE_IMAGE:
6082         {
6083            Edje_Part_Description_Image *ed;
6084
6085            ed = (Edje_Part_Description_Image*) current_desc;
6086
6087            fill = &ed->image.fill;
6088            break;
6089         }
6090       case EDJE_PART_TYPE_PROXY:
6091         {
6092            Edje_Part_Description_Proxy *ed;
6093
6094            ed = (Edje_Part_Description_Proxy*) current_desc;
6095
6096            fill = &ed->proxy.fill;
6097            break;
6098         }
6099       default:
6100         {
6101            ERR("parse error %s:%i. "
6102                "image and proxy attributes in non-IMAGE, non-PROXY part.",
6103                file_in, line - 1);
6104            exit(-1);
6105         }
6106      }
6107
6108    fill->abs_x = parse_int(0);
6109    fill->abs_y = parse_int(1);
6110 }
6111
6112
6113 /**
6114    @edcsection{description_text,Text state description sub blocks}
6115  */
6116
6117 /**
6118     @page edcref
6119
6120     @block
6121         text
6122     @context
6123         part {
6124             description {
6125                 ..
6126                 text {
6127                     text:        "some string of text to display";
6128                     font:        "font_name";
6129                     size:         SIZE;
6130                     text_class:  "class_name";
6131                     fit:          horizontal vertical;
6132                     min:          horizontal vertical;
6133                     max:          horizontal vertical;
6134                     align:        X-axis     Y-axis;
6135                     source:      "part_name";
6136                     text_source: "text_part_name";
6137                     ellipsis:     0.0-1.0;
6138                     style:       "stylename";
6139                 }
6140                 ..
6141             }
6142         }
6143     @description
6144     @endblock
6145
6146     @property
6147         text
6148     @parameters
6149         [a string of text, or nothing]
6150     @effect
6151         Sets the default content of a text part, normally the application is
6152         the one changing its value.
6153     @endproperty
6154 */
6155 static void
6156 st_collections_group_parts_part_description_text_text(void)
6157 {
6158    Edje_Part_Description_Text *ed;
6159    char *str = NULL;
6160    int i;
6161
6162    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6163        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6164      {
6165         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6166             file_in, line - 1);
6167         exit(-1);
6168      }
6169
6170    ed = (Edje_Part_Description_Text*) current_desc;
6171
6172    for (i = 0; ;i++)
6173      {
6174         char *s;
6175
6176         if (!is_param(i)) break;
6177         s = parse_str(i);
6178         if (!str) str = s;
6179         else
6180           {
6181              str = realloc(str, strlen(str) + strlen(s) + 1);
6182              strcat(str, s);
6183              free(s);
6184           }
6185      }
6186    ed->text.text.str = str;
6187 }
6188
6189 /**
6190     @page edcref
6191
6192     @property
6193         text_class
6194     @parameters
6195         [text class name]
6196     @effect
6197         Similar to color_class, this is the name used by the application
6198         to alter the font family and size at runtime.
6199     @endproperty
6200 */
6201 static void
6202 st_collections_group_parts_part_description_text_text_class(void)
6203 {
6204    Edje_Part_Description_Text *ed;
6205
6206    check_arg_count(1);
6207
6208    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6209        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6210      {
6211         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6212             file_in, line - 1);
6213         exit(-1);
6214      }
6215
6216    ed = (Edje_Part_Description_Text*) current_desc;
6217
6218    ed->text.text_class = parse_str(0);
6219 }
6220
6221 /**
6222     @page edcref
6223
6224     @property
6225         font
6226     @parameters
6227         [font alias]
6228     @effect
6229         This sets the font family to one of the aliases set up in the "fonts"
6230         block. Can be overrided by the application.
6231     @endproperty
6232 */
6233 static void
6234 st_collections_group_parts_part_description_text_font(void)
6235 {
6236    Edje_Part_Description_Text *ed;
6237
6238    check_arg_count(1);
6239
6240    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6241        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6242      {
6243         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6244             file_in, line - 1);
6245         exit(-1);
6246      }
6247
6248    ed = (Edje_Part_Description_Text*) current_desc;
6249
6250    ed->text.font.str = parse_str(0);
6251 }
6252
6253 /**
6254     @page edcref
6255
6256     @property
6257         style
6258     @parameters
6259         [the style name]
6260     @effect
6261         Causes the part to use the default style and tags defined in the
6262         "style" block with the specified name.
6263     @endproperty
6264 */
6265 static void
6266 st_collections_group_parts_part_description_text_style(void)
6267 {
6268    Edje_Part_Description_Text *ed;
6269
6270    check_arg_count(1);
6271
6272    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6273        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6274      {
6275         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6276             file_in, line - 1);
6277         exit(-1);
6278      }
6279
6280    ed = (Edje_Part_Description_Text*) current_desc;
6281
6282    ed->text.style.str = parse_str(0);
6283 }
6284
6285 /**
6286     @page edcref
6287
6288     @property
6289         repch
6290     @parameters
6291         [the replacement character string]
6292     @effect
6293         If this is a textblock and is in PASSWORD mode this string is used
6294         to replace every character to hide the details of the entry. Normally
6295         you would use a "*", but you can use anything you like.
6296     @endproperty
6297 */
6298 static void
6299 st_collections_group_parts_part_description_text_repch(void)
6300 {
6301    Edje_Part_Description_Text *ed;
6302
6303    check_arg_count(1);
6304
6305    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6306        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6307      {
6308         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6309             file_in, line - 1);
6310         exit(-1);
6311      }
6312
6313    ed = (Edje_Part_Description_Text*) current_desc;
6314
6315    ed->text.repch.str = parse_str(0);
6316 }
6317
6318 /**
6319     @page edcref
6320
6321     @property
6322         size
6323     @parameters
6324         [font size in points (pt)]
6325     @effect
6326         Sets the default font size for the text part. Can be overrided by the
6327         application.
6328     @endproperty
6329 */
6330 static void
6331 st_collections_group_parts_part_description_text_size(void)
6332 {
6333    Edje_Part_Description_Text *ed;
6334
6335    check_arg_count(1);
6336
6337    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6338        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6339      {
6340         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6341             file_in, line - 1);
6342         exit(-1);
6343      }
6344
6345    ed = (Edje_Part_Description_Text*)current_desc;
6346
6347    ed->text.size = parse_int_range(0, 0, 255);
6348 }
6349
6350 /**
6351     @page edcref
6352
6353     @property
6354         size_range
6355     @parameters
6356         [font min size in points (pt)] [font max size in points (pt)]
6357     @effect
6358         Sets the allowed font size for the text part. Setting min and max to 0
6359         means we won't restrict the sizing (default).
6360     @endproperty
6361     @since 1.1.0
6362 */
6363 static void
6364 st_collections_group_parts_part_description_text_size_range(void)
6365 {
6366    Edje_Part_Description_Text *ed;
6367
6368    check_arg_count(2);
6369
6370    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6371        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6372      {
6373         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6374             file_in, line - 1);
6375         exit(-1);
6376      }
6377
6378    ed = (Edje_Part_Description_Text*) current_desc;
6379
6380    ed->text.size_range_min = parse_int_range(0, 0, 255);
6381    ed->text.size_range_max = parse_int_range(1, 0, 255);
6382    if (ed->text.size_range_min > ed->text.size_range_max)
6383      {
6384         ERR("parse error %s:%i. min size is bigger than max size.",
6385             file_in, line - 1);
6386         exit(-1);
6387      }
6388 }
6389
6390 /**
6391     @page edcref
6392
6393     @property
6394         fit
6395     @parameters
6396         [horizontal] [vertical]
6397     @effect
6398         When any of the parameters is set to 1 edje will resize the text for it
6399         to fit in it's container. Both are disabled by default.
6400     @endproperty
6401 */
6402 static void
6403 st_collections_group_parts_part_description_text_fit(void)
6404 {
6405    Edje_Part_Description_Text *ed;
6406
6407    check_arg_count(2);
6408
6409    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6410        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6411      {
6412         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6413             file_in, line - 1);
6414         exit(-1);
6415      }
6416
6417    ed = (Edje_Part_Description_Text*) current_desc;
6418
6419    ed->text.fit_x = parse_bool(0);
6420    ed->text.fit_y = parse_bool(1);
6421 }
6422
6423 /**
6424     @page edcref
6425
6426     @property
6427         min
6428     @parameters
6429         [horizontal] [vertical]
6430     @effect
6431         When any of the parameters is enabled (1) it forces the minimum size of
6432         the container to be equal to the minimum size of the text. The default
6433         value is "0 0".
6434     @endproperty
6435 */
6436 static void
6437 st_collections_group_parts_part_description_text_min(void)
6438 {
6439    Edje_Part_Description_Text *ed;
6440
6441    check_arg_count(2);
6442
6443    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6444        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6445      {
6446         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6447             file_in, line - 1);
6448         exit(-1);
6449      }
6450
6451    ed = (Edje_Part_Description_Text*)current_desc;
6452
6453    ed->text.min_x = parse_bool(0);
6454    ed->text.min_y = parse_bool(1);
6455 }
6456
6457 /**
6458     @page edcref
6459
6460     @property
6461         max
6462     @parameters
6463         [horizontal] [vertical]
6464     @effect
6465         When any of the parameters is enabled (1) it forces the maximum size of
6466         the container to be equal to the maximum size of the text. The default
6467         value is "0 0".
6468     @endproperty
6469 */
6470 static void
6471 st_collections_group_parts_part_description_text_max(void)
6472 {
6473    Edje_Part_Description_Text *ed;
6474
6475    check_arg_count(2);
6476
6477    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6478        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6479      {
6480         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6481             file_in, line - 1);
6482         exit(-1);
6483      }
6484
6485    ed = (Edje_Part_Description_Text*) current_desc;
6486
6487    ed->text.max_x = parse_bool(0);
6488    ed->text.max_y = parse_bool(1);
6489 }
6490
6491 /**
6492     @page edcref
6493
6494     @property
6495         align
6496     @parameters
6497         [horizontal] [vertical]
6498     @effect
6499         Change the position of the point of balance inside the container. The
6500         default value is 0.5 0.5.
6501     @endproperty
6502 */
6503 static void
6504 st_collections_group_parts_part_description_text_align(void)
6505 {
6506    Edje_Part_Description_Text *ed;
6507
6508    check_arg_count(2);
6509
6510    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6511        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6512      {
6513         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6514             file_in, line - 1);
6515         exit(-1);
6516      }
6517
6518    ed = (Edje_Part_Description_Text*) current_desc;
6519
6520    ed->text.align.x = FROM_DOUBLE(parse_float_range(0, -1.0, 1.0));
6521    ed->text.align.y = FROM_DOUBLE(parse_float_range(1, 0.0, 1.0));
6522 }
6523
6524 /**
6525     @page edcref
6526
6527     @property
6528         source
6529     @parameters
6530         [another TEXT part's name]
6531     @effect
6532         Causes the part to use the text properties (like font and size) of
6533         another part and update them as they change.
6534     @endproperty
6535 */
6536 static void
6537 st_collections_group_parts_part_description_text_source(void)
6538 {
6539    Edje_Part_Collection *pc;
6540    Edje_Part_Description_Text *ed;
6541
6542    check_arg_count(1);
6543
6544    pc = eina_list_data_get(eina_list_last(edje_collections));
6545
6546    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6547        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6548      {
6549         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6550             file_in, line - 1);
6551         exit(-1);
6552      }
6553
6554    ed = (Edje_Part_Description_Text*) current_desc;
6555
6556    {
6557       char *name;
6558
6559       name = parse_str(0);
6560       data_queue_part_lookup(pc, name, &(ed->text.id_source));
6561       free(name);
6562    }
6563 }
6564
6565 /**
6566     @page edcref
6567
6568     @property
6569         text_source
6570     @parameters
6571         [another TEXT part's name]
6572     @effect
6573         Causes the part to display the text content of another part and update
6574         them as they change.
6575     @endproperty
6576 */
6577 static void
6578 st_collections_group_parts_part_description_text_text_source(void)
6579 {
6580    Edje_Part_Collection *pc;
6581    Edje_Part_Description_Text *ed;
6582
6583    check_arg_count(1);
6584
6585    pc = eina_list_data_get(eina_list_last(edje_collections));
6586
6587    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6588        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6589      {
6590         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6591             file_in, line - 1);
6592         exit(-1);
6593      }
6594
6595    ed = (Edje_Part_Description_Text*) current_desc;
6596
6597    {
6598       char *name;
6599
6600       name = parse_str(0);
6601       data_queue_part_lookup(pc, name, &(ed->text.id_text_source));
6602       free(name);
6603    }
6604 }
6605
6606 /**
6607     @page edcref
6608
6609     @property
6610         ellipsis
6611     @parameters
6612         [point of balance]
6613     @effect
6614         Used to balance the text in a relative point from 0.0 to 1.0, this
6615         point is the last section of the string to be cut out in case of a
6616         resize that is smaller than the text itself. The default value is 0.0.
6617     @endproperty
6618 */
6619 static void
6620 st_collections_group_parts_part_description_text_elipsis(void)
6621 {
6622    Edje_Part_Description_Text *ed;
6623
6624    check_arg_count(1);
6625
6626    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6627        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6628      {
6629         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6630             file_in, line - 1);
6631         exit(-1);
6632      }
6633
6634    ed = (Edje_Part_Description_Text*) current_desc;
6635
6636    ed->text.elipsis = parse_float_range(0, 0.0, 1.0);
6637 }
6638
6639
6640 /**
6641    @edcsection{description_box,Box state description sub blocks}
6642  */
6643
6644 /**
6645     @page edcref
6646
6647     @block
6648         box
6649     @context
6650         part {
6651             description {
6652                 ..
6653                 box {
6654                     layout: "vertical";
6655                     padding: 0 2;
6656                     align: 0.5 0.5;
6657                     min: 0 0;
6658                 }
6659                 ..
6660             }
6661         }
6662     @description
6663         A box block can contain other objects and display them in different
6664         layouts, any of the predefined set, or a custom one, set by the
6665         application.
6666     @endblock
6667
6668     @property
6669         layout
6670     @parameters
6671         [primary layout] [fallback layout]
6672     @effect
6673         Sets the layout for the box:
6674             @li horizontal (default)
6675             @li vertical
6676             @li horizontal_homogeneous
6677             @li vertical_homogeneous
6678             @li horizontal_max (homogeneous to the max sized child)
6679             @li vertical_max
6680             @li horizontal_flow
6681             @li vertical_flow
6682             @li stack
6683             @li some_other_custom_layout_set_by_the_application
6684         You could set a custom layout as fallback, it makes very
6685         very little sense though, and if that one fails, it will
6686         default to horizontal.
6687     @endproperty
6688
6689     @property
6690         align
6691     @parameters
6692         [horizontal] [vertical]
6693     @effect
6694         Change the position of the point of balance inside the container. The
6695         default value is 0.5 0.5.
6696     @endproperty
6697
6698     @property
6699         padding
6700     @parameters
6701         [horizontal] [vertical]
6702     @effect
6703         Sets the space between cells in pixels. Defaults to 0 0.
6704     @endproperty
6705
6706     @property
6707         min
6708     @parameters
6709         [horizontal] [vertical]
6710     @effect
6711         When any of the parameters is enabled (1) it forces the minimum size of
6712         the box to be equal to the minimum size of the items. The default
6713         value is "0 0".
6714     @endproperty
6715 */
6716 static void st_collections_group_parts_part_description_box_layout(void)
6717 {
6718    Edje_Part_Description_Box *ed;
6719
6720    check_min_arg_count(1);
6721
6722    if (current_part->type != EDJE_PART_TYPE_BOX)
6723      {
6724         ERR("parse error %s:%i. box attributes in non-BOX part.",
6725             file_in, line - 1);
6726         exit(-1);
6727      }
6728
6729    ed = (Edje_Part_Description_Box*) current_desc;
6730
6731    ed->box.layout = parse_str(0);
6732    if (is_param(1))
6733      ed->box.alt_layout = parse_str(1);
6734 }
6735
6736 static void st_collections_group_parts_part_description_box_align(void)
6737 {
6738    Edje_Part_Description_Box *ed;
6739
6740    check_arg_count(2);
6741
6742    if (current_part->type != EDJE_PART_TYPE_BOX)
6743      {
6744         ERR("parse error %s:%i. box attributes in non-BOX part.",
6745             file_in, line - 1);
6746         exit(-1);
6747      }
6748
6749    ed = (Edje_Part_Description_Box*) current_desc;
6750
6751    ed->box.align.x = FROM_DOUBLE(parse_float_range(0, -1.0, 1.0));
6752    ed->box.align.y = FROM_DOUBLE(parse_float_range(1, -1.0, 1.0));
6753 }
6754
6755 static void st_collections_group_parts_part_description_box_padding(void)
6756 {
6757    Edje_Part_Description_Box *ed;
6758
6759    check_arg_count(2);
6760
6761    if (current_part->type != EDJE_PART_TYPE_BOX)
6762      {
6763         ERR("parse error %s:%i. box attributes in non-BOX part.",
6764             file_in, line - 1);
6765         exit(-1);
6766      }
6767
6768    ed = (Edje_Part_Description_Box*) current_desc;
6769
6770    ed->box.padding.x = parse_int_range(0, 0, 0x7fffffff);
6771    ed->box.padding.y = parse_int_range(1, 0, 0x7fffffff);
6772 }
6773
6774 static void
6775 st_collections_group_parts_part_description_box_min(void)
6776 {
6777    Edje_Part_Description_Box *ed;
6778
6779    check_arg_count(2);
6780
6781    if (current_part->type != EDJE_PART_TYPE_BOX)
6782      {
6783         ERR("parse error %s:%i. box attributes in non-BOX part.",
6784             file_in, line - 1);
6785         exit(-1);
6786      }
6787
6788    ed = (Edje_Part_Description_Box*) current_desc;
6789
6790    ed->box.min.h = parse_bool(0);
6791    ed->box.min.v = parse_bool(1);
6792 }
6793
6794
6795 /**
6796    @edcsection{description_table,Table state description sub blocks}
6797  */
6798
6799 /**
6800     @page edcref
6801
6802     @block
6803         table
6804     @context
6805         part {
6806             description {
6807                 ..
6808                 table {
6809                     homogeneous: TABLE;
6810                     padding: 0 2;
6811                     align: 0.5 0.5;
6812                     min: 0 0;
6813                 }
6814                 ..
6815             }
6816         }
6817     @description
6818         A table block can contain other objects packed in multiple columns
6819         and rows, and each item can span across more than one column and/or
6820         row.
6821     @endblock
6822
6823     @property
6824         homogeneous
6825     @parameters
6826         [homogeneous mode]
6827     @effect
6828         Sets the homogeneous mode for the table:
6829             @li NONE (default)
6830             @li TABLE
6831             @li ITEM
6832     @endproperty
6833
6834     @property
6835         align
6836     @parameters
6837         [horizontal] [vertical]
6838     @effect
6839         Change the position of the point of balance inside the container. The
6840         default value is 0.5 0.5.
6841     @endproperty
6842
6843     @property
6844         padding
6845     @parameters
6846         [horizontal] [vertical]
6847     @effect
6848         Sets the space between cells in pixels. Defaults to 0 0.
6849     @endproperty
6850
6851     @property
6852         min
6853     @parameters
6854         [horizontal] [vertical]
6855     @effect
6856         When any of the parameters is enabled (1) it forces the minimum size of
6857         the table to be equal to the minimum size of the items. The default
6858         value is "0 0".
6859     @endproperty
6860 */
6861 static void st_collections_group_parts_part_description_table_homogeneous(void)
6862 {
6863    Edje_Part_Description_Table *ed;
6864
6865    check_min_arg_count(1);
6866
6867    if (current_part->type != EDJE_PART_TYPE_TABLE)
6868      {
6869         ERR("parse error %s:%i. table attributes in non-TABLE part.",
6870             file_in, line - 1);
6871         exit(-1);
6872      }
6873
6874    ed = (Edje_Part_Description_Table*) current_desc;
6875
6876    ed->table.homogeneous = parse_enum(0,
6877                                      "NONE", EDJE_OBJECT_TABLE_HOMOGENEOUS_NONE,
6878                                      "TABLE", EDJE_OBJECT_TABLE_HOMOGENEOUS_TABLE,
6879                                      "ITEM", EDJE_OBJECT_TABLE_HOMOGENEOUS_ITEM,
6880                                      NULL);
6881 }
6882
6883 static void st_collections_group_parts_part_description_table_align(void)
6884 {
6885    Edje_Part_Description_Table *ed;
6886
6887    check_arg_count(2);
6888
6889    if (current_part->type != EDJE_PART_TYPE_TABLE)
6890      {
6891         ERR("parse error %s:%i. table attributes in non-TABLE part.",
6892             file_in, line - 1);
6893         exit(-1);
6894      }
6895
6896    ed = (Edje_Part_Description_Table*) current_desc;
6897
6898    ed->table.align.x = FROM_DOUBLE(parse_float_range(0, -1.0, 1.0));
6899    ed->table.align.y = FROM_DOUBLE(parse_float_range(1, -1.0, 1.0));
6900 }
6901
6902 static void st_collections_group_parts_part_description_table_padding(void)
6903 {
6904    Edje_Part_Description_Table *ed;
6905
6906    check_arg_count(2);
6907
6908    if (current_part->type != EDJE_PART_TYPE_TABLE)
6909      {
6910         ERR("parse error %s:%i. table attributes in non-TABLE part.",
6911             file_in, line - 1);
6912         exit(-1);
6913      }
6914
6915    ed = (Edje_Part_Description_Table*) current_desc;
6916
6917    ed->table.padding.x = parse_int_range(0, 0, 0x7fffffff);
6918    ed->table.padding.y = parse_int_range(1, 0, 0x7fffffff);
6919 }
6920
6921 static void
6922 st_collections_group_parts_part_description_table_min(void)
6923 {
6924    Edje_Part_Description_Table *ed;
6925
6926    check_arg_count(2);
6927
6928    if (current_part->type != EDJE_PART_TYPE_TABLE)
6929      {
6930         ERR("parse error %s:%i. box attributes in non-TABLE part.",
6931             file_in, line - 1);
6932         exit(-1);
6933      }
6934
6935    ed = (Edje_Part_Description_Table*) current_desc;
6936
6937    ed->table.min.h = parse_bool(0);
6938    ed->table.min.v = parse_bool(1);
6939 }
6940
6941 /**
6942    @edcsection{description_map,Map state description sub blocks}
6943  */
6944
6945 /**
6946     @page edcref
6947     @block
6948         map
6949     @context
6950     description {
6951         ..
6952         map {
6953             perspective: "name";
6954             light: "name";
6955             on: 1;
6956             smooth: 1;
6957             perspective_on: 1;
6958             backface_cull: 1;
6959             alpha: 1;
6960             
6961             rotation {
6962                 ..
6963             }
6964         }
6965         ..
6966     }
6967     
6968     @description
6969     @endblock
6970     
6971     @property
6972         perspective
6973     @parameters
6974         [another part's name]
6975     @effect
6976         This sets the part that is used as the "perspective point" for giving
6977         a part a "3d look". The perspective point should have a perspective
6978         section that provides zplane and focal properties. The center of this
6979         part will be used as the focal point, so size, color and visibility
6980         etc. are not relevant just center point, zplane and focal are used.
6981         This also implicitly enables perspective transforms (see the on
6982         parameter for the map section).
6983     @endproperty
6984 */
6985 static void
6986 st_collections_group_parts_part_description_map_perspective(void)
6987 {
6988    Edje_Part_Collection *pc;
6989
6990    check_arg_count(1);
6991
6992    pc = eina_list_data_get(eina_list_last(edje_collections));
6993
6994    {
6995       char *name;
6996
6997       name = parse_str(0);
6998       data_queue_part_lookup(pc, name, &(current_desc->map.id_persp));
6999       free(name);
7000    }
7001
7002    current_desc->map.persp_on = 1;
7003 }
7004
7005 /**
7006     @page edcref
7007     @property
7008         light
7009     @parameters
7010         [another part's name]
7011     @effect
7012         This sets the part that is used as the "light" for calculating the
7013         brightness (based on how directly the part's surface is facing the
7014         light source point). Like the perspective point part, the center point
7015         is used and zplane is used for the z position (0 being the zero-plane
7016         where all 2D objects normally live) and positive values being further
7017         away into the distance. The light part color is used as the light
7018         color (alpha not used for light color). The color2 color is used for
7019         the ambient lighting when calculating brightness (alpha also not
7020         used).
7021     @endproperty
7022 */
7023 static void
7024 st_collections_group_parts_part_description_map_light(void)
7025 {
7026    Edje_Part_Collection *pc;
7027
7028    check_arg_count(1);
7029
7030    pc = eina_list_data_get(eina_list_last(edje_collections));
7031
7032    {
7033       char *name;
7034
7035       name = parse_str(0);
7036       data_queue_part_lookup(pc, name, &(current_desc->map.id_light));
7037       free(name);
7038    }
7039 }
7040
7041 /**
7042     @page edcref
7043     @property
7044         on
7045     @parameters
7046         [1 or 0]
7047     @effect
7048         This enables mapping for the part. Default is 0.
7049     @endproperty
7050 */
7051 static void
7052 st_collections_group_parts_part_description_map_on(void)
7053 {
7054    check_arg_count(1);
7055
7056    current_desc->map.on = parse_bool(0);
7057 }
7058
7059 /**
7060     @page edcref
7061     @property
7062         smooth
7063     @parameters
7064         [1 or 0]
7065     @effect
7066         This enable smooth map rendering. This may be linear interpolation,
7067         anisotropic filtering or anything the engine decides is "smooth".
7068         This is a best-effort hint and may not produce precisely the same
7069         results in all engines and situations. Default is 1
7070     @endproperty
7071 */
7072 static void
7073 st_collections_group_parts_part_description_map_smooth(void)
7074 {
7075    check_arg_count(1);
7076
7077    current_desc->map.smooth = parse_bool(0);
7078 }
7079
7080 /**
7081     @page edcref
7082     @property
7083         alpha
7084     @parameters
7085         [1 or 0]
7086     @effect
7087         This enable alpha channel when map rendering. Default is 1.
7088     @endproperty
7089 */
7090 static void
7091 st_collections_group_parts_part_description_map_alpha(void)
7092 {
7093    check_arg_count(1);
7094
7095    current_desc->map.alpha = parse_bool(0);
7096 }
7097
7098 /**
7099     @page edcref
7100     @property
7101         backface_cull
7102     @parameters
7103         [1 or 0]
7104     @effect
7105         This enables backface culling (when the rotated part that normally
7106         faces the camera is facing away after being rotated etc.). This means
7107         that the object will be hidden when "backface culled".
7108     @endproperty
7109 */
7110 static void
7111 st_collections_group_parts_part_description_map_backface_cull(void)
7112 {
7113    check_arg_count(1);
7114
7115    current_desc->map.backcull = parse_bool(0);
7116 }
7117
7118 /**
7119     @page edcref
7120     @property
7121         perspective_on
7122     @parameters
7123        [1 or 0]
7124     @effect
7125         Enable perspective when rotating even without a perspective point object.
7126         This would use perspective set for the object itself or for the
7127         canvas as a whole as the global perspective with 
7128         edje_perspective_set() and edje_perspective_global_set().
7129     @endproperty
7130 */
7131 static void
7132 st_collections_group_parts_part_description_map_perspective_on(void)
7133 {
7134    check_arg_count(1);
7135
7136    current_desc->map.persp_on = parse_bool(0);
7137 }
7138 /**
7139     @page edcref
7140     @block
7141         rotation
7142     @context
7143     map {
7144         ..
7145         rotation {
7146             center: "name";
7147             x: 45.0;
7148             y: 45.0;
7149             z: 45.0;
7150         }
7151         ..
7152     }
7153     @description
7154         Rotates the part, optionally with the center on another part.
7155     @endblock
7156     
7157     @property
7158         center
7159     @parameters
7160         [another part's name]
7161     @effect
7162         This sets the part that is used as the center of rotation when
7163         rotating the part with this description. The part's center point
7164         is used as the rotation center when applying rotation around the
7165         x, y and z axes. If no center is given, the parts original center
7166         itself is used for the rotation center.
7167     @endproperty
7168 */
7169 static void
7170 st_collections_group_parts_part_description_map_rotation_center(void)
7171 {
7172    Edje_Part_Collection *pc;
7173
7174    check_arg_count(1);
7175
7176    pc = eina_list_data_get(eina_list_last(edje_collections));
7177
7178    {
7179       char *name;
7180
7181       name = parse_str(0);
7182       data_queue_part_lookup(pc, name, &(current_desc->map.rot.id_center));
7183       free(name);
7184    }
7185 }
7186
7187 /**
7188     @page edcref
7189     @property
7190         x
7191     @parameters
7192         [X degrees]
7193     @effect
7194         This sets the rotation around the x axis of the part considering
7195         the center set. In degrees.
7196     @endproperty
7197 */
7198 static void
7199 st_collections_group_parts_part_description_map_rotation_x(void)
7200 {
7201    check_arg_count(1);
7202
7203    current_desc->map.rot.x = FROM_DOUBLE(parse_float(0));
7204 }
7205
7206 /**
7207     @page edcref
7208     @property
7209         y
7210     @parameters
7211         [Y degrees]
7212     @effect
7213         This sets the rotation around the y axis of the part considering
7214         the center set. In degrees.
7215     @endproperty
7216 */
7217 static void
7218 st_collections_group_parts_part_description_map_rotation_y(void)
7219 {
7220    check_arg_count(1);
7221
7222    current_desc->map.rot.y = FROM_DOUBLE(parse_float(0));
7223 }
7224
7225 /**
7226     @page edcref
7227     @property
7228         z
7229     @parameters
7230         [Z degrees]
7231     @effect
7232         This sets the rotation around the z axis of the part considering
7233         the center set. In degrees.
7234     @endproperty
7235 */
7236 static void
7237 st_collections_group_parts_part_description_map_rotation_z(void)
7238 {
7239    check_arg_count(1);
7240
7241    current_desc->map.rot.z = FROM_DOUBLE(parse_float(0));
7242 }
7243
7244 /**
7245     @page edcref
7246     @block
7247         perspective
7248     @context
7249     description {
7250         ..
7251         perspective {
7252             zplane: 0;
7253             focal: 1000;
7254         }
7255         ..
7256     }
7257     @description
7258         Adds focal and plane perspective to the part. Active if perspective_on is true.
7259         Must be provided if the part is being used by other part as it's perspective target.
7260     @endblock
7261     
7262     @property
7263         zplane
7264     @parameters
7265         [unscaled Z value]
7266     @effect
7267         This sets the z value that will not be scaled. Normally this is 0 as
7268         that is the z distance that all objects are at normally.
7269     @endproperty
7270 */
7271 static void
7272 st_collections_group_parts_part_description_perspective_zplane(void)
7273 {
7274    check_arg_count(1);
7275
7276    current_desc->persp.zplane = parse_int(0);
7277 }
7278
7279
7280 /**
7281     @page edcref
7282     @property
7283         focal
7284     @parameters
7285         [distance]
7286     @effect
7287         This sets the distance from the focal z plane (zplane) and the
7288         camera - i.e. very much equating to focal length of the camera
7289     @endproperty
7290 */
7291 static void
7292 st_collections_group_parts_part_description_perspective_focal(void)
7293 {
7294    check_arg_count(1);
7295
7296    current_desc->persp.focal = parse_int_range(0, 1, 0x7fffffff);
7297 }
7298
7299
7300 /**
7301    @edcsection{description_params,Params state description sub blocks}
7302  */
7303
7304 /**
7305     @page edcref
7306     @block
7307         params
7308     @context
7309     description {
7310         ..
7311         params {
7312             int: "name" 0;
7313             double: "other_name" 0.0;
7314             string: "another_name" "some text";
7315             bool: "name" 1;
7316             choice: "some_name" "value";
7317         }
7318         ..
7319     }
7320     @description
7321         Set parameters for EXTERNAL parts. The value overwrites previous
7322         definitions with the same name.
7323     @endblock
7324 */
7325 static void
7326 _st_collections_group_parts_part_description_params(Edje_External_Param_Type type)
7327 {
7328    Edje_Part_Description_External *ed;
7329    Edje_External_Param *param;
7330    Eina_List *l;
7331    const char *name;
7332    int found = 0;
7333
7334    check_arg_count(2);
7335
7336    if (current_part->type != EDJE_PART_TYPE_EXTERNAL)
7337      {
7338         ERR("parse error %s:%i. params in non-EXTERNAL part.",
7339             file_in, line - 1);
7340         exit(-1);
7341      }
7342
7343    ed = (Edje_Part_Description_External*) current_desc;
7344
7345    name = parse_str(0);
7346
7347    /* if a param with this name already exists, overwrite it */
7348    EINA_LIST_FOREACH(ed->external_params, l, param)
7349      {
7350         if (!strcmp(param->name, name))
7351           {
7352              found = 1;
7353              break;
7354           }
7355      }
7356
7357    if (!found)
7358      {
7359         param = mem_alloc(SZ(Edje_External_Param));
7360         param->name = name;
7361      }
7362
7363    param->type = type;
7364    param->i = 0;
7365    param->d = 0;
7366    param->s = NULL;
7367
7368    switch (type)
7369      {
7370       case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
7371       case EDJE_EXTERNAL_PARAM_TYPE_INT:
7372          param->i = parse_int(1);
7373          break;
7374       case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
7375          param->d = parse_float(1);
7376          break;
7377       case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
7378       case EDJE_EXTERNAL_PARAM_TYPE_STRING:
7379          param->s = parse_str(1);
7380          break;
7381       default:
7382          ERR("parse error %s:%i. Invalid param type.",
7383              file_in, line - 1);
7384          break;
7385      }
7386
7387    if (!found)
7388      ed->external_params = eina_list_append(ed->external_params, param);
7389 }
7390
7391 /**
7392     @page edcref
7393     @property
7394         int
7395     @parameters
7396         [param_name] [int_value]
7397     @effect
7398         Adds an integer parameter for an external object
7399     @endproperty
7400 */
7401 static void
7402 st_collections_group_parts_part_description_params_int(void)
7403 {
7404    _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_INT);
7405 }
7406
7407 /**
7408     @page edcref
7409     @property
7410         double
7411     @parameters
7412         [param_name] [double_value]
7413     @effect
7414         Adds a double parameter for an external object
7415     @endproperty
7416 */
7417 static void
7418 st_collections_group_parts_part_description_params_double(void)
7419 {
7420    _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_DOUBLE);
7421 }
7422
7423 /**
7424     @page edcref
7425     @property
7426         string
7427     @parameters
7428         [param_name] [string_value]
7429     @effect
7430         Adds a string parameter for an external object
7431     @endproperty
7432 */
7433 static void
7434 st_collections_group_parts_part_description_params_string(void)
7435 {
7436    _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_STRING);
7437 }
7438
7439 /**
7440     @page edcref
7441     @property
7442         bool
7443     @parameters
7444         [param_name] [bool_value]
7445     @effect
7446         Adds an boolean parameter for an external object. Value must be 0 or 1.
7447     @endproperty
7448 */
7449 static void
7450 st_collections_group_parts_part_description_params_bool(void)
7451 {
7452    _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_BOOL);
7453 }
7454
7455 /**
7456     @page edcref
7457     @property
7458         choice
7459     @parameters
7460         [param_name] [choice_string]
7461     @effect
7462         Adds a choice parameter for an external object. The possible
7463         choice values are defined by external type at their register time
7464         and will be validated at runtime.
7465     @endproperty
7466 */
7467 static void
7468 st_collections_group_parts_part_description_params_choice(void)
7469 {
7470    _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_CHOICE);
7471 }
7472
7473
7474 /**
7475    @edcsection{program, Program block}
7476  */
7477
7478 /**
7479     @page edcref
7480     @block
7481         program
7482     @context
7483         group {
7484             programs {
7485                ..
7486                   program {
7487                      name: "programname";
7488                      signal: "signalname";
7489                      source: "partname";
7490                      filter: "partname" "statename";
7491                      in: 0.3 0.0;
7492                      action: STATE_SET "statename" state_value;
7493                      transition: LINEAR 0.5;
7494                      target: "partname";
7495                      target: "anotherpart";
7496                      after: "programname";
7497                      after: "anotherprogram";
7498                   }
7499                ..
7500             }
7501         }
7502     @description
7503         Programs define how your interface reacts to events.
7504         Programs can change the state of parts, react to events or trigger
7505         other events.
7506     @endblock
7507 */
7508 static void
7509 ob_collections_group_programs_program(void)
7510 {
7511    Edje_Part_Collection *pc;
7512    Edje_Program *ep;
7513    Edje_Program_Parser *epp;
7514
7515    pc = eina_list_data_get(eina_list_last(edje_collections));
7516
7517    ep = mem_alloc(SZ(Edje_Program_Parser));
7518    ep->id = -1;
7519    ep->tween.mode = EDJE_TWEEN_MODE_LINEAR;
7520    ep->after = NULL;
7521    epp = (Edje_Program_Parser *)ep;
7522    epp->can_override = EINA_FALSE;
7523
7524    _edje_program_insert(pc, ep);
7525
7526    current_program = ep;
7527 }
7528
7529 /**
7530     @page edcref
7531     @property
7532         name
7533     @parameters
7534         [program name]
7535     @effect
7536         Symbolic name of program as a unique identifier.
7537     @endproperty
7538 */
7539 static void
7540 st_collections_group_programs_program_name(void)
7541 {
7542    Edje_Part_Collection *pc;
7543
7544    check_arg_count(1);
7545
7546    pc = eina_list_data_get(eina_list_last(edje_collections));
7547    current_program->name = parse_str(0);
7548
7549    _edje_program_check(current_program->name, current_program, pc->programs.fnmatch, pc->programs.fnmatch_count);
7550    _edje_program_check(current_program->name, current_program, pc->programs.strcmp, pc->programs.strcmp_count);
7551    _edje_program_check(current_program->name, current_program, pc->programs.strncmp, pc->programs.strncmp_count);
7552    _edje_program_check(current_program->name, current_program, pc->programs.strrncmp, pc->programs.strrncmp_count);
7553    _edje_program_check(current_program->name, current_program, pc->programs.nocmp, pc->programs.nocmp_count);
7554 }
7555
7556 /**
7557     @page edcref
7558     @property
7559         signal
7560     @parameters
7561         [signal name]
7562     @effect
7563         Specifies signal(s) that should cause the program to run. The signal
7564         received must match the specified source to run.
7565         Signals may be globbed, but only one signal keyword per program
7566         may be used. ex: signal: "mouse,clicked,*"; (clicking any mouse button
7567         that matches source starts program).
7568     @endproperty
7569 */
7570 static void
7571 st_collections_group_programs_program_signal(void)
7572 {
7573    Edje_Part_Collection *pc;
7574
7575    check_arg_count(1);
7576
7577    pc = eina_list_data_get(eina_list_last(edje_collections));
7578
7579    _edje_program_remove(pc, current_program);
7580    current_program->signal = parse_str(0);
7581    _edje_program_insert(pc, current_program);
7582 }
7583
7584 /**
7585     @page edcref
7586     @property
7587         source
7588     @parameters
7589         [source name]
7590     @effect
7591         Source of accepted signal. Sources may be globbed, but only one source
7592         keyword per program may be used. ex:source: "button-*"; (Signals from
7593         any part or program named "button-*" are accepted).
7594     @endproperty
7595 */
7596 static void
7597 st_collections_group_programs_program_source(void)
7598 {
7599    Edje_Part_Collection *pc;
7600
7601    check_arg_count(1);
7602
7603    pc = eina_list_data_get(eina_list_last(edje_collections));
7604
7605    _edje_program_remove(pc, current_program);
7606    current_program->source = parse_str(0);
7607    _edje_program_insert(pc, current_program);
7608 }
7609
7610 /**
7611     @page edcref
7612     @property
7613         filter
7614     @parameters
7615         [part] [state]
7616     @effect
7617         Filter signals to be only accepted if the part [part] is in state named [state].
7618         Only one filter per program can be used. If [state] is not given, the source of
7619         the event will be used instead.
7620     @endproperty
7621 */
7622 static void
7623 st_collections_group_programs_program_filter(void)
7624 {
7625    check_min_arg_count(1);
7626
7627    if(is_param(1)) {
7628            current_program->filter.part = parse_str(0);
7629            current_program->filter.state = parse_str(1);
7630    } else {
7631            current_program->filter.state = parse_str(0);
7632    }
7633 }
7634
7635 /**
7636     @page edcref
7637     @property
7638         in
7639     @parameters
7640         [from] [range]
7641     @effect
7642         Wait 'from' seconds before executing the program. And add a random
7643         number of seconds (from 0 to 'range') to the total waiting time.
7644     @endproperty
7645 */
7646 static void
7647 st_collections_group_programs_program_in(void)
7648 {
7649    check_arg_count(2);
7650
7651    current_program->in.from = parse_float_range(0, 0.0, 999999999.0);
7652    current_program->in.range = parse_float_range(1, 0.0, 999999999.0);
7653 }
7654
7655 /**
7656     @page edcref
7657     @property
7658         action
7659     @parameters
7660         [type] [param1] [param2]
7661     @effect
7662         Action to be performed by the program. Valid actions are: STATE_SET,
7663         ACTION_STOP, SIGNAL_EMIT, DRAG_VAL_SET, DRAG_VAL_STEP, DRAG_VAL_PAGE,
7664         FOCUS_SET, PARAM_COPY, PARAM_SET, PLAY_SAMPLE, PLAY_TONE
7665         Only one action can be specified per program. Examples:\n
7666            action: STATE_SET "statename" 0.5;\n
7667            action: ACTION_STOP;\n
7668            action: SIGNAL_EMIT "signalname" "emitter";\n
7669            action: DRAG_VAL_SET 0.5 0.0;\n
7670            action: DRAG_VAL_STEP 1.0 0.0;\n
7671            action: DRAG_VAL_PAGE 0.0 0.0;\n
7672            action: FOCUS_SET;\n
7673            action: FOCUS_OBJECT;\n
7674            action: PARAM_COPY "src_part" "src_param" "dst_part" "dst_param";\n
7675            action: PARAM_SET "part" "param" "value";\n
7676            action: PLAY_SAMPLE "sample name";\n
7677            action: PLAY_TONE "tone name" duration in seconds ( Range 0.1 to 10.0 );\n
7678     @endproperty
7679 */
7680 static void
7681 st_collections_group_programs_program_action(void)
7682 {
7683    Edje_Part_Collection *pc;
7684    Edje_Program *ep;
7685    int i;
7686
7687    pc = eina_list_data_get(eina_list_last(edje_collections));
7688    ep = current_program;
7689    ep->action = parse_enum(0,
7690                            "STATE_SET", EDJE_ACTION_TYPE_STATE_SET,
7691                            "ACTION_STOP", EDJE_ACTION_TYPE_ACTION_STOP,
7692                            "SIGNAL_EMIT", EDJE_ACTION_TYPE_SIGNAL_EMIT,
7693                            "DRAG_VAL_SET", EDJE_ACTION_TYPE_DRAG_VAL_SET,
7694                            "DRAG_VAL_STEP", EDJE_ACTION_TYPE_DRAG_VAL_STEP,
7695                            "DRAG_VAL_PAGE", EDJE_ACTION_TYPE_DRAG_VAL_PAGE,
7696                            "SCRIPT", EDJE_ACTION_TYPE_SCRIPT,
7697                            "FOCUS_SET", EDJE_ACTION_TYPE_FOCUS_SET,
7698                            "FOCUS_OBJECT", EDJE_ACTION_TYPE_FOCUS_OBJECT,
7699                            "PARAM_COPY", EDJE_ACTION_TYPE_PARAM_COPY,
7700                            "PARAM_SET", EDJE_ACTION_TYPE_PARAM_SET,
7701                            "PLAY_SAMPLE", EDJE_ACTION_TYPE_SOUND_SAMPLE,
7702                            "PLAY_TONE", EDJE_ACTION_TYPE_SOUND_TONE,
7703                            NULL);
7704    if (ep->action == EDJE_ACTION_TYPE_STATE_SET)
7705      {
7706         ep->state = parse_str(1);
7707         if (get_arg_count() == 1)
7708           ep->value = 0.0;
7709         else
7710           ep->value = parse_float_range(2, 0.0, 1.0);
7711      }
7712    else if (ep->action == EDJE_ACTION_TYPE_SIGNAL_EMIT)
7713      {
7714         ep->state = parse_str(1);
7715         ep->state2 = parse_str(2);
7716      }
7717    else if (ep->action == EDJE_ACTION_TYPE_SOUND_SAMPLE)
7718      {
7719         ep->sample_name = parse_str(1);
7720         for (i = 0; i < (int)edje_file->sound_dir->samples_count; i++)
7721           {
7722              if (!strcmp(edje_file->sound_dir->samples[i].name, ep->sample_name))
7723                break;
7724              if (i == (int)(edje_file->sound_dir->samples_count - 1))
7725                {
7726                   ERR("No Sample name %s exist.", ep->sample_name);
7727                   exit(-1);
7728                }
7729           }
7730         ep->speed = parse_float_range(2, 0.0, 10.0);
7731      }
7732    else if (ep->action == EDJE_ACTION_TYPE_SOUND_TONE)
7733      {
7734         ep->tone_name = parse_str(1);
7735         for (i = 0; i < (int)edje_file->sound_dir->tones_count; i++)
7736           {
7737              if (!strcmp(edje_file->sound_dir->tones[i].name, ep->tone_name))
7738                break;
7739              if (i == (int)(edje_file->sound_dir->tones_count - 1))
7740                {
7741                   ERR("No Tone name %s exist.", ep->tone_name);
7742                   exit(-1);
7743                }
7744           }
7745         ep->duration = parse_float_range(2, 0.1, 10.0);
7746      }
7747    else if (ep->action == EDJE_ACTION_TYPE_DRAG_VAL_SET)
7748      {
7749         ep->value = parse_float(1);
7750         ep->value2 = parse_float(2);
7751      }
7752    else if (ep->action == EDJE_ACTION_TYPE_DRAG_VAL_STEP)
7753      {
7754         ep->value = parse_float(1);
7755         ep->value2 = parse_float(2);
7756      }
7757    else if (ep->action == EDJE_ACTION_TYPE_DRAG_VAL_PAGE)
7758      {
7759         ep->value = parse_float(1);
7760         ep->value2 = parse_float(2);
7761      }
7762    else if (ep->action == EDJE_ACTION_TYPE_PARAM_COPY)
7763      {
7764         char *src_part, *dst_part;
7765         
7766         src_part = parse_str(1);
7767         ep->state = parse_str(2);
7768         dst_part = parse_str(3);
7769         ep->state2 = parse_str(4);
7770         
7771         data_queue_part_lookup(pc, src_part, &(ep->param.src));
7772         data_queue_part_lookup(pc, dst_part, &(ep->param.dst));
7773         
7774         free(src_part);
7775         free(dst_part);
7776      }
7777    else if (ep->action == EDJE_ACTION_TYPE_PARAM_SET)
7778      {
7779         char *part;
7780         
7781         part = parse_str(1);
7782         ep->state = parse_str(2);
7783         ep->state2 = parse_str(3);
7784         
7785         data_queue_part_lookup(pc, part, &(ep->param.dst));
7786         free(part);
7787      }
7788    
7789    switch (ep->action)
7790      {
7791       case EDJE_ACTION_TYPE_ACTION_STOP:
7792         check_arg_count(1);
7793         break;
7794       case EDJE_ACTION_TYPE_SCRIPT:
7795         /* this is implicitly set by script {} so this is here just for
7796          * completeness */
7797         break;
7798       case EDJE_ACTION_TYPE_FOCUS_OBJECT:
7799       case EDJE_ACTION_TYPE_FOCUS_SET:
7800         check_arg_count(1);
7801         break;
7802       case EDJE_ACTION_TYPE_PARAM_COPY:
7803         check_arg_count(5);
7804         break;
7805       case EDJE_ACTION_TYPE_PARAM_SET:
7806         check_arg_count(4);
7807         break;
7808       case EDJE_ACTION_TYPE_SOUND_SAMPLE:
7809         check_arg_count(3);
7810         break;
7811       case EDJE_ACTION_TYPE_SOUND_TONE:
7812         check_arg_count(3);
7813         break;
7814       default:
7815         check_arg_count(3);
7816      }
7817 }
7818
7819 /**
7820     @page edcref
7821     @property
7822         transition
7823     @parameters
7824         [type] [length] [[interp val 1]] [[interp val 2]] [[option]]
7825     @effect
7826         Defines how transitions occur using STATE_SET action.\n
7827         Where 'type' is the style of the transition and 'length' is a double
7828         specifying the number of seconds in which to preform the transition.\n
7829         Valid types are: LIN or LINEAR, SIN or SINUSOIDAL, 
7830         ACCEL or ACCELERATE, DECEL or DECELERATE, 
7831         ACCEL_FAC or ACCELERATE_FACTOR, DECEL_FAC or DECELERATE_FACTOR,
7832         SIN_FAC or SINUSOIDAL_FACTOR, DIVIS or DIVISOR_INTERP,
7833         BOUNCE, SPRING.
7834         
7835         ACCEL_FAC, DECEL_FAC and SIN_FAC need the extra optional
7836         "interp val 1" to determine the "factor" of curviness. 1.0 is the same
7837         as their non-factor counterparts, where 0.0 is equal to linear.
7838         Numbers higher than one make the curve angles steeper with a more
7839         pronounced curve point.
7840         
7841         DIVIS, BOUNCE and SPRING also require "interp val 2" in addition
7842         to "interp val 1".
7843         
7844         DIVIS uses val 1 as the initial gradient start
7845         (0.0 is horizontal, 1.0 is diagonal (linear), 2.0 is twice the
7846         gradient of linear etc.). val 2 is interpreted as an integer factor
7847         defining how much the value swings "outside" the gradient only to come
7848         back to the final resting spot at the end. 0.0 for val 2 is equivalent
7849         to linear interpolation. Note that DIVIS can exceed 1.0
7850         
7851         BOUNCE uses val 2 as the number of bounces (so its rounded down to
7852         the nearest integer value), with val 1 determining how much the
7853         bounce decays, with 0.0 giving linear decay per bounce, and higher
7854         values giving much more decay.
7855
7856         SPRING is similar to bounce, where val 2 specifies the number of
7857         spring "swings" and val 1 specifies the decay, but it can exceed 1.0
7858         on the outer swings.
7859
7860         Valid option is CURRENT.
7861
7862         CURRENT is the option which causes the edje object to move from its current position.
7863         It can be used as the last parameter of any transition type. (@since 1.1.0)
7864
7865     @endproperty
7866 */
7867 static void
7868 st_collections_group_programs_program_transition(void)
7869 {
7870    check_min_arg_count(2);
7871
7872    current_program->tween.mode = parse_enum(0,
7873                                             // short names
7874                                             "LIN", EDJE_TWEEN_MODE_LINEAR,
7875                                             "SIN", EDJE_TWEEN_MODE_SINUSOIDAL,
7876                                             "ACCEL", EDJE_TWEEN_MODE_ACCELERATE,
7877                                             "DECEL", EDJE_TWEEN_MODE_DECELERATE,
7878                                             "ACCEL_FAC", EDJE_TWEEN_MODE_ACCELERATE_FACTOR,
7879                                             "DECEL_FAC", EDJE_TWEEN_MODE_DECELERATE_FACTOR,
7880                                             "SIN_FAC", EDJE_TWEEN_MODE_SINUSOIDAL_FACTOR,
7881                                             "DIVIS", EDJE_TWEEN_MODE_DIVISOR_INTERP,
7882                                             
7883                                             // long/full names
7884                                             "LINEAR", EDJE_TWEEN_MODE_LINEAR,
7885                                             "SINUSOIDAL", EDJE_TWEEN_MODE_SINUSOIDAL,
7886                                             "ACCELERATE", EDJE_TWEEN_MODE_ACCELERATE,
7887                                             "DECELERATE", EDJE_TWEEN_MODE_DECELERATE,
7888                                             "ACCELERATE_FACTOR", EDJE_TWEEN_MODE_ACCELERATE_FACTOR,
7889                                             "DECELERATE_FACTOR", EDJE_TWEEN_MODE_DECELERATE_FACTOR,
7890                                             "SINUSOIDAL_FACTOR", EDJE_TWEEN_MODE_SINUSOIDAL_FACTOR,
7891                                             "DIVISOR_INTERP", EDJE_TWEEN_MODE_DIVISOR_INTERP,
7892                                             
7893                                             // long/full is short enough
7894                                             "BOUNCE", EDJE_TWEEN_MODE_BOUNCE,
7895                                             "SPRING", EDJE_TWEEN_MODE_SPRING,
7896                                             NULL);
7897    current_program->tween.time = FROM_DOUBLE(parse_float_range(1, 0.0, 999999999.0));
7898    if ((current_program->tween.mode >= EDJE_TWEEN_MODE_LINEAR) &&
7899        (current_program->tween.mode <= EDJE_TWEEN_MODE_DECELERATE))
7900      {
7901         if ((get_arg_count() == 3) && (!strcmp(parse_str(2), "CURRENT")))
7902           current_program->tween.mode |= EDJE_TWEEN_MODE_OPT_FROM_CURRENT;
7903         else if (get_arg_count() != 2)
7904           {
7905              ERR("parse error %s:%i. Need 2rd parameter to set time",
7906                  file_in, line - 1);
7907              exit(-1);
7908           }
7909      }
7910    // the following need v1
7911    // EDJE_TWEEN_MODE_ACCELERATE_FACTOR
7912    // EDJE_TWEEN_MODE_DECELERATE_FACTOR
7913    // EDJE_TWEEN_MODE_SINUSOIDAL_FACTOR
7914    // current_program->tween.v1
7915    else if ((current_program->tween.mode >= EDJE_TWEEN_MODE_ACCELERATE_FACTOR) &&
7916        (current_program->tween.mode <= EDJE_TWEEN_MODE_SINUSOIDAL_FACTOR))
7917      {
7918         if ((get_arg_count() == 4) && (!strcmp(parse_str(3), "CURRENT")))
7919           current_program->tween.mode |= EDJE_TWEEN_MODE_OPT_FROM_CURRENT;
7920         else if (get_arg_count() != 3)
7921           {
7922              ERR("parse error %s:%i. Need 3rd parameter to set factor",
7923                  file_in, line - 1);
7924              exit(-1);
7925           }
7926         current_program->tween.v1 = FROM_DOUBLE(parse_float_range(2, 0.0, 999999999.0));
7927      }
7928    // the followjng also need v2
7929    // EDJE_TWEEN_MODE_DIVISOR_INTERP
7930    // EDJE_TWEEN_MODE_BOUNCE
7931    // EDJE_TWEEN_MODE_SPRING
7932    // current_program->tween.v2
7933    else if ((current_program->tween.mode >= EDJE_TWEEN_MODE_DIVISOR_INTERP) &&
7934             (current_program->tween.mode <= EDJE_TWEEN_MODE_SPRING))
7935      {
7936         if ((get_arg_count() == 5) && (!strcmp(parse_str(4), "CURRENT")))
7937           current_program->tween.mode |= EDJE_TWEEN_MODE_OPT_FROM_CURRENT;
7938         else if (get_arg_count() != 4)
7939           {
7940              ERR("parse error %s:%i. "
7941                  "Need 3rd and 4th parameters to set factor and counts",
7942                  file_in, line - 1);
7943              exit(-1);
7944           }
7945         current_program->tween.v1 = FROM_DOUBLE(parse_float_range(2, 0.0, 999999999.0));
7946         current_program->tween.v2 = FROM_DOUBLE(parse_float_range(3, 0.0, 999999999.0));
7947      }
7948 }
7949
7950 /**
7951     @page edcref
7952     @property
7953         target
7954     @parameters
7955         [target]
7956     @effect
7957         Program or part on which the specified action acts. Multiple target
7958         keywords may be specified, one per target. SIGNAL_EMITs do not have
7959         targets.
7960     @endproperty
7961 */
7962 static void
7963 st_collections_group_programs_program_target(void)
7964 {
7965    Edje_Part_Collection *pc;
7966    Edje_Program *ep;
7967
7968    check_arg_count(1);
7969
7970    pc = eina_list_data_get(eina_list_last(edje_collections));
7971    ep = current_program;
7972      {
7973         Edje_Program_Target *et;
7974         Edje_Program_Target *etw;
7975         Eina_List *l;
7976         char *name;
7977         char *copy;
7978
7979         name = parse_str(0);
7980         
7981         EINA_LIST_FOREACH(ep->targets, l, etw)
7982           {
7983              if (!strcmp(name, (char*) (etw + 1)))
7984                {
7985                   free(name);
7986                   return;
7987                }
7988           }
7989
7990         et = mem_alloc(SZ(Edje_Program_Target) + strlen(name) + 1);
7991         ep->targets = eina_list_append(ep->targets, et);
7992         copy = (char*) (et + 1);
7993
7994         memcpy(copy, name, strlen(name) + 1);
7995
7996         if (ep->action == EDJE_ACTION_TYPE_STATE_SET)
7997           data_queue_part_lookup(pc, name, &(et->id));
7998         else if (ep->action == EDJE_ACTION_TYPE_ACTION_STOP)
7999           data_queue_program_lookup(pc, name, &(et->id));
8000         else if (ep->action == EDJE_ACTION_TYPE_DRAG_VAL_SET)
8001           data_queue_part_lookup(pc, name, &(et->id));
8002         else if (ep->action == EDJE_ACTION_TYPE_DRAG_VAL_STEP)
8003           data_queue_part_lookup(pc, name, &(et->id));
8004         else if (ep->action == EDJE_ACTION_TYPE_DRAG_VAL_PAGE)
8005           data_queue_part_lookup(pc, name, &(et->id));
8006         else if (ep->action == EDJE_ACTION_TYPE_FOCUS_SET)
8007           data_queue_part_lookup(pc, name, &(et->id));
8008         else if (ep->action == EDJE_ACTION_TYPE_FOCUS_OBJECT)
8009           data_queue_part_lookup(pc, name, &(et->id));
8010         else
8011           {
8012              ERR("parse error %s:%i. target may only be used after action",
8013                  file_in, line - 1);
8014              exit(-1);
8015           }
8016         free(name);
8017      }
8018 }
8019
8020 /**
8021     @page edcref
8022     @property
8023         after
8024     @parameters
8025         [after]
8026     @effect
8027         Specifies a program to run after the current program completes. The
8028         source and signal parameters of a program run as an "after" are ignored.
8029         Multiple "after" statements can be specified per program.
8030     @endproperty
8031 */
8032 static void
8033 st_collections_group_programs_program_after(void)
8034 {
8035    Edje_Part_Collection *pc;
8036    Edje_Program *ep;
8037
8038    check_arg_count(1);
8039
8040    pc = eina_list_data_get(eina_list_last(edje_collections));
8041    ep = current_program;
8042      {
8043         Edje_Program_After *pa;
8044    Edje_Program_After *pa2;
8045    Eina_List *l;
8046         char *name;
8047    char *copy;
8048
8049         name = parse_str(0);
8050
8051    EINA_LIST_FOREACH(ep->after, l, pa2)
8052      {
8053         if (!strcmp(name, (char*) (pa2 + 1)))
8054           {
8055              free(name);
8056              return;
8057           }
8058      }
8059
8060    pa = mem_alloc(SZ(Edje_Program_After) + strlen(name) + 1);
8061         pa->id = -1;
8062         ep->after = eina_list_append(ep->after, pa);
8063    copy = (char*)(pa + 1);
8064
8065    memcpy(copy, name, strlen(name) + 1);
8066
8067         data_queue_program_lookup(pc, name, &(pa->id));
8068         free(name);
8069      }
8070 }
8071
8072 /**
8073     @page edcref
8074     @property
8075         api
8076     @parameters
8077         [name] [description]
8078     @effect
8079         Specifies a hint to let applications (or IDE's) know how to bind
8080         things. The parameter name should contain the name of the function that
8081         the application should use, and description describes how it should
8082         be used.
8083     @endproperty
8084 */
8085 static void
8086 st_collections_group_programs_program_api(void)
8087 {
8088    check_min_arg_count(1);
8089
8090    current_program->api.name = parse_str(0);
8091
8092    if (is_param(1))
8093      {
8094        check_arg_count(2);
8095        current_program->api.description = parse_str(1);
8096      }
8097 }
8098
8099 static void
8100 st_collections_group_parts_part_api(void)
8101 {
8102    check_min_arg_count(1);
8103
8104    current_part->api.name = parse_str(0);
8105    if (is_param(1))
8106      {
8107        check_arg_count(2);
8108        current_part->api.description = parse_str(1);
8109      }
8110 }
8111
8112 static void
8113 ob_collections_group_programs_program_script(void)
8114 {
8115    Edje_Part_Collection *pc;
8116    Code *cd;
8117
8118    pc = eina_list_data_get(eina_list_last(edje_collections));
8119    cd = eina_list_data_get(eina_list_last(codes));
8120
8121    if (!is_verbatim()) track_verbatim(1);
8122    else
8123      {
8124         Eina_Bool empty = EINA_TRUE;
8125         char *s;
8126         int i, len;
8127
8128         s = get_verbatim();
8129         if (s)
8130           {
8131              Code_Program *cp;
8132
8133              /* FIXME: Need to store the script somewhere to be restored when using edje_edit API */
8134              cp = mem_alloc(SZ(Code_Program));
8135              cp->l1 = get_verbatim_line1();
8136              cp->l2 = get_verbatim_line2();
8137              cp->script = s;
8138              cp->original = strdup(s);
8139              if (cd->shared && cd->is_lua)
8140                {
8141                   ERR("parse error %s:%i. You're trying to mix Embryo and Lua scripting in the same group",
8142                       file_in, line - 1);
8143                   exit(-1);
8144                }
8145              cd->is_lua = 0;
8146
8147              len = strlen(cp->script);
8148              for (i = 0; i < len; i++)
8149                {
8150                   if (((cp->script[i] > 'a') && (cp->script[i] < 'z')) ||
8151                       ((cp->script[i] > 'A') && (cp->script[i] < 'Z')) ||
8152                       ((cp->script[i] > '0') && (cp->script[i] < '9')))
8153                     empty = EINA_FALSE;
8154                }
8155
8156              if (!empty)
8157                {
8158                   cd->programs = eina_list_append(cd->programs, cp);
8159                   data_queue_anonymous_lookup(pc, current_program, &(cp->id));
8160                   current_program->action = EDJE_ACTION_TYPE_SCRIPT;
8161                }
8162              else
8163                {
8164                   data_queue_anonymous_lookup(pc, current_program, NULL);
8165                   free(cp);
8166                   cp = NULL;
8167                }
8168
8169              set_verbatim(NULL, 0, 0);
8170           }
8171      }
8172 }
8173 /**
8174     @page edcref
8175     </table>
8176 */
8177
8178 static void
8179 edje_cc_handlers_hierarchy_set(Edje_Part *src)
8180 {  /* This funcion makes current part rel_1.id, rel_2.id relative to src */
8181    if (!src->name)
8182      {
8183         ERR("parse error %s:%i. You must set parent name before creating nested part",
8184             file_in, line - 1);
8185         exit(-1);
8186      }
8187    st_collections_group_parts_part_description_rel1_to_set(src->name);
8188    st_collections_group_parts_part_description_rel2_to_set(src->name);
8189 }
8190
8191 static Edje_Part *
8192 edje_cc_handlers_hierarchy_parent_get(void)
8193 {  /* Return the parent part pointer */
8194    int idx = eina_array_count(part_hierarchy) - 2;
8195    Edje_Cc_Handlers_Hierarchy_Info *info = (idx >= 0) ?
8196       eina_array_data_get(part_hierarchy, idx) : NULL;
8197
8198    return (info) ? info->ep : NULL;
8199 }
8200
8201 static void
8202 edje_cc_handlers_hierarchy_push(Edje_Part *ep, Edje_Part *cp)
8203 {  /* Remove part from hierarchy stack when finished parsing it */
8204    Edje_Cc_Handlers_Hierarchy_Info *info = malloc(sizeof(*info));
8205    info->current_de = current_de;
8206    info->current_part = cp;  /* current_part restored on pop */
8207    info->current_item = current_item;
8208    info->current_desc = current_desc;
8209    info->parent_desc = parent_desc;
8210    info->current_program = current_program;
8211    info->ep = ep;
8212
8213    eina_array_push(part_hierarchy, info);
8214 }
8215
8216 static void
8217 edje_cc_handlers_hierarchy_rename(Edje_Part *old, Edje_Part *new)
8218 {
8219    Edje_Cc_Handlers_Hierarchy_Info *item;
8220    Eina_Array_Iterator iterator;
8221    unsigned int i;       
8222
8223    EINA_ARRAY_ITER_NEXT(part_hierarchy, i, item, iterator)
8224      {
8225         if (item->ep == old) item->ep = new;
8226         if (item->current_part == old) item->current_part = new;
8227      }
8228 }
8229
8230 void
8231 edje_cc_handlers_hierarchy_alloc(void)
8232 {
8233    part_hierarchy = eina_array_new(8);
8234 }
8235
8236 void
8237 edje_cc_handlers_hierarchy_free(void)
8238 {
8239    eina_array_free(part_hierarchy);
8240    part_hierarchy = NULL;
8241 }
8242
8243 static void
8244 edje_cc_handlers_hierarchy_pop(void)
8245 {  /* Remove part from hierarchy stack when finished parsing it */
8246    Edje_Cc_Handlers_Hierarchy_Info *info = eina_array_pop(part_hierarchy);
8247
8248    if (info)
8249      {
8250         current_de = info->current_de;
8251         current_part = info->current_part;
8252         current_item = info->current_item;
8253         current_desc = info->current_desc;
8254         parent_desc = info->parent_desc;
8255         current_program = info->current_program;
8256
8257         free(info);
8258      }
8259 }