2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 Navit Team
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.
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.
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.
31 #include "transform.h"
39 #include "navigation.h"
45 #include "navit_nls.h"
47 #include "vehicleprofile.h"
48 #include "roadprofile.h"
53 struct osd_item osd_item;
55 struct graphics_gc *green;
59 transform_rotate(struct point *center, int angle, struct point *p,
64 for (i = 0; i < count; i++) {
65 dx = sin(M_PI * angle / 180.0);
66 dy = cos(M_PI * angle / 180.0);
67 x = dy * p->x - dx * p->y;
68 y = dx * p->x + dy * p->y;
77 handle(struct graphics *gr, struct graphics_gc *gc, struct point *p, int r,
87 transform_rotate(p, dir, ph, 2);
88 graphics_draw_lines(gr, gc, ph, 2);
95 transform_rotate(p, dir, ph, 3);
96 graphics_draw_lines(gr, gc, ph, 3);
100 format_distance(double distance, char *sep)
102 if (distance >= 100000)
103 return g_strdup_printf("%.0f%skm", distance / 1000, sep);
104 else if (distance >= 10000)
105 return g_strdup_printf("%.1f%skm", distance / 1000, sep);
106 else if (distance >= 300)
107 return g_strdup_printf("%.0f%sm", round(distance / 25) * 25, sep);
108 else if (distance >= 50)
109 return g_strdup_printf("%.0f%sm", round(distance / 10) * 10, sep);
110 else if (distance >= 10)
111 return g_strdup_printf("%.0f%sm", distance, sep);
113 return g_strdup_printf("%.1f%sm", distance, sep);
117 format_time(struct tm *tm, int days)
120 return g_strdup_printf("%d+%02d:%02d", days, tm->tm_hour, tm->tm_min);
122 return g_strdup_printf("%02d:%02d", tm->tm_hour, tm->tm_min);
126 format_speed(double speed, char *sep)
128 return g_strdup_printf("%.0f%skm/h", speed, sep);
132 format_float(double num)
134 return g_strdup_printf("%f", num);
138 format_float_0(double num)
140 return g_strdup_printf("%.0f", num);
144 osd_compass_draw(struct compass *this, struct navit *nav,
147 struct point p,bbox[4];
148 struct attr attr_dir, destination_attr, position_attr;
149 double dir, vdir = 0;
154 osd_std_draw(&this->osd_item);
155 p.x = this->osd_item.w/2;
156 p.y = this->osd_item.w/2;
157 graphics_draw_circle(this->osd_item.gr,
158 this->osd_item.graphic_fg_white, &p, this->osd_item.w*5/6);
160 if (vehicle_get_attr(v, attr_position_direction, &attr_dir, NULL)) {
161 vdir = *attr_dir.u.numd;
162 handle(this->osd_item.gr, this->osd_item.graphic_fg_white, &p, this->osd_item.w/3, -vdir);
165 if (navit_get_attr(nav, attr_destination, &destination_attr, NULL)
166 && vehicle_get_attr(v, attr_position_coord_geo,&position_attr, NULL)) {
167 pro = destination_attr.u.pcoord->pro;
168 transform_from_geo(pro, position_attr.u.coord_geo, &c1);
169 c2.x = destination_attr.u.pcoord->x;
170 c2.y = destination_attr.u.pcoord->y;
171 dir = atan2(c2.x - c1.x, c2.y - c1.y) * 180.0 / M_PI;
173 handle(this->osd_item.gr, this->green, &p, this->osd_item.w/3, dir);
174 buffer=format_distance(transform_distance(pro, &c1, &c2),"");
175 graphics_get_text_bbox(this->osd_item.gr, this->osd_item.font, buffer, 0x10000, 0, bbox, 0);
176 p.x=(this->osd_item.w-bbox[2].x)/2;
177 p.y = this->osd_item.h-this->osd_item.h/10;
178 graphics_draw_text(this->osd_item.gr, this->green, NULL, this->osd_item.font, buffer, &p, 0x10000, 0);
182 graphics_draw_mode(this->osd_item.gr, draw_mode_end);
188 osd_compass_init(struct compass *this, struct navit *nav)
192 osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
194 this->green = graphics_gc_new(this->osd_item.gr);
199 graphics_gc_set_foreground(this->green, &c);
200 graphics_gc_set_linewidth(this->green, this->width);
201 graphics_gc_set_linewidth(this->osd_item.graphic_fg_white, this->width);
203 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_compass_draw), attr_position_coord_geo, this));
205 osd_compass_draw(this, nav, NULL);
208 static struct osd_priv *
209 osd_compass_new(struct navit *nav, struct osd_methods *meth,
212 struct compass *this = g_new0(struct compass, 1);
214 this->osd_item.p.x = 20;
215 this->osd_item.p.y = 20;
216 this->osd_item.w = 60;
217 this->osd_item.h = 80;
218 this->osd_item.navit = nav;
219 this->osd_item.font_size = 200;
220 this->osd_item.meth.draw = osd_draw_cast(osd_compass_draw);
221 osd_set_std_attr(attrs, &this->osd_item, 2);
222 attr = attr_search(attrs, NULL, attr_width);
223 this->width=attr ? attr->u.num : 2;
224 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_compass_init), attr_navit, this));
225 return (struct osd_priv *) this;
230 struct osd_item item;
231 struct callback *draw_cb,*navit_init_cb;
232 struct graphics_image *img;
237 osd_button_draw(struct osd_button *this, struct navit *nav)
239 struct point bp = this->item.p;
240 osd_wrap_point(&bp, nav);
241 graphics_draw_image(this->item.gr, this->item.graphic_bg, &bp, this->img);
245 osd_button_init(struct osd_button *this, struct navit *nav)
247 struct graphics *gra = navit_get_graphics(nav);
249 this->img = graphics_image_new(gra, this->src);
251 dbg(1, "failed to load '%s'\n", this->src);
255 this->item.w=this->img->width;
257 this->item.h=this->img->height;
258 if (this->use_overlay) {
259 struct graphics_image *img;
261 osd_set_std_graphic(nav, &this->item, (struct osd_priv *)this);
262 img=graphics_image_new(this->item.gr, this->src);
263 p.x=(this->item.w-this->img->width)/2;
264 p.y=(this->item.h-this->img->height)/2;
265 osd_std_draw(&this->item);
266 graphics_draw_image(this->item.gr, this->item.graphic_bg, &p, img);
267 graphics_draw_mode(this->item.gr, draw_mode_end);
268 graphics_image_free(this->item.gr, img);
270 this->item.configured=1;
272 this->item.graphic_bg=graphics_gc_new(this->item.gr);
273 graphics_add_callback(gra, this->draw_cb=callback_new_attr_2(callback_cast(osd_button_draw), attr_postdraw, this, nav));
275 navit_add_callback(nav, this->navit_init_cb = callback_new_attr_1(callback_cast (osd_std_click), attr_button, &this->item));
278 static struct osd_priv *
279 osd_button_new(struct navit *nav, struct osd_methods *meth,
282 struct osd_button *this = g_new0(struct osd_button, 1);
285 this->item.navit = nav;
286 this->item.meth.draw = osd_draw_cast(osd_button_draw);
288 osd_set_std_attr(attrs, &this->item, 1);
290 attr=attr_search(attrs, NULL, attr_use_overlay);
292 this->use_overlay=attr->u.num;
293 if (!this->item.command) {
294 dbg(0, "no command\n");
297 attr = attr_search(attrs, NULL, attr_src);
303 this->src = graphics_icon_path(attr->u.str);
305 navit_add_callback(nav, this->navit_init_cb = callback_new_attr_1(callback_cast (osd_button_init), attr_navit, this));
307 return (struct osd_priv *) this;
313 struct nav_next_turn {
314 struct osd_item osd_item;
317 int icon_h, icon_w, active;
323 osd_nav_next_turn_draw(struct nav_next_turn *this, struct navit *navit,
328 struct navigation *nav = NULL;
329 struct map *map = NULL;
330 struct map_rect *mr = NULL;
331 struct item *item = NULL;
332 struct graphics_image *gr_image;
334 char *name = "unknown";
335 int level = this->level;
338 nav = navit_get_navigation(navit);
340 map = navigation_get_map(nav);
342 mr = map_rect_new(map, NULL);
344 while ((item = map_rect_get_item(mr))
345 && (item->type == type_nav_position || item->type == type_nav_none || level-- > 0));
347 name = item_to_name(item->type);
348 dbg(1, "name=%s\n", name);
349 if (this->active != 1 || this->last_name != name) {
351 this->last_name = name;
355 if (this->active != 0) {
361 map_rect_destroy(mr);
364 osd_std_draw(&this->osd_item);
366 image = g_strdup_printf(this->icon_src, name);
367 dbg(1, "image=%s\n", image);
369 graphics_image_new_scaled(this->osd_item.gr,
374 image = graphics_icon_path("unknown.xpm");
376 graphics_image_new_scaled(this->
383 dbg(1, "gr_image=%p\n", gr_image);
387 gr_image->width) / 2;
390 gr_image->height) / 2;
391 graphics_draw_image(this->osd_item.gr,
393 graphic_fg_white, &p,
395 graphics_image_free(this->osd_item.gr,
400 graphics_draw_mode(this->osd_item.gr, draw_mode_end);
405 osd_nav_next_turn_init(struct nav_next_turn *this, struct navit *nav)
407 osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
408 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_nav_next_turn_draw), attr_position_coord_geo, this));
409 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_std_click), attr_button, &this->osd_item));
410 osd_nav_next_turn_draw(this, nav, NULL);
413 static struct osd_priv *
414 osd_nav_next_turn_new(struct navit *nav, struct osd_methods *meth,
417 struct nav_next_turn *this = g_new0(struct nav_next_turn, 1);
420 this->osd_item.p.x = 20;
421 this->osd_item.p.y = -80;
422 this->osd_item.w = 70;
423 this->osd_item.navit = nav;
424 this->osd_item.h = 70;
425 this->osd_item.font_size = 200;
426 this->osd_item.meth.draw = osd_draw_cast(osd_nav_next_turn_draw);
427 osd_set_std_attr(attrs, &this->osd_item, 0);
434 attr = attr_search(attrs, NULL, attr_icon_w);
436 this->icon_w = attr->u.num;
438 attr = attr_search(attrs, NULL, attr_icon_h);
440 this->icon_h = attr->u.num;
442 attr = attr_search(attrs, NULL, attr_icon_src);
444 struct file_wordexp *we;
446 we = file_wordexp_new(attr->u.str);
447 array = file_wordexp_get_array(we);
448 this->icon_src = graphics_icon_path(array[0]);
449 file_wordexp_destroy(we);
451 this->icon_src = graphics_icon_path("%s_wh.svg");
454 attr = attr_search(attrs, NULL, attr_level);
456 this->level=attr->u.num;
458 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_nav_next_turn_init), attr_navit, this));
459 return (struct osd_priv *) this;
462 struct nav_toggle_announcer
465 struct callback *navit_init_cb;
466 struct osd_item item;
468 int icon_h, icon_w, active, last_state;
472 osd_nav_toggle_announcer_draw(struct nav_toggle_announcer *this, struct navit *navit, struct vehicle *v)
476 struct graphics_image *gr_image;
478 char *gui_sound_off = "gui_sound_off";
479 char *gui_sound_on = "gui_sound";
480 struct attr attr, speechattr;
482 if (this->last_state == -1)
484 if (!navit_get_attr(navit, attr_speech, &speechattr, NULL))
485 if (!speech_get_attr(speechattr.u.speech, attr_active, &attr, NULL))
487 this->active = attr.u.num;
489 this->active = !this->active;
491 if(this->active != this->last_state)
493 this->last_state = this->active;
499 graphics_draw_mode(this->item.gr, draw_mode_begin);
502 graphics_draw_rectangle(this->item.gr, this->item.graphic_bg, &p, this->item.w, this->item.h);
505 path = g_strdup_printf(this->icon_src, gui_sound_on);
507 path = g_strdup_printf(this->icon_src, gui_sound_off);
509 gr_image = graphics_image_new_scaled(this->item.gr, path, this->icon_w, this->icon_h);
513 path = graphics_icon_path("unknown.xpm");
514 gr_image = graphics_image_new_scaled(this->item.gr, path, this->icon_w, this->icon_h);
517 dbg(1, "gr_image=%p\n", gr_image);
521 p.x = (this->item.w - gr_image->width) / 2;
522 p.y = (this->item.h - gr_image->height) / 2;
523 graphics_draw_image(this->item.gr, this->item.graphic_fg_white, &p, gr_image);
524 graphics_image_free(this->item.gr, gr_image);
528 graphics_draw_mode(this->item.gr, draw_mode_end);
533 osd_nav_toggle_announcer_init(struct nav_toggle_announcer *this, struct navit *nav)
535 osd_set_std_graphic(nav, &this->item, (struct osd_priv *)this);
536 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_nav_toggle_announcer_draw), attr_speech, this));
537 navit_add_callback(nav, this->navit_init_cb = callback_new_attr_1(callback_cast(osd_std_click), attr_button, &this->item));
538 osd_nav_toggle_announcer_draw(this, nav, NULL);
541 static struct osd_priv *
542 osd_nav_toggle_announcer_new(struct navit *nav, struct osd_methods *meth, struct attr **attrs)
544 struct nav_toggle_announcer *this = g_new0(struct nav_toggle_announcer, 1);
546 char *command = "announcer_toggle()";
550 this->item.p.x = -64;
551 this->item.navit = nav;
553 this->item.meth.draw = osd_draw_cast(osd_nav_toggle_announcer_draw);
555 osd_set_std_attr(attrs, &this->item, 0);
559 this->last_state = -1;
561 attr = attr_search(attrs, NULL, attr_icon_src);
563 struct file_wordexp *we;
565 we = file_wordexp_new(attr->u.str);
566 array = file_wordexp_get_array(we);
567 this->icon_src = g_strdup(array[0]);
568 file_wordexp_destroy(we);
570 this->icon_src = graphics_icon_path("%s_32.xpm");
572 this->item.command = g_strdup(command);
574 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_nav_toggle_announcer_init), attr_navit, this));
575 return (struct osd_priv *) this;
578 struct osd_speed_warner {
579 struct osd_item item;
580 struct graphics_gc *red;
587 osd_speed_warner_draw(struct osd_speed_warner *this, struct navit *navit, struct vehicle *v)
592 osd_std_draw(&this->item);
593 p[0].x=this->item.w/2-this->d/4;
594 p[0].y=this->item.h/2-this->d/4;
595 graphics_draw_rectangle(this->item.gr, this->item.graphic_fg_white, p, this->d/2, this->d/2);
596 p[0].x=this->item.w/2;
597 p[0].y=this->item.h/2;
598 graphics_draw_circle(this->item.gr, this->item.graphic_fg_white, p, this->d/2);
599 graphics_draw_circle(this->item.gr, this->red, p, this->d-this->width*2);
600 graphics_get_text_bbox(this->item.gr, this->item.font, text, 0x10000, 0, p, 0);
601 p[0].x=(this->item.w-p[2].x)/2;
602 p[0].y=(this->item.h+p[2].y)/2-p[2].y;
603 graphics_draw_text(this->item.gr, this->item.graphic_fg_text, NULL, this->item.font, text, p, 0x10000, 0);
604 graphics_draw_mode(this->item.gr, draw_mode_end);
608 osd_speed_warner_init(struct osd_speed_warner *this, struct navit *nav)
610 osd_set_std_graphic(nav, &this->item, (struct osd_priv *)this);
611 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_speed_warner_draw), attr_position_coord_geo, this));
612 this->red=graphics_gc_new(this->item.gr);
613 graphics_gc_set_foreground(this->red, &(struct color ){0xffff,0,0,0xffff});
614 graphics_gc_set_linewidth(this->red, this->width);
615 graphics_gc_set_linewidth(this->item.graphic_fg_white, this->d/4+2);
616 osd_speed_warner_draw(this, nav, NULL);
619 static struct osd_priv *
620 osd_speed_warner_new(struct navit *nav, struct osd_methods *meth, struct attr **attrs)
622 struct osd_speed_warner *this=g_new0(struct osd_speed_warner, 1);
626 this->item.navit = nav;
629 this->item.meth.draw = osd_draw_cast(osd_speed_warner_draw);
630 osd_set_std_attr(attrs, &this->item, 2);
631 this->d=this->item.w;
632 if (this->item.h < this->d)
633 this->d=this->item.h;
634 this->width=this->d/10;
635 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_speed_warner_init), attr_navit, this));
636 return (struct osd_priv *) this;
640 struct osd_item osd_item;
648 osd_text_format_attr(struct attr *attr, char *format)
650 struct tm tm, text_tm, text_tm0;
655 switch (attr->type) {
656 case attr_position_speed:
657 return format_speed(*attr->u.numd,"");
658 case attr_position_height:
659 case attr_position_direction:
660 return format_float_0(*attr->u.numd);
661 case attr_position_magnetic_direction:
662 return g_strdup_printf("%d",attr->u.num);
663 case attr_position_coord_geo:
664 coord_format(attr->u.coord_geo->lat,attr->u.coord_geo->lng,DEGREES_MINUTES_SECONDS,buffer,sizeof(buffer));
665 return g_strdup(buffer);
666 case attr_destination_time:
667 if (!format || (strcmp(format,"arrival") && strcmp(format,"remaining")))
670 tm = *localtime(&textt);
671 if (!strcmp(format,"remaining")) {
672 textt-=tm.tm_hour*3600+tm.tm_min*60+tm.tm_sec;
673 tm = *localtime(&textt);
675 textt += attr->u.num / 10;
676 text_tm = *localtime(&textt);
677 if (tm.tm_year != text_tm.tm_year || tm.tm_mon != text_tm.tm_mon || tm.tm_mday != text_tm.tm_mday) {
681 text_tm0.tm_hour = 0;
685 days = (mktime(&text_tm0) - mktime(&tm) + 43200) / 86400;
687 return format_time(&text_tm, days);
689 case attr_destination_length:
692 if (!strcmp(format,"named"))
693 return format_distance(attr->u.num,"");
694 if (!strcmp(format,"value") || !strcmp(format,"unit")) {
695 char *ret,*tmp=format_distance(attr->u.num," ");
696 char *pos=strchr(tmp,' ');
700 if (!strcmp(format,"value"))
709 return attr_to_text(attr, NULL, 1);
713 osd_text_split(char *in, char **index)
719 len=strcspn(in,"[.");
746 osd_text_draw(struct osd_text *this, struct navit *navit, struct vehicle *v)
748 struct point p, p2[4];
749 char *str,*next,*last,*start,*end,*key,*subkey,*index,*value;
751 struct attr attr, vehicle_attr, maxspeed_attr;
752 struct navigation *nav = NULL;
753 struct tracking *tracking = NULL;
754 struct route *route = NULL;
755 struct map *nav_map = NULL;
756 struct map_rect *nav_mr = NULL;
759 int height=this->osd_item.font_size*13/256;
760 int yspacing=height/2;
761 int xspacing=height/4;
762 enum attr_type attr_type;
764 vehicle_attr.u.vehicle=NULL;
766 str=g_strdup(this->text);
767 while ((start=strstr(str, "${"))) {
775 subkey=osd_text_split(key,NULL);
776 if (!strcmp(key,"navigation") && subkey) {
778 nav = navit_get_navigation(navit);
780 nav_map = navigation_get_map(nav);
782 key=osd_text_split(subkey,&index);
783 if (nav_map && !strcmp(subkey,"item")) {
785 nav_mr = map_rect_new(nav_map, NULL);
787 item = map_rect_get_item(nav_mr);
793 if (item->type == type_nav_none)
794 item=map_rect_get_item(nav_mr);
799 item=map_rect_get_item(nav_mr);
803 dbg(1,"name %s\n", item_to_name(item->type));
804 subkey=osd_text_split(key,&index);
805 attr_type=attr_from_name(key);
806 dbg(1,"type %s\n", attr_to_name(attr_type));
807 if (item_attr_get(item, attr_type, &attr))
808 value=osd_text_format_attr(&attr, index);
813 } else if (!strcmp(key,"tracking") && subkey) {
815 tracking = navit_get_tracking(navit);
816 route = navit_get_route(navit);
819 key=osd_text_split(subkey,&index);
820 if (!strcmp(subkey, "item") && key) {
821 item=tracking_get_current_item(tracking);
822 if (item && !strcmp(key,"route_speed")) {
823 double routespeed = -1;
824 int *flags=tracking_get_current_flags(tracking);
825 if (flags && (*flags & AF_SPEED_LIMIT) && tracking_get_attr(tracking, attr_maxspeed, &maxspeed_attr, NULL)) {
826 routespeed = maxspeed_attr.u.num;
827 value = format_speed(routespeed, "");
830 if (routespeed == -1) {
831 struct vehicleprofile *prof=navit_get_vehicleprofile(navit);
832 struct roadprofile *rprof=NULL;
834 rprof=vehicleprofile_get_roadprofile(prof, item->type);
836 routespeed=rprof->speed;
837 value=format_speed(routespeed,"");
841 attr_type=attr_from_name(key);
842 if (tracking_get_attr(tracking, attr_type, &attr, NULL))
843 value=osd_text_format_attr(&attr, index);
847 } else if (!strcmp(key,"vehicle") && subkey) {
848 if (navit && !vehicle_attr.u.vehicle) {
849 navit_get_attr(navit, attr_vehicle, &vehicle_attr, NULL);
851 if (vehicle_attr.u.vehicle) {
852 key=osd_text_split(subkey,&index);
853 attr_type=attr_from_name(subkey);
854 if (vehicle_get_attr(vehicle_attr.u.vehicle, attr_type, &attr, NULL)) {
855 value=osd_text_format_attr(&attr, index);
859 } else if (!strcmp(key,"navit") && subkey) {
861 key = osd_text_split(subkey, &index);
862 if (!strcmp(subkey,"messages")) {
867 msg = navit_get_messages(navit);
870 len+= strlen(msg->text) + 2;
875 value = g_malloc(len +1);
877 msg = navit_get_messages(navit);
880 tmp = g_stpcpy((value+offset), msg->text);
881 g_stpcpy(tmp, "\\n");
882 offset += strlen(msg->text) + 2;
892 next=g_strdup_printf("%s%s%s",str,value ? value:" ",end);
900 while ((next=strstr(next, "\\n"))) {
907 if (! g_ascii_isspace(*last)) {
914 dbg(1,"this->align=%d\n", this->align);
915 switch (this->align & 51) {
920 p.y=(this->osd_item.h-lines*(height+yspacing)-yspacing);
922 case 16: // Grow from top to bottom
925 this->osd_item.h = (lines-1) * (height+yspacing) + height;
927 this->osd_item.h = 0;
931 osd_std_resize(&this->osd_item);
934 p.y=(this->osd_item.h-lines*(height+yspacing)-yspacing)/2;
937 osd_std_draw(&this->osd_item);
939 next=strstr(str, "\\n");
944 graphics_get_text_bbox(this->osd_item.gr,
948 switch (this->align & 12) {
953 p.x=this->osd_item.w-(p2[2].x-p2[0].x)-xspacing;
956 p.x = ((p2[0].x - p2[2].x) / 2) + (this->osd_item.w / 2);
958 p.y += height+yspacing;
959 graphics_draw_text(this->osd_item.gr,
960 this->osd_item.graphic_fg_text,
961 NULL, this->osd_item.font,
966 graphics_draw_mode(this->osd_item.gr, draw_mode_end);
972 osd_text_init(struct osd_text *this, struct navit *nav)
975 osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
976 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_text_draw), attr_position_coord_geo, this));
977 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_std_click), attr_button, &this->osd_item));
978 osd_text_draw(this, nav, NULL);
982 static struct osd_priv *
983 osd_text_new(struct navit *nav, struct osd_methods *meth,
986 struct osd_text *this = g_new0(struct osd_text, 1);
989 this->osd_item.p.x = -80;
990 this->osd_item.p.y = 20;
991 this->osd_item.w = 60;
992 this->osd_item.h = 20;
993 this->osd_item.navit = nav;
994 this->osd_item.font_size = 200;
995 this->osd_item.meth.draw = osd_draw_cast(osd_text_draw);
996 osd_set_std_attr(attrs, &this->osd_item, 2);
1000 attr = attr_search(attrs, NULL, attr_label);
1002 this->text = g_strdup(attr->u.str);
1005 attr = attr_search(attrs, NULL, attr_align);
1007 this->align=attr->u.num;
1009 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_text_init), attr_navit, this));
1010 return (struct osd_priv *) this;
1014 struct osd_item osd_item;
1016 int icon_h, icon_w, active;
1021 osd_gps_status_draw(struct gps_status *this, struct navit *navit,
1026 struct graphics_image *gr_image;
1028 struct attr attr, vehicle_attr;
1031 if (navit && navit_get_attr(navit, attr_vehicle, &vehicle_attr, NULL)) {
1032 if (vehicle_get_attr(vehicle_attr.u.vehicle, attr_position_fix_type, &attr, NULL)) {
1033 switch(attr.u.num) {
1037 if (vehicle_get_attr(vehicle_attr.u.vehicle, attr_position_sats_used, &attr, NULL)) {
1038 dbg(1,"num=%d\n", attr.u.num);
1039 if (attr.u.num >= 3)
1040 strength=attr.u.num-1;
1044 if (vehicle_get_attr(vehicle_attr.u.vehicle, attr_position_hdop, &attr, NULL)) {
1045 if (*attr.u.numd > 2.0 && strength > 4)
1047 if (*attr.u.numd > 4.0 && strength > 3)
1058 if (this->strength != strength) {
1059 this->strength=strength;
1063 osd_std_draw(&this->osd_item);
1065 image = g_strdup_printf(this->icon_src, strength);
1066 gr_image = graphics_image_new_scaled(this->osd_item.gr, image, this->icon_w, this->icon_h);
1068 p.x = (this->osd_item.w - gr_image->width) / 2;
1069 p.y = (this->osd_item.h - gr_image->height) / 2;
1070 graphics_draw_image(this->osd_item.gr, this->osd_item. graphic_fg_white, &p, gr_image);
1071 graphics_image_free(this->osd_item.gr, gr_image);
1075 graphics_draw_mode(this->osd_item.gr, draw_mode_end);
1080 osd_gps_status_init(struct gps_status *this, struct navit *nav)
1082 osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
1083 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_gps_status_draw), attr_position_coord_geo, this));
1084 osd_gps_status_draw(this, nav, NULL);
1087 static struct osd_priv *
1088 osd_gps_status_new(struct navit *nav, struct osd_methods *meth,
1089 struct attr **attrs)
1091 struct gps_status *this = g_new0(struct gps_status, 1);
1094 this->osd_item.p.x = 20;
1095 this->osd_item.p.y = -80;
1096 this->osd_item.w = 60;
1097 this->osd_item.navit = nav;
1098 this->osd_item.h = 40;
1099 this->osd_item.font_size = 200;
1100 this->osd_item.meth.draw = osd_draw_cast(osd_gps_status_draw);
1101 osd_set_std_attr(attrs, &this->osd_item, 0);
1106 this->strength = -2;
1108 attr = attr_search(attrs, NULL, attr_icon_w);
1110 this->icon_w = attr->u.num;
1112 attr = attr_search(attrs, NULL, attr_icon_h);
1114 this->icon_h = attr->u.num;
1116 attr = attr_search(attrs, NULL, attr_icon_src);
1118 struct file_wordexp *we;
1120 we = file_wordexp_new(attr->u.str);
1121 array = file_wordexp_get_array(we);
1122 this->icon_src = g_strdup(array[0]);
1123 file_wordexp_destroy(we);
1125 this->icon_src = graphics_icon_path("gui_strength_%d_32_32.png");
1127 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_gps_status_init), attr_navit, this));
1128 return (struct osd_priv *) this;
1133 struct osd_item osd_item;
1135 int icon_h, icon_w, active;
1137 struct callback *click_cb;
1141 osd_volume_draw(struct volume *this, struct navit *navit)
1144 struct graphics_image *gr_image;
1147 osd_std_draw(&this->osd_item);
1149 image = g_strdup_printf(this->icon_src, this->strength);
1150 gr_image = graphics_image_new_scaled(this->osd_item.gr, image, this->icon_w, this->icon_h);
1152 p.x = (this->osd_item.w - gr_image->width) / 2;
1153 p.y = (this->osd_item.h - gr_image->height) / 2;
1154 graphics_draw_image(this->osd_item.gr, this->osd_item. graphic_fg_white, &p, gr_image);
1155 graphics_image_free(this->osd_item.gr, gr_image);
1159 graphics_draw_mode(this->osd_item.gr, draw_mode_end);
1163 osd_volume_click(struct volume *this, struct navit *nav, int pressed, int button, struct point *p)
1165 struct point bp = this->osd_item.p;
1166 osd_wrap_point(&bp, nav);
1167 if ((p->x < bp.x || p->y < bp.y || p->x > bp.x + this->osd_item.w || p->y > bp.y + this->osd_item.h) && !this->osd_item.pressed)
1169 navit_ignore_button(nav);
1171 if (p->y - bp.y < this->osd_item.h/2)
1175 if (this->strength < 0)
1177 if (this->strength > 5)
1179 osd_volume_draw(this, nav);
1183 osd_volume_init(struct volume *this, struct navit *nav)
1185 osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
1186 navit_add_callback(nav, this->click_cb = callback_new_attr_1(callback_cast (osd_volume_click), attr_button, this));
1187 osd_volume_draw(this, nav);
1190 static struct osd_priv *
1191 osd_volume_new(struct navit *nav, struct osd_methods *meth,
1192 struct attr **attrs)
1194 struct volume *this = g_new0(struct volume, 1);
1197 this->osd_item.p.x = 20;
1198 this->osd_item.p.y = -80;
1199 this->osd_item.w = 60;
1200 this->osd_item.navit = nav;
1201 this->osd_item.h = 40;
1202 this->osd_item.font_size = 200;
1203 this->osd_item.meth.draw = osd_draw_cast(osd_volume_draw);
1204 osd_set_std_attr(attrs, &this->osd_item, 0);
1209 this->strength = -1;
1211 attr = attr_search(attrs, NULL, attr_icon_w);
1213 this->icon_w = attr->u.num;
1215 attr = attr_search(attrs, NULL, attr_icon_h);
1217 this->icon_h = attr->u.num;
1219 attr = attr_search(attrs, NULL, attr_icon_src);
1221 struct file_wordexp *we;
1223 we = file_wordexp_new(attr->u.str);
1224 array = file_wordexp_get_array(we);
1225 this->icon_src = g_strdup(array[0]);
1226 file_wordexp_destroy(we);
1228 this->icon_src = graphics_icon_path("gui_strength_%d_32_32.png");
1230 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_volume_init), attr_navit, this));
1231 return (struct osd_priv *) this;
1238 plugin_register_osd_type("compass", osd_compass_new);
1239 plugin_register_osd_type("navigation_next_turn", osd_nav_next_turn_new);
1240 plugin_register_osd_type("button", osd_button_new);
1241 plugin_register_osd_type("toggle_announcer", osd_nav_toggle_announcer_new);
1242 plugin_register_osd_type("speed_warner", osd_speed_warner_new);
1243 plugin_register_osd_type("text", osd_text_new);
1244 plugin_register_osd_type("gps_status", osd_gps_status_new);
1245 plugin_register_osd_type("volume", osd_volume_new);