Fix:maptool:Another name for faroe islands
[navit-package] / navit / osd.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 "debug.h"
22 #include "plugin.h"
23 #include "item.h"
24 #include "color.h"
25 #include "point.h"
26 #include "navit.h"
27 #include "graphics.h"
28 #include "command.h"
29 #include "callback.h"
30 #include "osd.h"
31
32
33 struct osd {
34         struct osd_methods meth;
35         struct osd_priv *priv;
36 };
37
38 struct osd *
39 osd_new(struct attr *parent, struct attr **attrs)
40 {
41         struct osd *o;
42         struct osd_priv *(*new)(struct navit *nav, struct osd_methods *meth, struct attr **attrs);
43         struct attr *type=attr_search(attrs, NULL, attr_type);
44
45         if (! type)
46                 return NULL;
47         new=plugin_get_osd_type(type->u.str);
48         if (! new)
49                 return NULL;
50         o=g_new0(struct osd, 1);
51         o->priv=new(parent->u.navit, &o->meth, attrs);
52         return o;
53 }
54
55 void
56 osd_wrap_point(struct point *p, struct navit *nav)
57 {
58         if (p->x < 0)
59                 p->x += navit_get_width(nav);
60         if (p->y < 0)
61                 p->y += navit_get_height(nav);
62
63 }
64
65 void
66 osd_std_click(struct osd_item *this, struct navit *nav, int pressed, int button, struct point *p)
67 {
68         struct point bp = this->p;
69         osd_wrap_point(&bp, nav);
70         if ((p->x < bp.x || p->y < bp.y || p->x > bp.x + this->w || p->y > bp.y + this->h || !this->configured) && !this->pressed)
71                 return;
72         if (button != 1)
73                 return;
74         if (!!pressed == !!this->pressed)
75                 return;
76         if (navit_ignore_button(nav))
77                 return;
78         this->pressed = pressed;
79         if (pressed && this->command) {
80                 struct attr navit;
81                 navit.type=attr_navit;
82                 navit.u.navit=nav;
83                 dbg(0, "calling command '%s'\n", this->command);
84                 command_evaluate(&navit, this->command);
85         }
86 }
87
88 void
89 osd_std_resize(struct osd_item *item)
90 {
91         graphics_overlay_resize(item->gr, &item->p, item->w, item->h, 65535, 1);
92 }
93  
94 static void
95 osd_std_calculate_sizes(struct osd_item *item, struct osd_priv *priv, int w, int h) 
96 {
97         struct attr vehicle_attr;
98
99         if (item->rel_w) {
100                 item->w = (item->rel_w * w) / 100;
101         }
102  
103         if (item->rel_h) {
104                 item->h = (item->rel_h * h) / 100;
105         }
106  
107         if (item->rel_x) {
108                 item->p.x = (item->rel_x * w) / 100;
109         }
110  
111         if (item->rel_y) {
112                 item->p.y = (item->rel_y * h) / 100;
113         }
114
115         osd_std_resize(item);
116         if (item->meth.draw) {
117                 if (navit_get_attr(item->navit, attr_vehicle, &vehicle_attr, NULL)) {
118                         item->meth.draw(priv, item->navit, vehicle_attr.u.vehicle);
119                 }
120         }
121 }
122
123 static void
124 osd_std_reconfigure(struct osd_item *item, struct command_saved *cs)
125 {
126         if (!command_saved_error(cs)) {
127                 graphics_overlay_disable(item->gr, !command_saved_get_int(cs));
128         } else {
129                 dbg(0, "Error in saved command: %i\n", command_saved_error(cs));
130         }
131 }
132
133 void
134 osd_set_std_attr(struct attr **attrs, struct osd_item *item, int flags)
135 {
136         struct attr *attr;
137
138         item->flags=flags;
139         item->osd_configuration=-1;
140         item->color_white.r = 0xffff;
141         item->color_white.g = 0xffff;
142         item->color_white.b = 0xffff;
143         item->color_white.a = 0xffff;
144         item->text_color.r = 0xffff;
145         item->text_color.g = 0xffff;
146         item->text_color.b = 0xffff;
147         item->text_color.a = 0xffff;
148         if (flags & 1) {
149                 item->color_bg.r = 0x0808;
150                 item->color_bg.g = 0x0808;
151                 item->color_bg.b = 0xf8f8;
152                 item->color_bg.a = 0x0000;
153         } else {
154                 item->color_bg.r = 0x0;
155                 item->color_bg.g = 0x0;
156                 item->color_bg.b = 0x0;
157                 item->color_bg.a = 0x5fff;
158         }
159
160         attr=attr_search(attrs, NULL, attr_osd_configuration);
161         if (attr)
162                 item->osd_configuration = attr->u.num;
163
164         attr=attr_search(attrs, NULL, attr_enable_expression);
165         if (attr) {
166                 item->enable_cs = command_saved_new(attr->u.str, item->navit, NULL);
167         }
168
169         attr = attr_search(attrs, NULL, attr_w);
170         if (attr) {
171                 if (attr->u.num > ATTR_REL_MAXABS) {
172                         item->rel_w = attr->u.num - ATTR_REL_RELSHIFT;
173                 } else {
174                         item->rel_w = 0;
175                         item->w = attr->u.num;
176                 }
177         }
178
179         attr = attr_search(attrs, NULL, attr_h);
180         if (attr) {
181                 if (attr->u.num > ATTR_REL_MAXABS) {
182                         item->rel_h = attr->u.num - ATTR_REL_RELSHIFT;
183                 } else {
184                         item->rel_h = 0;
185                         item->h = attr->u.num;
186                 }
187         }
188
189         attr = attr_search(attrs, NULL, attr_x);
190         if (attr) {
191                 if (attr->u.num > ATTR_REL_MAXABS) {
192                         item->rel_x = attr->u.num - ATTR_REL_RELSHIFT;
193                 } else {
194                         item->rel_x = 0;
195                         item->p.x = attr->u.num;
196                 }
197         }
198
199         attr = attr_search(attrs, NULL, attr_y);
200         if (attr) {
201                 if (attr->u.num > ATTR_REL_MAXABS) {
202                         item->rel_y = attr->u.num - ATTR_REL_RELSHIFT;
203                 } else {
204                         item->rel_y = 0;
205                         item->p.y = attr->u.num;
206                 }
207         }
208
209         attr = attr_search(attrs, NULL, attr_font_size);
210         if (attr)
211                 item->font_size = attr->u.num;
212         
213         attr=attr_search(attrs, NULL, attr_background_color);
214         if (attr)
215                 item->color_bg=*attr->u.color;
216         attr = attr_search(attrs, NULL, attr_command);
217         if (attr) 
218                 item->command = g_strdup(attr->u.str);
219         attr=attr_search(attrs, NULL, attr_text_color);
220         if (attr)
221                 item->text_color=*attr->u.color;
222         attr=attr_search(attrs, NULL, attr_flags);
223         if (attr)
224                 item->attr_flags=attr->u.num;
225 }
226
227 void
228 osd_std_config(struct osd_item *item, struct navit *navit)
229 {
230         struct attr attr;
231         dbg(1,"enter\n");
232         if (item->enable_cs) {
233                 item->reconfig_cb = callback_new_1(callback_cast(osd_std_reconfigure), item);
234                 command_saved_set_cb(item->enable_cs, item->reconfig_cb);
235
236                 if (!command_saved_error(item->enable_cs)) {
237                         item->configured = !! command_saved_get_int(item->enable_cs);
238                 } else {
239                         dbg(0, "Error in saved command: %i.\n", command_saved_error(item->enable_cs));
240                 }
241         } else {
242                 if (!navit_get_attr(navit, attr_osd_configuration, &attr, NULL))
243                         attr.u.num=-1;
244                 item->configured = !!(attr.u.num & item->osd_configuration);
245         }
246         graphics_overlay_disable(item->gr, !item->configured);
247 }
248
249 void
250 osd_set_std_graphic(struct navit *nav, struct osd_item *item, struct osd_priv *priv)
251 {
252         struct graphics *navit_gr;
253
254         navit_gr = navit_get_graphics(nav);
255         item->gr = graphics_overlay_new(navit_gr, &item->p, item->w, item->h, 65535, 1);
256
257         item->graphic_bg = graphics_gc_new(item->gr);
258         graphics_gc_set_foreground(item->graphic_bg, &item->color_bg);
259         graphics_background_gc(item->gr, item->graphic_bg);
260
261         item->graphic_fg_white = graphics_gc_new(item->gr);
262         graphics_gc_set_foreground(item->graphic_fg_white, &item->color_white);
263
264         if (item->flags & 2) {
265                 item->font = graphics_font_new(item->gr, item->font_size, 1);
266                 item->graphic_fg_text = graphics_gc_new(item->gr);
267                 graphics_gc_set_foreground(item->graphic_fg_text, &item->text_color);
268         }
269
270         item->cb = callback_new_attr_2(callback_cast(osd_std_config), attr_osd_configuration, item, nav);
271         navit_add_callback(nav, item->cb);
272
273         item->resize_cb = callback_new_attr_2(callback_cast(osd_std_calculate_sizes), attr_resize, item, priv);
274         graphics_add_callback(navit_gr, item->resize_cb);
275
276         osd_std_config(item, nav);
277 }
278
279 void
280 osd_std_draw(struct osd_item *item)
281 {
282         struct point p[2];
283         int flags=item->attr_flags;
284
285         graphics_draw_mode(item->gr, draw_mode_begin);
286         p[0].x=0;
287         p[0].y=0;
288         graphics_draw_rectangle(item->gr, item->graphic_bg, p, item->w, item->h);
289         p[1].x=item->w-1;
290         p[1].y=0;
291         if (flags & 1) 
292                 graphics_draw_lines(item->gr, item->graphic_fg_text, p, 2);
293         p[0].x=item->w-1;
294         p[0].y=item->h-1;
295         if (flags & 2) 
296                 graphics_draw_lines(item->gr, item->graphic_fg_text, p, 2);
297         p[1].x=0;
298         p[1].y=item->h-1;
299         if (flags & 4) 
300                 graphics_draw_lines(item->gr, item->graphic_fg_text, p, 2);
301         p[0].x=0;
302         p[0].y=0;
303         if (flags & 8) 
304                 graphics_draw_lines(item->gr, item->graphic_fg_text, p, 2);
305 }