--- trunk/src/goto.c 2010/01/21 21:18:33 249 +++ trunk/src/goto.c 2010/06/07 19:19:50 288 @@ -125,6 +125,8 @@ float f; int i; + cairo_t *cr = gdk_cairo_create(context->gotoc.compass_pixmap); + gint width = widget->allocation.width; gint height = widget->allocation.height; gint diameter = (height < width)?height:width; @@ -145,20 +147,12 @@ widget->style->bg[GTK_STATE_NORMAL].green + widget->style->bg[GTK_STATE_NORMAL].blue < 3*60000) { /* background is very bright, use white */ - gdk_draw_arc(context->gotoc.compass_pixmap, widget->style->white_gc, TRUE, - (width-diameter)/2, (height-diameter)/2, diameter, diameter, - 0, 360*64); - } else { - GdkGC *lgrey_gc = gdk_gc_new(context->gotoc.compass_pixmap); - gdk_gc_copy(lgrey_gc, widget->style->black_gc); - GdkColor lgrey_color; - gdk_color_parse("#DDDDDD", &lgrey_color); - gdk_gc_set_rgb_fg_color(lgrey_gc, &lgrey_color); - - gdk_draw_arc(context->gotoc.compass_pixmap, lgrey_gc, TRUE, - (width-diameter)/2, (height-diameter)/2, diameter, diameter, - 0, 360*64); - } + cairo_set_source_rgb(cr, 1, 1, 1); + } else + cairo_set_source_rgb(cr, 0.87, 0.87, 0.87); + + cairo_arc(cr, width/2, height/2, diameter/2, 0, 2 * M_PI); + cairo_fill(cr); /* draw the locked/unlocked icon */ gdk_draw_pixbuf(context->gotoc.compass_pixmap, @@ -210,37 +204,71 @@ if(!isnan(context->gotoc.heading)) { + /* --------------------------- draw sun ---------------------- */ + float sun_az = astro_get_sun_azimuth(context->appdata); + if(!isnan(sun_az)) { + float sang = sun_az - context->gotoc.heading; + + cairo_set_source_rgb(cr, 1.0, 0.8, 0.0); + + int sd = diameter/6; + int sx = xcenter + (diameter/2 - sd/2) * sin(sang); + int sy = ycenter - (diameter/2 - sd/2) * cos(sang); + + int scd = 0.6*sd; + + cairo_arc (cr, sx, sy, scd/2, 0, 2 * M_PI); + cairo_fill(cr); + + /* draw sun rays */ + for(f=0;f<2*M_PI-M_PI/8;f+=M_PI/4) { + float ang = f - context->gotoc.heading; + + cairo_move_to(cr, sx + sd * 0.5 * sin(ang), + sy + sd * 0.5 * -cos(ang)); + + cairo_line_to(cr, sx + sd * 0.2 * sin(ang+0.5), + sy + sd * 0.2 * -cos(ang+0.5)); + + cairo_line_to(cr, sx + sd * 0.2 * sin(ang-0.5), + sy + sd * 0.2 * -cos(ang-0.5)); + + cairo_close_path (cr); + cairo_fill(cr); + } + } + + /* ---------------- draw markers -------------------- */ + cairo_set_source_rgb(cr, 0, 0, 0); + for(i=0,f=0;f<2*M_PI-M_PI/8;f+=M_PI/4,i++) { float ang = f - context->gotoc.heading; if(!(i&1)) { - /* draw diamonds */ - GdkPoint diamond[4]; - #define OUT (1.0-LETTER_SPACE) - diamond[0].x = xcenter + radius * OUT * sin(ang); - diamond[0].y = ycenter + radius * OUT * -cos(ang); + cairo_move_to(cr, xcenter + radius * OUT * sin(ang), + ycenter + radius * OUT * -cos(ang)); + + cairo_line_to(cr, xcenter + radius * (OUT-DIAMOND_HEIGHT/2) * + sin(ang+DIAMOND_WIDTH), + ycenter + radius * (OUT-DIAMOND_HEIGHT/2)* + -cos(ang+DIAMOND_WIDTH)); - diamond[1].x = xcenter + radius * (OUT-DIAMOND_HEIGHT/2) * - sin(ang+DIAMOND_WIDTH); - diamond[1].y = ycenter + radius * (OUT-DIAMOND_HEIGHT/2)* - -cos(ang+DIAMOND_WIDTH); - - diamond[2].x = xcenter + radius * (OUT-DIAMOND_HEIGHT) * sin(ang); - diamond[2].y = ycenter + radius * (OUT-DIAMOND_HEIGHT) * -cos(ang); - - diamond[3].x = xcenter + radius * (OUT-DIAMOND_HEIGHT/2) * - sin(ang-DIAMOND_WIDTH); - diamond[3].y = ycenter + radius * (OUT-DIAMOND_HEIGHT/2) * - -cos(ang-DIAMOND_WIDTH); - - gdk_draw_polygon(context->gotoc.compass_pixmap, - widget->style->black_gc, TRUE, - diamond, sizeof(diamond)/sizeof(GdkPoint)); + cairo_line_to(cr, xcenter + radius * (OUT-DIAMOND_HEIGHT) * sin(ang), + ycenter + radius * (OUT-DIAMOND_HEIGHT) * -cos(ang)); + + cairo_line_to(cr, xcenter + radius * (OUT-DIAMOND_HEIGHT/2) * + sin(ang-DIAMOND_WIDTH), + ycenter + radius * (OUT-DIAMOND_HEIGHT/2) * + -cos(ang-DIAMOND_WIDTH)); + + cairo_close_path (cr); + cairo_fill(cr); const char *str[] = { "N", "E", "S", "W" }; - PangoLayout *layout = gtk_widget_create_pango_layout(widget, _(str[i/2])); + PangoLayout *layout = + gtk_widget_create_pango_layout(widget, _(str[i/2])); int tw, th; pango_layout_get_pixel_size(layout, &tw, &th); @@ -250,47 +278,43 @@ layout); g_object_unref(layout); - } else - gdk_draw_line(context->gotoc.compass_pixmap, widget->style->black_gc, - xcenter + radius * 0.9 * sin(ang), - ycenter + radius * 0.9 * -cos(ang), - xcenter + radius * 1.0 * sin(ang), - ycenter + radius * 1.0 * -cos(ang)); + } else { + cairo_move_to(cr, xcenter + radius * 0.9 * sin(ang), + ycenter + radius * 0.9 * -cos(ang)); + + cairo_line_to(cr, xcenter + radius * 1.0 * sin(ang), + ycenter + radius * 1.0 * -cos(ang)); + + cairo_stroke(cr); + } } - /* draw arrow */ - - /* setup required colors */ - GdkGC *arrow_gc = gdk_gc_new(context->gotoc.compass_pixmap); - gdk_gc_copy(arrow_gc, widget->style->black_gc); - GdkColor arrow_color; - gdk_color_parse("#800000", &arrow_color); - gdk_gc_set_rgb_fg_color(arrow_gc, &arrow_color); - - GdkPoint arrow[4]; + /* --------------------------- draw arrow ---------------------- */ pos_t *pos = gps_get_pos(context->appdata); if(pos && !isnan(pos->lat) && !isnan(pos->lon)) { - context->appdata->gps = *pos; /* save position */ + context->appdata->gps.saved = *pos; /* save position */ float arot = gpx_pos_get_bearing(*pos, context->gotoc.pos) * M_PI/180 - context->gotoc.heading; - arrow[0].x = xcenter + radius * ARROW_LENGTH * sin(arot); - arrow[0].y = ycenter + radius * ARROW_LENGTH * -cos(arot); + cairo_move_to(cr, xcenter + radius * ARROW_LENGTH * sin(arot), + ycenter + radius * ARROW_LENGTH * -cos(arot)); - arrow[1].x = xcenter + radius * -ARROW_LENGTH * sin(arot+ARROW_WIDTH); - arrow[1].y = ycenter + radius * -ARROW_LENGTH * -cos(arot+ARROW_WIDTH); + cairo_line_to(cr, xcenter + radius * -ARROW_LENGTH * sin(arot+ARROW_WIDTH), + ycenter + radius * -ARROW_LENGTH * -cos(arot+ARROW_WIDTH)); - arrow[2].x = xcenter + radius * -0.5 * ARROW_LENGTH * sin(arot); - arrow[2].y = ycenter + radius * -0.5 * ARROW_LENGTH * -cos(arot); + cairo_line_to(cr, xcenter + radius * -0.5 * ARROW_LENGTH * sin(arot), + ycenter + radius * -0.5 * ARROW_LENGTH * -cos(arot)); - arrow[3].x = xcenter + radius * -ARROW_LENGTH * sin(arot-ARROW_WIDTH); - arrow[3].y = ycenter + radius * -ARROW_LENGTH * -cos(arot-ARROW_WIDTH); + cairo_line_to(cr, xcenter + radius * -ARROW_LENGTH * sin(arot-ARROW_WIDTH), + ycenter + radius * -ARROW_LENGTH * -cos(arot-ARROW_WIDTH)); - gdk_draw_polygon(context->gotoc.compass_pixmap, arrow_gc, TRUE, - arrow, sizeof(arrow)/sizeof(GdkPoint)); + cairo_set_source_rgb(cr, 0.5, 0.0, 0.0); + cairo_close_path (cr); + cairo_fill(cr); + } else { PangoLayout *layout; @@ -308,6 +332,7 @@ g_object_unref(layout); } } + cairo_destroy(cr); } /* Create a new backing pixmap of the appropriate size */ @@ -353,7 +378,9 @@ 0, 0, width, height); gps_sat_t *sat = gps_get_sats(context->appdata); - if(sat && sat->num) { + gint sat_num = gps_get_satnum(context->appdata); + + if(sat && sat_num) { /* setup required colors */ GdkGC *used_gc = gdk_gc_new(context->gotoc.sat_pixmap); gdk_gc_copy(used_gc, widget->style->black_gc); @@ -363,27 +390,27 @@ #define SAT_SPACING 3 int i, x; - int swid = (width-SAT_SPACING*(sat->num-1))/sat->num; + int swid = (width-SAT_SPACING*(sat_num-1))/sat_num; /* as of xgps, a ss of 40 and more is "plenty" */ int max_ss = 40; - for(i=0;inum;i++) - if(sat->ss[i] > max_ss) sat->ss[i] = max_ss; + for(i=0;i max_ss) sat[i].ss = max_ss; if(swid > 40) { swid = 40; - x = (width-sat->num*swid)/2; + x = (width-sat_num*swid)/2; } else x = 0; - for(i=0;inum;i++) { + for(i=0;i%d", sat->PRN[i]); + snprintf(str, sizeof(str), "%d", sat[i].prn); PangoLayout *layout = gtk_widget_create_pango_layout(widget, NULL); pango_layout_set_markup(layout, str, strlen(str)); #else - snprintf(str, sizeof(str), "%d", sat->PRN[i]); + snprintf(str, sizeof(str), "%d", sat[i].prn); PangoLayout *layout = gtk_widget_create_pango_layout(widget, str); #endif @@ -395,19 +422,15 @@ g_object_unref(layout); - int h = (height-th) * sat->ss[i] / max_ss; + int h = (height-th) * sat[i].ss / max_ss; gdk_draw_rectangle(context->gotoc.sat_pixmap, - sat->used[i]?used_gc:widget->style->fg_gc[GTK_STATE_NORMAL], + sat[i].used?used_gc:widget->style->fg_gc[GTK_STATE_NORMAL], TRUE, x, height-h-th, swid, h); x += SAT_SPACING+swid; } - /* free sat infos */ - free(sat->PRN); - free(sat->ss); - free(sat->used); } else { PangoLayout *layout = gtk_widget_create_pango_layout(widget, _("No SAT info")); @@ -419,10 +442,6 @@ g_object_unref(layout); } - - /* free the sat structure */ - if(sat) - free(sat); } /* Create a new backing pixmap of the appropriate size */ @@ -574,6 +593,7 @@ } #endif +/* create "goto" tab */ GtkWidget *goto_cache(cache_context_t *context) { int i; @@ -583,7 +603,7 @@ context->gotoc.pos = gpx_cache_pos(context->cache); - GtkWidget *hbox = gtk_hbox_new(FALSE, 32); + GtkWidget *hbox = portrait_box_new(FALSE, 32); context->gotoc.compass_area = gtk_drawing_area_new(); gtk_drawing_area_size(GTK_DRAWING_AREA(context->gotoc.compass_area),