Contents of /trunk/src/goto.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 233 - (hide annotations)
Wed Dec 9 19:45:36 2009 UTC (14 years, 5 months ago) by harbaum
File MIME type: text/plain
File size: 20167 byte(s)
File selection fremantleized
1 harbaum 1 /*
2     * Copyright (C) 2008 Till Harbaum <till@harbaum.org>.
3     *
4     * This file is part of GPXView.
5     *
6     * GPXView is free software: you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation, either version 3 of the License, or
9     * (at your option) any later version.
10     *
11     * GPXView is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with GPXView. If not, see <http://www.gnu.org/licenses/>.
18     */
19    
20     #include <stdio.h>
21     #include <string.h>
22     #include <math.h>
23    
24     #include "gpxview.h"
25    
26     #ifdef USE_MAEMO
27     #include "dbus.h"
28     #endif
29    
30     #define COMPASS_SIZE 230
31     #define LETTER_SPACE 0.2
32     #define DIAMOND_WIDTH 0.05
33     #define DIAMOND_HEIGHT 0.2
34     #define ARROW_WIDTH 0.3
35     #define ARROW_LENGTH 0.7
36     #define UPDATE_MS 1000 /* gps updates are sent once a second */
37    
38     #define SAT_WIDTH 330
39     #define SAT_HEIGHT 60
40    
41     static float rad2deg(float rad) {
42     return fmodf(360.0 + (180.0/M_PI) * rad, 360.0);
43     }
44    
45     static void compass_draw(GtkWidget *widget, cache_context_t *context) {
46     float f;
47     int i;
48    
49     gint width = widget->allocation.width;
50     gint height = widget->allocation.height;
51     gint diameter = (height < width)?height:width;
52    
53     gint xcenter = width/2;
54     gint ycenter = height/2;
55     gint radius = diameter/2;
56    
57     /* erase background */
58     gdk_draw_rectangle(context->gotoc.compass_pixmap,
59     widget->style->bg_gc[GTK_STATE_NORMAL], TRUE,
60     0, 0, width, height);
61    
62     /* use white rosetta background unless the real background */
63     /* is very bright. Use bright grey then */
64    
65     if(widget->style->bg[GTK_STATE_NORMAL].red +
66     widget->style->bg[GTK_STATE_NORMAL].green +
67     widget->style->bg[GTK_STATE_NORMAL].blue < 3*60000) {
68     /* background is very bright, use white */
69     gdk_draw_arc(context->gotoc.compass_pixmap, widget->style->white_gc, TRUE,
70     (width-diameter)/2, (height-diameter)/2, diameter, diameter,
71     0, 360*64);
72     } else {
73     GdkGC *lgrey_gc = gdk_gc_new(context->gotoc.compass_pixmap);
74     gdk_gc_copy(lgrey_gc, widget->style->black_gc);
75     GdkColor lgrey_color;
76     gdk_color_parse("#DDDDDD", &lgrey_color);
77     gdk_gc_set_rgb_fg_color(lgrey_gc, &lgrey_color);
78    
79     gdk_draw_arc(context->gotoc.compass_pixmap, lgrey_gc, TRUE,
80     (width-diameter)/2, (height-diameter)/2, diameter, diameter,
81     0, 360*64);
82     }
83    
84     /* draw the locked/unlocked icon */
85     gdk_draw_pixbuf(context->gotoc.compass_pixmap,
86     widget->style->fg_gc[GTK_STATE_NORMAL],
87 harbaum 231 icon_get(ICON_MISC, context->appdata->compass_locked?0:1),
88 harbaum 1 0, 0, (width-diameter)/2 + diameter/32,
89     (height+diameter)/2 - 16 - diameter/32 , 16, 16,
90     GDK_RGB_DITHER_NONE,0,0);
91    
92     /* don't update heading if the compass is locked */
93     if(!context->appdata->compass_locked) {
94     int i, valid = 0, cnt=0;
95     double x_sum = 0.0, y_sum = 0.0;
96    
97     /* shift heading buffer up one entry and add new value at entry 0 */
98     for(i=MAX_AVERAGE-1;i>0;i--)
99     context->gotoc.head_avg[i] = context->gotoc.head_avg[i-1];
100     context->gotoc.head_avg[0] = gps_get_heading(context->appdata)*M_PI/180.0;
101    
102     // printf("Damping = %d\n", context->appdata->compass_damping);
103     // printf("add heading %f\n", rad2deg(context->gotoc.head_avg[0]));
104    
105     /* determine number of valid entries */
106     for(i=0;i<MAX_AVERAGE && valid<context->appdata->compass_damping;i++)
107     if(!isnan(context->gotoc.head_avg[i]))
108     valid++;
109    
110     /* map back to angle if at least one value has been added */
111     if(valid) {
112     /* map all valid antries onto a circle */
113     for(i=0;i<MAX_AVERAGE && cnt<context->appdata->compass_damping;i++) {
114     if(!isnan(context->gotoc.head_avg[i])) {
115     float weight = 1.0 - ((float)(cnt++)/(float)valid);
116     printf("weight = %f * %f\n",
117     weight, rad2deg(context->gotoc.head_avg[i]));
118     x_sum += weight * sin(context->gotoc.head_avg[i]);
119     y_sum += weight * cos(context->gotoc.head_avg[i]);
120     }
121     }
122    
123     printf("%d valid heading entries\n", valid);
124     context->gotoc.heading = atan2(x_sum, y_sum);
125     printf("averaged heading: %f\n",
126     rad2deg(context->gotoc.heading));
127     } else {
128     // printf("no valid heading, keeping old value heading\n");
129     }
130     }
131    
132     if(!isnan(context->gotoc.heading)) {
133    
134     for(i=0,f=0;f<2*M_PI-M_PI/8;f+=M_PI/4,i++) {
135     float ang = f - context->gotoc.heading;
136    
137     if(!(i&1)) {
138     /* draw diamonds */
139     GdkPoint diamond[4];
140    
141     #define OUT (1.0-LETTER_SPACE)
142    
143     diamond[0].x = xcenter + radius * OUT * sin(ang);
144     diamond[0].y = ycenter + radius * OUT * -cos(ang);
145    
146     diamond[1].x = xcenter + radius * (OUT-DIAMOND_HEIGHT/2) *
147     sin(ang+DIAMOND_WIDTH);
148     diamond[1].y = ycenter + radius * (OUT-DIAMOND_HEIGHT/2)*
149     -cos(ang+DIAMOND_WIDTH);
150    
151     diamond[2].x = xcenter + radius * (OUT-DIAMOND_HEIGHT) * sin(ang);
152     diamond[2].y = ycenter + radius * (OUT-DIAMOND_HEIGHT) * -cos(ang);
153    
154     diamond[3].x = xcenter + radius * (OUT-DIAMOND_HEIGHT/2) *
155     sin(ang-DIAMOND_WIDTH);
156     diamond[3].y = ycenter + radius * (OUT-DIAMOND_HEIGHT/2) *
157     -cos(ang-DIAMOND_WIDTH);
158    
159     gdk_draw_polygon(context->gotoc.compass_pixmap,
160     widget->style->black_gc, TRUE,
161     diamond, sizeof(diamond)/sizeof(GdkPoint));
162    
163     const char *str[] = { "N", "E", "S", "W" };
164     PangoLayout *layout = gtk_widget_create_pango_layout(widget, _(str[i/2]));
165     int tw, th;
166     pango_layout_get_pixel_size(layout, &tw, &th);
167    
168     gdk_draw_layout(context->gotoc.compass_pixmap, widget->style->black_gc,
169     xcenter + radius * (1.0-LETTER_SPACE/2)*sin(ang) - tw/2,
170     ycenter + radius * (1.0-LETTER_SPACE/2)*-cos(ang) - th/2,
171     layout);
172    
173     g_object_unref(layout);
174     } else
175     gdk_draw_line(context->gotoc.compass_pixmap, widget->style->black_gc,
176     xcenter + radius * 0.9 * sin(ang),
177     ycenter + radius * 0.9 * -cos(ang),
178     xcenter + radius * 1.0 * sin(ang),
179     ycenter + radius * 1.0 * -cos(ang));
180     }
181    
182     /* draw arrow */
183    
184     /* setup required colors */
185     GdkGC *arrow_gc = gdk_gc_new(context->gotoc.compass_pixmap);
186     gdk_gc_copy(arrow_gc, widget->style->black_gc);
187     GdkColor arrow_color;
188     gdk_color_parse("#800000", &arrow_color);
189     gdk_gc_set_rgb_fg_color(arrow_gc, &arrow_color);
190    
191     GdkPoint arrow[4];
192    
193     pos_t *pos = gps_get_pos(context->appdata);
194 harbaum 47 if(pos && !isnan(pos->lat) && !isnan(pos->lon)) {
195 harbaum 1 context->appdata->gps = *pos; /* save position */
196    
197     float arot =
198     gpx_pos_get_bearing(*pos, context->gotoc.pos) *
199     M_PI/180 - context->gotoc.heading;
200    
201     arrow[0].x = xcenter + radius * ARROW_LENGTH * sin(arot);
202     arrow[0].y = ycenter + radius * ARROW_LENGTH * -cos(arot);
203    
204     arrow[1].x = xcenter + radius * -ARROW_LENGTH * sin(arot+ARROW_WIDTH);
205     arrow[1].y = ycenter + radius * -ARROW_LENGTH * -cos(arot+ARROW_WIDTH);
206    
207     arrow[2].x = xcenter + radius * -0.5 * ARROW_LENGTH * sin(arot);
208     arrow[2].y = ycenter + radius * -0.5 * ARROW_LENGTH * -cos(arot);
209    
210     arrow[3].x = xcenter + radius * -ARROW_LENGTH * sin(arot-ARROW_WIDTH);
211     arrow[3].y = ycenter + radius * -ARROW_LENGTH * -cos(arot-ARROW_WIDTH);
212    
213     gdk_draw_polygon(context->gotoc.compass_pixmap, arrow_gc, TRUE,
214     arrow, sizeof(arrow)/sizeof(GdkPoint));
215     } else {
216     PangoLayout *layout;
217    
218     if(context->appdata->use_gps)
219     layout = gtk_widget_create_pango_layout(widget, _("No fix"));
220     else
221     layout = gtk_widget_create_pango_layout(widget, _("GPS disabled"));
222    
223     int tw, th;
224     pango_layout_get_pixel_size(layout, &tw, &th);
225    
226     gdk_draw_layout(context->gotoc.compass_pixmap, widget->style->black_gc,
227     xcenter - tw/2, ycenter - th/2, layout);
228    
229     g_object_unref(layout);
230     }
231     }
232     }
233    
234     /* Create a new backing pixmap of the appropriate size */
235     static gint compass_configure_event(GtkWidget *widget,
236     GdkEventConfigure *event, gpointer data) {
237     cache_context_t *context = (cache_context_t*)data;
238    
239     if(context->gotoc.compass_pixmap)
240     gdk_pixmap_unref(context->gotoc.compass_pixmap);
241    
242     context->gotoc.compass_pixmap = gdk_pixmap_new(widget->window,
243     widget->allocation.width,
244     widget->allocation.height,
245     -1);
246     compass_draw(widget, context);
247     // goto_update(context);
248    
249     return TRUE;
250     }
251    
252     /* Redraw the screen from the backing pixmap */
253     static gint compass_expose_event(GtkWidget *widget, GdkEventExpose *event,
254     gpointer data) {
255     cache_context_t *context = (cache_context_t*)data;
256    
257     gdk_draw_pixmap(widget->window,
258     widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
259     context->gotoc.compass_pixmap,
260     event->area.x, event->area.y,
261     event->area.x, event->area.y,
262     event->area.width, event->area.height);
263    
264     return FALSE;
265     }
266    
267     static void sat_draw(GtkWidget *widget, cache_context_t *context) {
268     gint width = widget->allocation.width;
269     gint height = widget->allocation.height;
270    
271     /* erase background */
272     gdk_draw_rectangle(context->gotoc.sat_pixmap,
273     widget->style->bg_gc[GTK_STATE_NORMAL], TRUE,
274     0, 0, width, height);
275    
276     gps_sat_t *sat = gps_get_sats(context->appdata);
277     if(sat && sat->num) {
278     /* setup required colors */
279     GdkGC *used_gc = gdk_gc_new(context->gotoc.sat_pixmap);
280     gdk_gc_copy(used_gc, widget->style->black_gc);
281     GdkColor used_color;
282     gdk_color_parse("#008000", &used_color); // green
283     gdk_gc_set_rgb_fg_color(used_gc, &used_color);
284    
285     #define SAT_SPACING 3
286     int i, x;
287     int swid = (width-SAT_SPACING*(sat->num-1))/sat->num;
288    
289     /* as of xgps, a ss of 40 and more is "plenty" */
290     int max_ss = 40;
291     for(i=0;i<sat->num;i++)
292     if(sat->ss[i] > max_ss) sat->ss[i] = max_ss;
293    
294     if(swid > 40) {
295     swid = 40;
296     x = (width-sat->num*swid)/2;
297     } else
298     x = 0;
299    
300     for(i=0;i<sat->num;i++) {
301     char str[32];
302     #ifdef USE_MAEMO
303     snprintf(str, sizeof(str), "<span size=\"small\">%d</span>", sat->PRN[i]);
304     PangoLayout *layout = gtk_widget_create_pango_layout(widget, NULL);
305     pango_layout_set_markup(layout, str, strlen(str));
306     #else
307     snprintf(str, sizeof(str), "%d", sat->PRN[i]);
308     PangoLayout *layout = gtk_widget_create_pango_layout(widget, str);
309     #endif
310    
311     int tw, th;
312     pango_layout_get_pixel_size(layout, &tw, &th);
313 harbaum 47 gdk_draw_layout(context->gotoc.sat_pixmap,
314     widget->style->text_gc[GTK_STATE_NORMAL],
315 harbaum 1 x + swid/2 - tw/2, height - th, layout);
316    
317     g_object_unref(layout);
318    
319     int h = (height-th) * sat->ss[i] / max_ss;
320    
321     gdk_draw_rectangle(context->gotoc.sat_pixmap,
322 harbaum 47 sat->used[i]?used_gc:widget->style->fg_gc[GTK_STATE_NORMAL],
323     TRUE, x, height-h-th, swid, h);
324 harbaum 1
325     x += SAT_SPACING+swid;
326     }
327    
328     /* free sat infos */
329     free(sat->PRN);
330     free(sat->ss);
331     free(sat->used);
332     } else {
333 harbaum 47 PangoLayout *layout =
334     gtk_widget_create_pango_layout(widget, _("No SAT info"));
335 harbaum 1 int tw, th;
336     pango_layout_get_pixel_size(layout, &tw, &th);
337 harbaum 47 gdk_draw_layout(context->gotoc.sat_pixmap,
338     widget->style->text_gc[GTK_STATE_NORMAL],
339 harbaum 1 (width - tw)/2, (height - th)/2, layout);
340    
341     g_object_unref(layout);
342     }
343    
344     /* free the sat structure */
345     if(sat)
346     free(sat);
347     }
348    
349     /* Create a new backing pixmap of the appropriate size */
350     static gint sat_configure_event(GtkWidget *widget, GdkEventConfigure *event,
351     gpointer data) {
352     cache_context_t *context = (cache_context_t*)data;
353    
354     if(context->gotoc.sat_pixmap)
355     gdk_pixmap_unref(context->gotoc.sat_pixmap);
356    
357     context->gotoc.sat_pixmap = gdk_pixmap_new(widget->window,
358     widget->allocation.width,
359     widget->allocation.height,
360     -1);
361     sat_draw(widget, context);
362    
363     return TRUE;
364     }
365    
366     /* Redraw the screen from the backing pixmap */
367     static gint sat_expose_event(GtkWidget *widget, GdkEventExpose *event,
368     gpointer data) {
369     cache_context_t *context = (cache_context_t*)data;
370    
371     gdk_draw_pixmap(widget->window,
372     widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
373     context->gotoc.sat_pixmap,
374     event->area.x, event->area.y,
375     event->area.x, event->area.y,
376     event->area.width, event->area.height);
377    
378     return FALSE;
379     }
380    
381     gint goto_destroy_event(GtkWidget *widget, gpointer data ) {
382     cache_context_t *context = (cache_context_t*)data;
383    
384     printf("destroying goto view\n");
385    
386     /* stop timer */
387     if(context->gotoc.handler_id)
388     gtk_timeout_remove(context->gotoc.handler_id);
389    
390     return FALSE;
391     }
392    
393     static gboolean goto_update(gpointer data) {
394     cache_context_t *context = (cache_context_t*)data;
395    
396     if(context->gotoc.sat_pixmap) {
397     static int sub = 0;
398    
399     if(!sub) {
400     /* draw sat view */
401     sat_draw(context->gotoc.sat_area, context);
402     gtk_widget_queue_draw_area(context->gotoc.sat_area, 0,0,
403     context->gotoc.sat_area->allocation.width,
404     context->gotoc.sat_area->allocation.height);
405     }
406    
407     if(sub++ == 5) sub = 0;
408     }
409    
410     if(context->gotoc.compass_pixmap) {
411     /* draw compass */
412     compass_draw(context->gotoc.compass_area, context);
413     gtk_widget_queue_draw_area(context->gotoc.compass_area, 0,0,
414     context->gotoc.compass_area->allocation.width,
415     context->gotoc.compass_area->allocation.height);
416     }
417    
418     pos_t *pos = gps_get_pos(context->appdata);
419 harbaum 47 if(pos && !isnan(pos->lat) && !isnan(pos->lon) &&
420     !isnan(context->gotoc.pos.lat) && !isnan(context->gotoc.pos.lon)) {
421 harbaum 1 char str[16];
422     gpx_pos_get_distance_str(str, sizeof(str),
423     *pos, context->gotoc.pos,
424     context->appdata->imperial);
425     gtk_label_set_text(GTK_LABEL(context->gotoc.distance_label), str);
426    
427     snprintf(str, sizeof(str), _("%.1f°"),
428     gpx_pos_get_bearing(*pos, context->gotoc.pos));
429     gtk_label_set_text(GTK_LABEL(context->gotoc.bearing_label), str);
430     } else {
431     gtk_label_set_text(GTK_LABEL(context->gotoc.distance_label), "-----");
432     gtk_label_set_text(GTK_LABEL(context->gotoc.bearing_label), "-----");
433     }
434    
435 harbaum 53 float eph = gps_get_eph(context->appdata);
436     if(isnan(eph))
437     gtk_label_set_text(GTK_LABEL(context->gotoc.eph_label), "-----");
438 harbaum 1 else {
439     char str[16];
440 harbaum 53 /* distance needs to be given in km */
441     if(context->appdata->imperial)
442     eph /= (6371.0/3959.0); // km to miles
443    
444     distance_str(str, sizeof(str), eph/1000.0, context->appdata->imperial);
445     gtk_label_set_text(GTK_LABEL(context->gotoc.eph_label), str);
446 harbaum 1 }
447    
448     return TRUE; // fire again
449     }
450    
451     static gboolean compass_clicked_event(GtkWidget *widget, GdkEventButton *event,
452     gpointer user_data) {
453     cache_context_t *context = (cache_context_t*)user_data;
454    
455     context->appdata->compass_locked = !context->appdata->compass_locked;
456    
457     printf("compass is now %slocked\n",
458     context->appdata->compass_locked?"":"un");
459    
460     if(context->gotoc.compass_pixmap) {
461     /* draw compass */
462     compass_draw(context->gotoc.compass_area, context);
463     gtk_widget_queue_draw_area(context->gotoc.compass_area, 0,0,
464     context->gotoc.compass_area->allocation.width,
465     context->gotoc.compass_area->allocation.height);
466     }
467     return FALSE;
468     }
469    
470 harbaum 214 static void pos_modified(GtkWidget *widget, gpointer data ) {
471     cache_context_t *context = (cache_context_t*)data;
472    
473     /* extract position from entries */
474 harbaum 221 context->gotoc.pos.lat = lat_entry_get(context->gotoc.lat_entry);
475     context->gotoc.pos.lon = lon_entry_get(context->gotoc.lon_entry);
476 harbaum 214
477     goto_update(context);
478     }
479    
480 harbaum 1 GtkWidget *goto_cache(cache_context_t *context) {
481     int i;
482    
483     /* clear list used for averaging */
484     for(i=0;i<MAX_AVERAGE;i++)
485     context->gotoc.head_avg[i] = NAN;
486    
487     context->gotoc.pos = gpx_cache_pos(context->cache);
488    
489 harbaum 229 GtkWidget *hbox = gtk_hbox_new(FALSE, 32);
490 harbaum 1
491     context->gotoc.compass_area = gtk_drawing_area_new();
492     gtk_drawing_area_size(GTK_DRAWING_AREA(context->gotoc.compass_area),
493     COMPASS_SIZE, COMPASS_SIZE);
494    
495     gtk_signal_connect(GTK_OBJECT(context->gotoc.compass_area), "expose_event",
496     (GtkSignalFunc)compass_expose_event, context);
497     gtk_signal_connect(GTK_OBJECT(context->gotoc.compass_area),"configure_event",
498     (GtkSignalFunc)compass_configure_event, context);
499     gtk_signal_connect(GTK_OBJECT(context->gotoc.compass_area),
500     "button_press_event",
501     (GtkSignalFunc)compass_clicked_event, context);
502    
503     gtk_widget_set_events(context->gotoc.compass_area, GDK_EXPOSURE_MASK);
504     gtk_widget_add_events(context->gotoc.compass_area, GDK_BUTTON_PRESS_MASK);
505     gtk_box_pack_start_defaults(GTK_BOX(hbox), context->gotoc.compass_area);
506    
507     GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
508 harbaum 214 GtkWidget *table = gtk_table_new(5, 3, FALSE);
509 harbaum 1
510 harbaum 214 /* ---------- destination coordinates ------- */
511 harbaum 1
512 harbaum 214 /* SIZE_SMALL doesn't work here as setting the label returns to normal */
513     gtk_table_attach_defaults(GTK_TABLE(table), left_label_new(_("Latitude:")), 0,1,0,1);
514     context->gotoc.lat_entry = lat_entry_new(context->gotoc.pos.lat);
515     gtk_table_attach_defaults(GTK_TABLE(table), context->gotoc.lat_entry, 1,2,0,1);
516     gtk_table_attach_defaults(GTK_TABLE(table), left_label_new(_("Longitude:")), 0,1,1,2);
517     context->gotoc.lon_entry = lon_entry_new(context->gotoc.pos.lon);
518     gtk_table_attach_defaults(GTK_TABLE(table), context->gotoc.lon_entry, 1,2,1,2);
519 harbaum 1
520 harbaum 214 g_signal_connect(G_OBJECT(context->gotoc.lat_entry), "changed",
521     G_CALLBACK(pos_modified), context);
522     g_signal_connect(G_OBJECT(context->gotoc.lon_entry), "changed",
523     G_CALLBACK(pos_modified), context);
524 harbaum 1
525 harbaum 231 gtk_table_attach_defaults(GTK_TABLE(table), preset_coordinate_picker(context->appdata,
526     context->gotoc.lat_entry, context->gotoc.lon_entry), 2,3,0,1);
527 harbaum 1
528 harbaum 231 gtk_table_attach_defaults(GTK_TABLE(table), goto_coordinate(context->appdata,
529     context->gotoc.lat_entry, context->gotoc.lon_entry), 2,3,1,2);
530    
531 harbaum 214 gtk_table_set_row_spacing(GTK_TABLE(table), 1, 16);
532     gtk_table_set_col_spacing(GTK_TABLE(table), 0, 16);
533 harbaum 1
534     /* -------------- distance label ------------------------- */
535 harbaum 214 gtk_table_attach_defaults(GTK_TABLE(table), left_label_new(_("Distance:")), 0,1,2,3);
536 harbaum 1 gtk_table_attach_defaults(GTK_TABLE(table),
537 harbaum 233 (context->gotoc.distance_label = gtk_label_new("-----")), 1,2,2,3);
538 harbaum 1
539     /* -------------- bearing label ------------------------- */
540 harbaum 214 gtk_table_attach_defaults(GTK_TABLE(table), left_label_new(_("Bearing:")), 0,1,3,4);
541 harbaum 1 gtk_table_attach_defaults(GTK_TABLE(table),
542 harbaum 233 (context->gotoc.bearing_label = gtk_label_new("-----")), 1,2,3,4);
543 harbaum 1
544     /* -------------- error label ------------------------- */
545 harbaum 214 gtk_table_attach_defaults(GTK_TABLE(table), left_label_new(_("Est. error:")), 0,1,4,5);
546 harbaum 1 gtk_table_attach_defaults(GTK_TABLE(table),
547 harbaum 233 (context->gotoc.eph_label = gtk_label_new("-----")), 1,2,4,5);
548 harbaum 1
549 harbaum 214 gtk_table_set_row_spacing(GTK_TABLE(table), 4, 16);
550 harbaum 1
551     /* -------------- sat view box ------------------------- */
552     GtkWidget *ihbox = gtk_hbox_new(FALSE,0);
553    
554     context->gotoc.sat_area = gtk_drawing_area_new();
555     gtk_drawing_area_size(GTK_DRAWING_AREA(context->gotoc.sat_area),
556     SAT_WIDTH, SAT_HEIGHT);
557    
558     gtk_signal_connect(GTK_OBJECT(context->gotoc.sat_area), "expose_event",
559     (GtkSignalFunc)sat_expose_event, context);
560     gtk_signal_connect(GTK_OBJECT(context->gotoc.sat_area),"configure_event",
561     (GtkSignalFunc)sat_configure_event, context);
562    
563     gtk_widget_set_events(context->gotoc.sat_area, GDK_EXPOSURE_MASK);
564    
565     gtk_box_pack_start(GTK_BOX(ihbox), context->gotoc.sat_area, 1,0,0);
566    
567 harbaum 214 gtk_table_attach_defaults(GTK_TABLE(table), ihbox, 0,3,5,6);
568 harbaum 1
569     /* ------------------------------------------------------- */
570    
571 harbaum 229 gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, FALSE, 0);
572     gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
573 harbaum 1
574 harbaum 214 context->gotoc.handler_id =
575     gtk_timeout_add(UPDATE_MS, goto_update, context);
576 harbaum 1
577     return hbox;
578     }
579    
580     void goto_coordinate_update(cache_context_t *context) {
581 harbaum 214 static pos_t pos = { 0.0, 0.0 };
582    
583 harbaum 1 if(!context->notes.modified)
584     return;
585 harbaum 214
586     pos_t npos = notes_get_pos(context);
587     if(pos_differ(&npos, &pos)) {
588     pos = npos;
589    
590 harbaum 221 lat_entry_set(context->gotoc.lat_entry, npos.lat);
591     lon_entry_set(context->gotoc.lon_entry, npos.lon);
592 harbaum 214 }
593 harbaum 1 }