e470b8822f9f20c587964d7dbba31dce1e06ad03
[profile/ivi/navit.git] / navit / 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 = {COLOR_BACKGROUND_};
33         struct attr *name_attr,*color_attr,*order_delta_attr,*font_attr,*day_attr,*night_attr,*active_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 ((day_attr=attr_search(attrs, NULL, attr_daylayout))) {
43                 l->dayname = g_strdup(day_attr->u.str);
44         }
45         if ((night_attr=attr_search(attrs, NULL, attr_nightlayout))) {
46                 l->nightname = g_strdup(night_attr->u.str);
47         }
48         if ((color_attr=attr_search(attrs, NULL, attr_color)))
49                 l->color = *color_attr->u.color;
50         else
51                 l->color = def_color;
52         if ((order_delta_attr=attr_search(attrs, NULL, attr_order_delta)))
53                 l->order_delta=order_delta_attr->u.num;
54         if ((active_attr=attr_search(attrs, NULL, attr_active)))
55                 l->active = active_attr->u.num;
56         return l;
57 }
58
59 struct attr_iter {
60         GList *last;
61 };
62
63
64 struct attr_iter *
65 layout_attr_iter_new(void)
66 {
67         return g_new0(struct attr_iter, 1);
68 }
69
70 void
71 layout_attr_iter_destroy(struct attr_iter *iter)
72 {
73         g_free(iter);
74 }
75
76 int
77 layout_get_attr(struct layout *layout, enum attr_type type, struct attr *attr, struct attr_iter *iter)
78 {
79         GList *cursor,*layer;
80         attr->type=type;
81         switch (type) {
82         case attr_cursor:
83                 cursor=layout->cursors;
84                 while (cursor) {
85                         if (!iter || iter->last == g_list_previous(cursor)) {
86                                 attr->u.cursor=cursor->data;
87                                 if (iter)
88                                         iter->last=cursor;
89                                 return 1;
90                         }
91                         cursor=g_list_next(cursor);
92                 }
93                 break;
94         case attr_layer:
95                 layer=layout->layers;
96                 while (layer) {
97                         if (!iter || iter->last == g_list_previous(layer)) {
98                                 attr->u.layer=layer->data;
99                                 if (iter)
100                                         iter->last=layer;
101                                 return 1;
102                         }
103                         layer=g_list_next(layer);
104                 }
105                 break;
106         case attr_active:
107                 attr->u.num=layout->active;
108                 break;
109         default:
110                 break;
111         }
112         return 0;
113 }
114
115
116 int
117 layout_add_attr(struct layout *layout, struct attr *attr)
118 {
119         switch (attr->type) {
120         case attr_cursor:
121                 layout->cursors = g_list_append(layout->cursors, attr->u.cursor);
122                 return 1;
123         case attr_layer:
124                 layout->layers = g_list_append(layout->layers, attr->u.layer);
125                 return 1;
126         default:
127                 return 0;
128         }
129 }
130
131 /**
132  * Searchs the layout for a cursor with the given name.
133  *
134  * @param layout The layout
135  * @param name The name
136  * @returns A pointer to cursor with the given name or the name default or NULL.
137  * @author Ralph Sennhauser (10/2009)
138 */
139 struct cursor *
140 layout_get_cursor(struct layout *this_, char *name)
141 {
142         GList *c;
143         struct cursor *d=NULL;
144
145         c=g_list_first(this_->cursors);
146         while (c) {
147                 if (! strcmp(((struct cursor *)c->data)->name, name))
148                         return c->data;
149                 if (! strcmp(((struct cursor *)c->data)->name, "default"))
150                         d=c->data;
151                 c=g_list_next(c);
152         }
153         return d;
154 }
155
156
157
158 struct cursor *
159 cursor_new(struct attr *parent, struct attr **attrs)
160 {
161         struct attr *w, *h, *name, *interval, *sequence_range;
162         struct cursor *this;
163
164         w=attr_search(attrs, NULL, attr_w);
165         h=attr_search(attrs, NULL, attr_h);
166         if (! w || ! h)
167                 return NULL;
168
169         this=g_new0(struct cursor,1);
170         this->w=w->u.num;
171         this->h=h->u.num;
172         name=attr_search(attrs, NULL, attr_name);
173         if (name)
174                 this->name=g_strdup(name->u.str);
175         else
176                 this->name=g_strdup("default");
177         interval=attr_search(attrs, NULL, attr_interval);
178         if (interval)
179                 this->interval=interval->u.num;
180         sequence_range=attr_search(attrs, NULL, attr_sequence_range);
181         if (sequence_range) {
182                 struct range *r=g_new0(struct range,1);
183                 r->min=sequence_range->u.range.min;
184                 r->max=sequence_range->u.range.max;
185                 this->sequence_range=r;
186         }
187         else {
188                 this->sequence_range=NULL;
189         }
190         dbg(2,"ret=%p\n", this);
191         return this;
192 }
193
194 void
195 cursor_destroy(struct cursor *this_)
196 {
197         if (this_->sequence_range)
198                 g_free(this_->sequence_range);
199         if (this_->name) {
200                 g_free(this_->name);
201         }
202         g_free(this_);
203 }
204
205 int
206 cursor_add_attr(struct cursor *this_, struct attr *attr)
207 {
208         switch (attr->type) {
209         case attr_itemgra:
210                 this_->attrs=attr_generic_add_attr(this_->attrs, attr);
211                 return 1;
212         default:
213                 break;
214         }
215         return 0;
216 }
217
218 static int
219 layer_set_attr_do(struct layer *l, struct attr *attr, int init)
220 {
221         switch (attr->type) {
222         case attr_active:
223                 l->active = attr->u.num;
224                 return 1;
225         case attr_details:
226                 l->details = attr->u.num;
227                 return 1;
228         case attr_name:
229                 g_free(l->name);
230                 l->name = g_strdup(attr->u.str);
231                 return 1;
232         default:
233                 return 0;
234         }
235 }
236
237
238
239 struct layer * layer_new(struct attr *parent, struct attr **attrs)
240 {
241         struct layer *l;
242
243         l = g_new0(struct layer, 1);
244         l->active=1;
245         for (;*attrs; attrs++) {
246                 layer_set_attr_do(l, *attrs, 1);
247         }
248         return l;
249 }
250
251 int
252 layer_get_attr(struct layer *layer, enum attr_type type, struct attr *attr, struct attr_iter *iter)
253 {
254         attr->type=type;
255         switch(type) {
256         case attr_active:
257                 attr->u.num=layer->active;
258                 return 1;
259         case attr_details:
260                 attr->u.num=layer->details;
261                 return 1;
262         case attr_name:
263                 if (layer->name) {
264                         attr->u.str=layer->name;
265                         return 1;
266                 }
267                 break;
268         default:
269                 return 0;
270         }
271         return 0;
272 }
273
274 int
275 layer_add_attr(struct layer *layer, struct attr *attr)
276 {
277         switch (attr->type) {
278         case attr_itemgra:
279                 layer->itemgras = g_list_append(layer->itemgras, attr->u.itemgra);
280                 return 1;
281         default:
282                 return 0;
283         }
284 }
285
286 int
287 layer_set_attr(struct layer *layer, struct attr *attr)
288 {
289         return layer_set_attr_do(layer, attr, 0);
290 }
291
292 struct itemgra * itemgra_new(struct attr *parent, struct attr **attrs)
293 {
294         struct itemgra *itm;
295         struct attr *order, *item_types, *speed_range, *angle_range, *sequence_range;
296         enum item_type *type;
297         struct range defrange;
298         
299         itm = g_new0(struct itemgra, 1);
300         order=attr_search(attrs, NULL, attr_order);
301         item_types=attr_search(attrs, NULL, attr_item_types);
302         speed_range=attr_search(attrs, NULL, attr_speed_range);
303         angle_range=attr_search(attrs, NULL, attr_angle_range);
304         sequence_range=attr_search(attrs, NULL, attr_sequence_range);
305         defrange.min=0;
306         defrange.max=32767;
307         if (order) 
308                 itm->order=order->u.range;
309         else 
310                 itm->order=defrange;
311         if (speed_range) 
312                 itm->speed_range=speed_range->u.range;
313         else 
314                 itm->speed_range=defrange;
315         if (angle_range) 
316                 itm->angle_range=angle_range->u.range;
317         else 
318                 itm->angle_range=defrange;
319         if (sequence_range) 
320                 itm->sequence_range=sequence_range->u.range;
321         else 
322                 itm->sequence_range=defrange;
323         if (item_types) {
324                 type=item_types->u.item_types;
325                 while (type && *type != type_none) {
326                         itm->type=g_list_append(itm->type, GINT_TO_POINTER(*type));
327                         type++;
328                 }
329         }
330         return itm;
331 }
332 int
333 itemgra_add_attr(struct itemgra *itemgra, struct attr *attr)
334 {
335         switch (attr->type) {
336         case attr_polygon:
337         case attr_polyline:
338         case attr_circle:
339         case attr_text:
340         case attr_icon:
341         case attr_image:
342         case attr_arrows:
343                 itemgra->elements = g_list_append(itemgra->elements, attr->u.element);
344                 return 1;
345         default:
346                 dbg(0,"unknown: %s\n", attr_to_name(attr->type));
347                 return 0;
348         }
349 }
350
351 static void
352 element_set_color(struct element *e, struct attr **attrs)
353 {
354         struct attr *color;
355         color=attr_search(attrs, NULL, attr_color);
356         if (color)
357                 e->color=*color->u.color;
358 }
359
360
361 static void
362 element_set_background_color(struct color *c, struct attr **attrs)
363 {
364         struct attr *color;
365         color=attr_search(attrs, NULL, attr_background_color);
366         if (color)
367                 *c=*color->u.color;
368 }
369
370
371 static void
372 element_set_text_size(struct element *e, struct attr **attrs)
373 {
374         struct attr *text_size;
375         text_size=attr_search(attrs, NULL, attr_text_size);
376         if (text_size)
377                 e->text_size=text_size->u.num;
378 }
379
380 static void
381 element_set_polyline_width(struct element *e, struct attr **attrs)
382 {
383         struct attr *width;
384         width=attr_search(attrs, NULL, attr_width);
385         if (width)
386                 e->u.polyline.width=width->u.num;
387 }
388
389 static void
390 element_set_polyline_directed(struct element *e, struct attr **attrs)
391 {
392         struct attr *directed;
393         directed=attr_search(attrs, NULL, attr_directed);
394         if (directed)
395                 e->u.polyline.directed=directed->u.num;
396 }
397
398 static void
399 element_set_polyline_dash(struct element *e, struct attr **attrs)
400 {
401         struct attr *dash;
402         int i;
403
404         dash=attr_search(attrs, NULL, attr_dash);
405         if (dash) {
406                 for (i=0; i<4; i++) {
407                         if (!dash->u.dash[i])
408                                 break;
409                         e->u.polyline.dash_table[i] = dash->u.dash[i];
410                 }
411                 e->u.polyline.dash_num=i;
412         }
413 }
414
415 static void
416 element_set_polyline_offset(struct element *e, struct attr **attrs)
417 {
418         struct attr *offset;
419         offset=attr_search(attrs, NULL, attr_offset);
420         if (offset)
421                 e->u.polyline.offset=offset->u.num;
422 }
423
424 static void
425 element_set_circle_width(struct element *e, struct attr **attrs)
426 {
427         struct attr *width;
428         width=attr_search(attrs, NULL, attr_width);
429         if (width)
430                 e->u.circle.width=width->u.num;
431 }
432
433 static void
434 element_set_circle_radius(struct element *e, struct attr **attrs)
435 {
436         struct attr *radius;
437         radius=attr_search(attrs, NULL, attr_radius);
438         if (radius)
439                 e->u.circle.radius=radius->u.num;
440 }
441
442 struct polygon *
443 polygon_new(struct attr *parent, struct attr **attrs)
444 {
445         struct element *e;
446         e = g_new0(struct element, 1);
447         e->type=element_polygon;
448         element_set_color(e, attrs);
449
450         return (struct polygon *)e;
451 }
452
453 struct polyline *
454 polyline_new(struct attr *parent, struct attr **attrs)
455 {
456         struct element *e;
457         
458         e = g_new0(struct element, 1);
459         e->type=element_polyline;
460         element_set_color(e, attrs);
461         element_set_polyline_width(e, attrs);
462         element_set_polyline_directed(e, attrs);
463         element_set_polyline_dash(e, attrs);
464         element_set_polyline_offset(e, attrs);
465         return (struct polyline *)e;
466 }
467
468 struct circle *
469 circle_new(struct attr *parent, struct attr **attrs)
470 {
471         struct element *e;
472         struct color color_black = {COLOR_BLACK_};
473         struct color color_white = {COLOR_WHITE_};
474
475         e = g_new0(struct element, 1);
476         e->type=element_circle;
477         e->color = color_black;
478         e->u.circle.background_color = color_white;
479         element_set_color(e, attrs);
480         element_set_background_color(&e->u.circle.background_color, attrs);
481         element_set_text_size(e, attrs);
482         element_set_circle_width(e, attrs);
483         element_set_circle_radius(e, attrs);
484
485         return (struct circle *)e;
486 }
487
488 struct text *
489 text_new(struct attr *parent, struct attr **attrs)
490 {
491         struct element *e;
492         struct color color_black = {COLOR_BLACK_};
493         struct color color_white = {COLOR_WHITE_};
494         
495         e = g_new0(struct element, 1);
496         e->type=element_text;
497         element_set_text_size(e, attrs);
498         e->color = color_black;
499         e->u.text.background_color = color_white;
500         element_set_color(e, attrs);
501         element_set_background_color(&e->u.text.background_color, attrs);
502
503         return (struct text *)e;
504 }
505
506 struct icon *
507 icon_new(struct attr *parent, struct attr **attrs)
508 {
509         struct element *e;
510         struct attr *src,*w,*h,*rotation;
511         src=attr_search(attrs, NULL, attr_src);
512         if (! src)
513                 return NULL;
514
515         e = g_malloc0(sizeof(*e)+strlen(src->u.str)+1);
516         e->type=element_icon;
517         e->u.icon.src=(char *)(e+1);
518         if ((w=attr_search(attrs, NULL, attr_w)))
519                 e->u.icon.width=w->u.num;
520         else
521                 e->u.icon.width=-1;
522         if ((h=attr_search(attrs, NULL, attr_h)))
523                 e->u.icon.height=h->u.num;
524         else
525                 e->u.icon.height=-1;
526         if ((rotation=attr_search(attrs, NULL, attr_rotation)))
527                 e->u.icon.rotation=rotation->u.num;
528         strcpy(e->u.icon.src,src->u.str);
529
530         return (struct icon *)e;        
531 }
532
533 struct image *
534 image_new(struct attr *parent, struct attr **attrs)
535 {
536         struct element *e;
537
538         e = g_malloc0(sizeof(*e));
539         e->type=element_image;
540
541         return (struct image *)e;       
542 }
543
544 struct arrows *
545 arrows_new(struct attr *parent, struct attr **attrs)
546 {
547         struct element *e;
548         e = g_malloc0(sizeof(*e));
549         e->type=element_arrows;
550         element_set_color(e, attrs);
551         return (struct arrows *)e;      
552 }
553
554 int
555 element_add_attr(struct element *e, struct attr *attr)
556 {
557         switch (attr->type) {
558         case attr_coord:
559                 e->coord=g_realloc(e->coord,(e->coord_count+1)*sizeof(struct coord));
560                 e->coord[e->coord_count++]=*attr->u.coord;
561                 return 1;
562         default:
563                 return 0;
564         }
565 }