34826320b3e9fdf6db8a7a7e12f2d9b3f46b828c
[navit-package] / src / gui / gtk / gui_gtk_statusbar.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <time.h>
4 #include <math.h>
5 #include <gtk/gtk.h>
6 #include "item.h"
7 #include "coord.h"
8 #include "debug.h"
9 #include "vehicle.h"
10 #include "callback.h"
11 #include "route.h"
12 #include "transform.h"
13 #include "navit.h"
14 #include "navigation.h"
15 #include "gui_gtk.h"
16
17 #include "statusbar.h"
18
19 struct statusbar_priv {
20         struct gui_priv *gui;
21         GtkWidget *hbox;
22         char gps_text[128];
23         GtkWidget *gps; 
24         char route_text[128];
25         GtkWidget *route;
26         struct callback *vehicle_cb;
27 };
28
29
30 static void
31 statusbar_destroy(struct statusbar_priv *this)
32 {
33         g_free(this);
34 }
35
36 static void
37 statusbar_gps_update(struct statusbar_priv *this, int sats, int qual, double lng, double lat, double height, double direction, double speed)
38 {
39         char lat_c='N';
40         char lng_c='E';
41         char *dirs[]={"N","NO","O","SO","S","SW","W","NW","N"};
42         char *dir;
43         char *utf8;
44         int dir_idx;
45
46         if (lng < 0) {
47                 lng=-lng;
48                 lng_c='W';
49         }
50         if (lat < 0) {
51                 lat=-lat;
52                 lat_c='S';
53         }
54         dir_idx=(direction+22.5)/45;
55         dir=dirs[dir_idx];
56         sprintf(this->gps_text,"GPS %2d/%1d %02.0f%07.4f%c %03.0f%07.4f%c %4.0fm %3.0f°%-2s %3.0fkm/h", sats, qual, floor(lat), fmod(lat*60,60), lat_c, floor(lng), fmod(lng*60,60), lng_c, height, direction, dir, speed);
57         utf8=g_locale_to_utf8(this->gps_text,-1,NULL,NULL,NULL);
58         gtk_label_set_text(GTK_LABEL(this->gps), utf8);
59         g_free(utf8);
60         
61 }
62
63 static void
64 statusbar_route_update(struct statusbar_priv *this, struct navit *nav, struct vehicle *v)
65 {
66         struct navigation *navig;
67         struct navigation_list *list;
68         struct item *item;
69         struct attr attr;
70         double route_len;
71         time_t eta;
72         struct tm *eta_tm;
73         char buffer[128];
74         char *utf8;
75         double lng, lat, direction=0, height=0, speed=0;
76         int sats=0, qual=0;
77         char lat_c='N';
78         char lng_c='E';
79         char *dirs[]={"N","NO","O","SO","S","SW","W","NW","N"};
80         char *dir;
81         int dir_idx;
82
83         navig=navit_get_navigation(nav);
84         if (! navig)
85                 return;
86         list=navigation_list_new(navig);
87         if (! list)
88                 return;
89         item=navigation_list_get_item(list);
90         if (! item)
91                 return;
92         if (!item_attr_get(item, attr_destination_length, &attr))
93                 return;
94         route_len=attr.u.num;
95         if (!item_attr_get(item, attr_destination_time, &attr))
96                 return;
97         eta=time(NULL)+attr.u.num;
98         eta_tm=localtime(&eta);
99         navigation_list_destroy(list);
100         sprintf(buffer,"Route %4.0fkm    %02d:%02d ETA",route_len/1000, eta_tm->tm_hour, eta_tm->tm_min);
101         if (strcmp(buffer, this->route_text)) {
102                 strcpy(this->route_text, buffer);
103                 gtk_label_set_text(GTK_LABEL(this->route), this->route_text);
104         }
105         if (!vehicle_position_attr_get(v, attr_position_coord_geo, &attr))
106                 return;
107         lng=attr.u.coord_geo->lng;
108         lat=attr.u.coord_geo->lat;
109         if (lng < 0) {
110                 lng=-lng;
111                 lng_c='W';
112         }
113         if (lat < 0) {
114                 lat=-lat;
115                 lat_c='S';
116         }
117         if (vehicle_position_attr_get(v, attr_position_direction, &attr))
118                 direction=*(attr.u.numd);
119         dir_idx=(direction+22.5)/45;
120         dir=dirs[dir_idx];
121         if (vehicle_position_attr_get(v, attr_position_height, &attr))
122                 height=*(attr.u.numd);
123         if (vehicle_position_attr_get(v, attr_position_speed, &attr))
124                 speed=*(attr.u.numd);
125         if (vehicle_position_attr_get(v, attr_position_sats_used, &attr))
126                 sats=attr.u.num;
127         if (vehicle_position_attr_get(v, attr_position_qual, &attr))
128                 qual=attr.u.num;
129         sprintf(this->gps_text,"GPS %2d/%1d %02.0f%07.4f%c %03.0f%07.4f%c %4.0fm %3.0f°%-2s %3.0fkm/h", sats, qual, floor(lat), fmod(lat*60,60), lat_c, floor(lng), fmod(lng*60,60), lng_c, height, direction, dir, speed);
130         utf8=g_locale_to_utf8(this->gps_text,-1,NULL,NULL,NULL);
131         gtk_label_set_text(GTK_LABEL(this->gps), utf8);
132         g_free(utf8);
133 }
134
135 static struct statusbar_methods methods = {
136         statusbar_destroy,
137 };
138
139 struct statusbar_priv *
140 gui_gtk_statusbar_new(struct gui_priv *gui, struct statusbar_methods *meth)
141 {
142         struct statusbar_priv *this=g_new0(struct statusbar_priv, 1);
143         char *utf8;
144
145         this->gui=gui;
146         *meth=methods;
147
148         this->hbox=gtk_hbox_new(FALSE, 1);
149         utf8=g_locale_to_utf8("GPS 00/0 0000.0000N 00000.0000E 0000m 000°NO 000km/h",-1,NULL,NULL,NULL);
150         this->gps=gtk_label_new(utf8);
151         g_free(utf8);
152         gtk_label_set_justify(GTK_LABEL(this->gps),  GTK_JUSTIFY_LEFT);
153         this->route=gtk_label_new("Route 0000km  0+00:00 ETA");
154         gtk_label_set_justify(GTK_LABEL(this->route),  GTK_JUSTIFY_LEFT);
155         gtk_box_pack_start(GTK_BOX(this->hbox), this->gps, TRUE, TRUE, 2);
156         gtk_box_pack_start(GTK_BOX(this->hbox), gtk_vseparator_new(), TRUE, TRUE, 2);
157         gtk_box_pack_start(GTK_BOX(this->hbox), this->route, TRUE, TRUE, 2);
158         GTK_WIDGET_UNSET_FLAGS (this->hbox, GTK_CAN_FOCUS);
159
160         gtk_box_pack_end(GTK_BOX(gui->vbox), this->hbox, FALSE, FALSE, 0);
161         gtk_widget_show_all(this->hbox);
162         this->vehicle_cb=callback_new_1(callback_cast(statusbar_route_update), this);
163         navit_add_vehicle_cb(gui->nav, this->vehicle_cb);
164         return this;
165 }
166