Add:Core:Add the possibility to define cursors in layout
[navit-package] / navit / layout.c
1 /**
2  * Navit, a modular navigation system.
3  * Copyright (C) 2005-2009 Navit Team
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * version 2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19
20 #include <glib.h>
21 #include <string.h>
22 #include "item.h"
23 #include "attr.h"
24 #include "layout.h"
25 #include "coord.h"
26 #include "debug.h"
27
28
29 struct layout * layout_new(struct attr *parent, struct attr **attrs)
30 {
31         struct layout *l;
32         struct color def_color = {0xffff, 0xefef, 0xb7b7, 0xffff};
33         struct attr *name_attr,*color_attr,*order_delta_attr,*font_attr;
34
35         if (! (name_attr=attr_search(attrs, NULL, attr_name)))
36                 return NULL;
37         l = g_new0(struct layout, 1);
38         l->name = g_strdup(name_attr->u.str);
39         if ((font_attr=attr_search(attrs, NULL, attr_font))) {
40                 l->font = g_strdup(font_attr->u.str);
41         }
42         if ((color_attr=attr_search(attrs, NULL, attr_color)))
43                 l->color = *color_attr->u.color;
44         else
45                 l->color = def_color;
46         if ((order_delta_attr=attr_search(attrs, NULL, attr_order_delta)))
47                 l->order_delta=order_delta_attr->u.num;
48         return l;
49 }
50
51 int
52 layout_add_attr(struct layout *layout, struct attr *attr)
53 {
54         switch (attr->type) {
55         case attr_cursor:
56                 layout->cursors = g_list_append(layout->cursors, attr->u.cursor);
57                 return 1;
58         case attr_layer:
59                 layout->layers = g_list_append(layout->layers, attr->u.layer);
60                 return 1;
61         default:
62                 return 0;
63         }
64 }
65
66 /**
67  * Searchs the layout for a cursor with the given name.
68  *
69  * @param layout The layout
70  * @param name The name
71  * @returns A pointer to cursor with the given name or the name default or NULL.
72  * @author Ralph Sennhauser (10/2009)
73 */
74 struct cursor *
75 layout_get_cursor(struct layout *this_, char *name)
76 {
77         GList *c;
78         struct cursor *d=NULL;
79
80         c=g_list_first(this_->cursors);
81         while (c) {
82                 if (! strcmp(((struct cursor *)c->data)->name, name))
83                         return c->data;
84                 if (! strcmp(((struct cursor *)c->data)->name, "default"))
85                         d=c->data;
86                 c=g_list_next(c);
87         }
88         return d;
89 }
90
91
92
93 struct cursor *
94 cursor_new(struct attr *parent, struct attr **attrs)
95 {
96         struct attr *w, *h, *name, *interval, *sequence_range;
97
98         w=attr_search(attrs, NULL, attr_w);
99         h=attr_search(attrs, NULL, attr_h);
100         if (! w || ! h)
101                 return NULL;
102
103         struct cursor *this=g_new0(struct cursor,1);
104         this->w=w->u.num;
105         this->h=h->u.num;
106         name=attr_search(attrs, NULL, attr_name);
107         if (name)
108                 this->name=g_strdup(name->u.str);
109         else
110                 this->name=g_strdup("default");
111         interval=attr_search(attrs, NULL, attr_interval);
112         if (interval)
113                 this->interval=interval->u.num;
114         sequence_range=attr_search(attrs, NULL, attr_sequence_range);
115         if (sequence_range) {
116                 struct range *r=g_new0(struct range,1);
117                 r->min=sequence_range->u.range.min;
118                 r->max=sequence_range->u.range.max;
119                 this->sequence_range=r;
120         }
121         else {
122                 this->sequence_range=NULL;
123         }
124         dbg(2,"ret=%p\n", this);
125         return this;
126 }
127
128 void
129 cursor_destroy(struct cursor *this_)
130 {
131         if (this_->sequence_range)
132                 g_free(this_->sequence_range);
133         if (this_->name) {
134                 g_free(this_->name);
135         }
136         g_free(this_);
137 }
138
139 int
140 cursor_add_attr(struct cursor *this_, struct attr *attr)
141 {
142         switch (attr->type) {
143         case attr_itemgra:
144                 this_->attrs=attr_generic_add_attr(this_->attrs, attr);
145                 return 1;
146         default:
147                 break;
148         }
149         return 0;
150 }
151
152
153
154 struct layer * layer_new(struct attr *parent, struct attr **attrs)
155 {
156         struct layer *l;
157
158         struct attr *name, *details;
159         l = g_new0(struct layer, 1);
160         name=attr_search(attrs, NULL, attr_name);
161         if (name)
162                 l->name = g_strdup(name->u.str);
163         details=attr_search(attrs, NULL, attr_details);
164         if (details)
165                 l->details = details->u.num;
166         return l;
167 }
168
169 int
170 layer_add_attr(struct layer *layer, struct attr *attr)
171 {
172         switch (attr->type) {
173         case attr_itemgra:
174                 layer->itemgras = g_list_append(layer->itemgras, attr->u.itemgra);
175                 return 1;
176         default:
177                 return 0;
178         }
179 }
180
181
182 struct itemgra * itemgra_new(struct attr *parent, struct attr **attrs)
183 {
184         struct itemgra *itm;
185         struct attr *order, *item_types, *speed_range, *angle_range, *sequence_range;
186         enum item_type *type;
187         struct range defrange;
188         
189         itm = g_new0(struct itemgra, 1);
190         order=attr_search(attrs, NULL, attr_order);
191         item_types=attr_search(attrs, NULL, attr_item_types);
192         speed_range=attr_search(attrs, NULL, attr_speed_range);
193         angle_range=attr_search(attrs, NULL, attr_angle_range);
194         sequence_range=attr_search(attrs, NULL, attr_sequence_range);
195         defrange.min=0;
196         defrange.max=32767;
197         if (order) 
198                 itm->order=order->u.range;
199         else 
200                 itm->order=defrange;
201         if (speed_range) 
202                 itm->speed_range=speed_range->u.range;
203         else 
204                 itm->speed_range=defrange;
205         if (angle_range) 
206                 itm->angle_range=angle_range->u.range;
207         else 
208                 itm->angle_range=defrange;
209         if (sequence_range) 
210                 itm->sequence_range=sequence_range->u.range;
211         else 
212                 itm->sequence_range=defrange;
213         if (item_types) {
214                 type=item_types->u.item_types;
215                 while (type && *type != type_none) {
216                         itm->type=g_list_append(itm->type, GINT_TO_POINTER(*type));
217                         type++;
218                 }
219         }
220         return itm;
221 }
222 int
223 itemgra_add_attr(struct itemgra *itemgra, struct attr *attr)
224 {
225         switch (attr->type) {
226         case attr_polygon:
227         case attr_polyline:
228         case attr_circle:
229         case attr_text:
230         case attr_icon:
231         case attr_image:
232         case attr_arrows:
233                 itemgra->elements = g_list_append(itemgra->elements, attr->u.element);
234                 return 1;
235         default:
236                 dbg(0,"unknown: %s\n", attr_to_name(attr->type));
237                 return 0;
238         }
239 }
240
241 static void
242 element_set_color(struct element *e, struct attr **attrs)
243 {
244         struct attr *color;
245         color=attr_search(attrs, NULL, attr_color);
246         if (color)
247                 e->color=*color->u.color;
248 }
249
250 static void
251 element_set_text_size(struct element *e, struct attr **attrs)
252 {
253         struct attr *text_size;
254         text_size=attr_search(attrs, NULL, attr_text_size);
255         if (text_size)
256                 e->text_size=text_size->u.num;
257 }
258
259 static void
260 element_set_polyline_width(struct element *e, struct attr **attrs)
261 {
262         struct attr *width;
263         width=attr_search(attrs, NULL, attr_width);
264         if (width)
265                 e->u.polyline.width=width->u.num;
266 }
267
268 static void
269 element_set_polyline_directed(struct element *e, struct attr **attrs)
270 {
271         struct attr *directed;
272         directed=attr_search(attrs, NULL, attr_directed);
273         if (directed)
274                 e->u.polyline.directed=directed->u.num;
275 }
276
277 static void
278 element_set_polyline_dash(struct element *e, struct attr **attrs)
279 {
280         struct attr *dash;
281         int i;
282
283         dash=attr_search(attrs, NULL, attr_dash);
284         if (dash) {
285                 for (i=0; i<4; i++) {
286                         if (!dash->u.dash[i])
287                                 break;
288                         e->u.polyline.dash_table[i] = dash->u.dash[i];
289                 }
290                 e->u.polyline.dash_num=i;
291         }
292 }
293
294 static void
295 element_set_polyline_offset(struct element *e, struct attr **attrs)
296 {
297         struct attr *offset;
298         offset=attr_search(attrs, NULL, attr_offset);
299         if (offset)
300                 e->u.polyline.offset=offset->u.num;
301 }
302
303 static void
304 element_set_circle_width(struct element *e, struct attr **attrs)
305 {
306         struct attr *width;
307         width=attr_search(attrs, NULL, attr_width);
308         if (width)
309                 e->u.circle.width=width->u.num;
310 }
311
312 static void
313 element_set_circle_radius(struct element *e, struct attr **attrs)
314 {
315         struct attr *radius;
316         radius=attr_search(attrs, NULL, attr_radius);
317         if (radius)
318                 e->u.circle.radius=radius->u.num;
319 }
320
321 struct polygon *
322 polygon_new(struct attr *parent, struct attr **attrs)
323 {
324         struct element *e;
325         e = g_new0(struct element, 1);
326         e->type=element_polygon;
327         element_set_color(e, attrs);
328
329         return (struct polygon *)e;
330 }
331
332 struct polyline *
333 polyline_new(struct attr *parent, struct attr **attrs)
334 {
335         struct element *e;
336         
337         e = g_new0(struct element, 1);
338         e->type=element_polyline;
339         element_set_color(e, attrs);
340         element_set_polyline_width(e, attrs);
341         element_set_polyline_directed(e, attrs);
342         element_set_polyline_dash(e, attrs);
343         element_set_polyline_offset(e, attrs);
344         return (struct polyline *)e;
345 }
346
347 struct circle *
348 circle_new(struct attr *parent, struct attr **attrs)
349 {
350         struct element *e;
351
352         e = g_new0(struct element, 1);
353         e->type=element_circle;
354         element_set_color(e, attrs);
355         element_set_text_size(e, attrs);
356         element_set_circle_width(e, attrs);
357         element_set_circle_radius(e, attrs);
358
359         return (struct circle *)e;
360 }
361
362 struct text *
363 text_new(struct attr *parent, struct attr **attrs)
364 {
365         struct element *e;
366         
367         e = g_new0(struct element, 1);
368         e->type=element_text;
369         element_set_text_size(e, attrs);
370
371         return (struct text *)e;
372 }
373
374 struct icon *
375 icon_new(struct attr *parent, struct attr **attrs)
376 {
377         struct element *e;
378         struct attr *src,*w,*h,*rotation;
379         src=attr_search(attrs, NULL, attr_src);
380         if (! src)
381                 return NULL;
382
383         e = g_malloc0(sizeof(*e)+strlen(src->u.str)+1);
384         e->type=element_icon;
385         e->u.icon.src=(char *)(e+1);
386         if ((w=attr_search(attrs, NULL, attr_w)))
387                 e->u.icon.width=w->u.num;
388         else
389                 e->u.icon.width=-1;
390         if ((h=attr_search(attrs, NULL, attr_h)))
391                 e->u.icon.height=h->u.num;
392         else
393                 e->u.icon.height=-1;
394         if ((rotation=attr_search(attrs, NULL, attr_rotation)))
395                 e->u.icon.rotation=rotation->u.num;
396         strcpy(e->u.icon.src,src->u.str);
397
398         return (struct icon *)e;        
399 }
400
401 struct image *
402 image_new(struct attr *parent, struct attr **attrs)
403 {
404         struct element *e;
405
406         e = g_malloc0(sizeof(*e));
407         e->type=element_image;
408
409         return (struct image *)e;       
410 }
411
412 struct arrows *
413 arrows_new(struct attr *parent, struct attr **attrs)
414 {
415         struct element *e;
416         e = g_malloc0(sizeof(*e));
417         e->type=element_arrows;
418         element_set_color(e, attrs);
419         return (struct arrows *)e;      
420 }
421
422 int
423 element_add_attr(struct element *e, struct attr *attr)
424 {
425         switch (attr->type) {
426         case attr_coord:
427                 e->coord=g_realloc(e->coord,(e->coord_count+1)*sizeof(struct coord));
428                 e->coord[e->coord_count++]=*attr->u.coord;
429                 return 1;
430         default:
431                 return 0;
432         }
433 }