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