Add:Core:Made cursor configurable via navit.xml
[navit-package] / navit / layout.c
1 /**
2  * Navit, a modular navigation system.
3  * Copyright (C) 2005-2008 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 struct layout * layout_new(struct attr *parent, struct attr **attrs)
29 {
30         struct layout *l;
31         struct color def_color = {0xffff, 0xefef, 0xb7b7, 0xffff};
32         struct attr *name_attr,*color_attr,*order_delta_attr,*font_attr;
33
34         if (! (name_attr=attr_search(attrs, NULL, attr_name)))
35                 return NULL;
36         l = g_new0(struct layout, 1);
37         l->name = g_strdup(name_attr->u.str);
38         if ((font_attr=attr_search(attrs, NULL, attr_font))) {
39                 l->font = g_strdup(font_attr->u.str);
40         }
41         if ((color_attr=attr_search(attrs, NULL, attr_color)))
42                 l->color = *color_attr->u.color;
43         else
44                 l->color = def_color;
45         if ((order_delta_attr=attr_search(attrs, NULL, attr_order_delta)))
46                 l->order_delta=order_delta_attr->u.num;
47         return l;
48 }
49
50 int
51 layout_add_attr(struct layout *layout, struct attr *attr)
52 {
53         switch (attr->type) {
54         case attr_layer:
55                 layout->layers = g_list_append(layout->layers, attr->u.layer);
56                 return 1;
57         default:
58                 return 0;
59         }
60 }
61
62
63
64 struct layer * layer_new(struct attr *parent, struct attr **attrs)
65 {
66         struct layer *l;
67
68         struct attr *name, *details;
69         l = g_new0(struct layer, 1);
70         name=attr_search(attrs, NULL, attr_name);
71         if (name)
72                 l->name = g_strdup(name->u.str);
73         details=attr_search(attrs, NULL, attr_details);
74         if (details)
75                 l->details = details->u.num;
76         return l;
77 }
78
79 int
80 layer_add_attr(struct layer *layer, struct attr *attr)
81 {
82         switch (attr->type) {
83         case attr_itemgra:
84                 layer->itemgras = g_list_append(layer->itemgras, attr->u.itemgra);
85                 return 1;
86         default:
87                 return 0;
88         }
89 }
90
91
92 struct itemgra * itemgra_new(struct attr *parent, struct attr **attrs)
93 {
94         struct itemgra *itm;
95         struct attr *order, *item_types, *speed_range, *angle_range, *sequence_range;
96         enum item_type *type;
97         struct range defrange;
98         
99         itm = g_new0(struct itemgra, 1);
100         order=attr_search(attrs, NULL, attr_order);
101         item_types=attr_search(attrs, NULL, attr_item_types);
102         speed_range=attr_search(attrs, NULL, attr_speed_range);
103         angle_range=attr_search(attrs, NULL, attr_angle_range);
104         sequence_range=attr_search(attrs, NULL, attr_sequence_range);
105         defrange.min=0;
106         defrange.max=32767;
107         if (order) 
108                 itm->order=order->u.range;
109         else 
110                 itm->order=defrange;
111         if (speed_range) 
112                 itm->speed_range=speed_range->u.range;
113         else 
114                 itm->speed_range=defrange;
115         if (angle_range) 
116                 itm->angle_range=angle_range->u.range;
117         else 
118                 itm->angle_range=defrange;
119         if (sequence_range) 
120                 itm->sequence_range=sequence_range->u.range;
121         else 
122                 itm->sequence_range=defrange;
123         if (item_types) {
124                 type=item_types->u.item_types;
125                 while (type && *type != type_none) {
126                         itm->type=g_list_append(itm->type, GINT_TO_POINTER(*type));
127                         type++;
128                 }
129         }
130         return itm;
131 }
132 int
133 itemgra_add_attr(struct itemgra *itemgra, struct attr *attr)
134 {
135         switch (attr->type) {
136         case attr_polygon:
137         case attr_polyline:
138         case attr_circle:
139         case attr_text:
140         case attr_icon:
141         case attr_image:
142         case attr_arrows:
143                 itemgra->elements = g_list_append(itemgra->elements, attr->u.element);
144                 return 1;
145         default:
146                 dbg(0,"unknown: %s\n", attr_to_name(attr->type));
147                 return 0;
148         }
149 }
150
151 static void
152 element_set_color(struct element *e, struct attr **attrs)
153 {
154         struct attr *color;
155         color=attr_search(attrs, NULL, attr_color);
156         if (color)
157                 e->color=*color->u.color;
158 }
159
160 static void
161 element_set_text_size(struct element *e, struct attr **attrs)
162 {
163         struct attr *text_size;
164         text_size=attr_search(attrs, NULL, attr_text_size);
165         if (text_size)
166                 e->text_size=text_size->u.num;
167 }
168
169 static void
170 element_set_polyline_width(struct element *e, struct attr **attrs)
171 {
172         struct attr *width;
173         width=attr_search(attrs, NULL, attr_width);
174         if (width)
175                 e->u.polyline.width=width->u.num;
176 }
177
178 static void
179 element_set_polyline_directed(struct element *e, struct attr **attrs)
180 {
181         struct attr *directed;
182         directed=attr_search(attrs, NULL, attr_directed);
183         if (directed)
184                 e->u.polyline.directed=directed->u.num;
185 }
186
187 static void
188 element_set_polyline_dash(struct element *e, struct attr **attrs)
189 {
190         struct attr *dash;
191         int i;
192
193         dash=attr_search(attrs, NULL, attr_dash);
194         if (dash) {
195                 for (i=0; i<4; i++) {
196                         if (!dash->u.dash[i])
197                                 break;
198                         e->u.polyline.dash_table[i] = dash->u.dash[i];
199                 }
200                 e->u.polyline.dash_num=i;
201         }
202 }
203
204 static void
205 element_set_polyline_offset(struct element *e, struct attr **attrs)
206 {
207         struct attr *offset;
208         offset=attr_search(attrs, NULL, attr_offset);
209         if (offset)
210                 e->u.polyline.offset=offset->u.num;
211 }
212
213 static void
214 element_set_circle_width(struct element *e, struct attr **attrs)
215 {
216         struct attr *width;
217         width=attr_search(attrs, NULL, attr_width);
218         if (width)
219                 e->u.circle.width=width->u.num;
220 }
221
222 static void
223 element_set_circle_radius(struct element *e, struct attr **attrs)
224 {
225         struct attr *radius;
226         radius=attr_search(attrs, NULL, attr_radius);
227         if (radius)
228                 e->u.circle.radius=radius->u.num;
229 }
230
231 struct polygon *
232 polygon_new(struct attr *parent, struct attr **attrs)
233 {
234         struct element *e;
235         e = g_new0(struct element, 1);
236         e->type=element_polygon;
237         element_set_color(e, attrs);
238
239         return (struct polygon *)e;
240 }
241
242 struct polyline *
243 polyline_new(struct attr *parent, struct attr **attrs)
244 {
245         struct element *e;
246         
247         e = g_new0(struct element, 1);
248         e->type=element_polyline;
249         element_set_color(e, attrs);
250         element_set_polyline_width(e, attrs);
251         element_set_polyline_directed(e, attrs);
252         element_set_polyline_dash(e, attrs);
253         element_set_polyline_offset(e, attrs);
254         return (struct polyline *)e;
255 }
256
257 struct circle *
258 circle_new(struct attr *parent, struct attr **attrs)
259 {
260         struct element *e;
261
262         e = g_new0(struct element, 1);
263         e->type=element_circle;
264         element_set_color(e, attrs);
265         element_set_text_size(e, attrs);
266         element_set_circle_width(e, attrs);
267         element_set_circle_radius(e, attrs);
268
269         return (struct circle *)e;
270 }
271
272 struct text *
273 text_new(struct attr *parent, struct attr **attrs)
274 {
275         struct element *e;
276         
277         e = g_new0(struct element, 1);
278         e->type=element_text;
279         element_set_text_size(e, attrs);
280
281         return (struct text *)e;
282 }
283
284 struct icon *
285 icon_new(struct attr *parent, struct attr **attrs)
286 {
287         struct element *e;
288         struct attr *src,*w,*h;
289         src=attr_search(attrs, NULL, attr_src);
290         if (! src)
291                 return NULL;
292
293         e = g_malloc0(sizeof(*e)+strlen(src->u.str)+1);
294         e->type=element_icon;
295         e->u.icon.src=(char *)(e+1);
296         if ((w=attr_search(attrs, NULL, attr_w)))
297                 e->u.icon.width=w->u.num;
298         else
299                 e->u.icon.width=-1;
300         if ((h=attr_search(attrs, NULL, attr_h)))
301                 e->u.icon.height=h->u.num;
302         else
303                 e->u.icon.height=-1;
304         strcpy(e->u.icon.src,src->u.str);
305
306         return (struct icon *)e;        
307 }
308
309 struct image *
310 image_new(struct attr *parent, struct attr **attrs)
311 {
312         struct element *e;
313
314         e = g_malloc0(sizeof(*e));
315         e->type=element_image;
316
317         return (struct image *)e;       
318 }
319
320 struct arrows *
321 arrows_new(struct attr *parent, struct attr **attrs)
322 {
323         struct element *e;
324         e = g_malloc0(sizeof(*e));
325         e->type=element_arrows;
326         element_set_color(e, attrs);
327         return (struct arrows *)e;      
328 }
329
330 int
331 element_add_attr(struct element *e, struct attr *attr)
332 {
333         switch (attr->type) {
334         case attr_coord:
335                 e->coord=g_realloc(e->coord,(e->coord_count+1)*sizeof(struct coord));
336                 e->coord[e->coord_count++]=*attr->u.coord;
337                 return 1;
338         default:
339                 return 0;
340         }
341 }