125 |
float f; |
float f; |
126 |
int i; |
int i; |
127 |
|
|
128 |
|
cairo_t *cr = gdk_cairo_create(context->gotoc.compass_pixmap); |
129 |
|
|
130 |
gint width = widget->allocation.width; |
gint width = widget->allocation.width; |
131 |
gint height = widget->allocation.height; |
gint height = widget->allocation.height; |
132 |
gint diameter = (height < width)?height:width; |
gint diameter = (height < width)?height:width; |
147 |
widget->style->bg[GTK_STATE_NORMAL].green + |
widget->style->bg[GTK_STATE_NORMAL].green + |
148 |
widget->style->bg[GTK_STATE_NORMAL].blue < 3*60000) { |
widget->style->bg[GTK_STATE_NORMAL].blue < 3*60000) { |
149 |
/* background is very bright, use white */ |
/* background is very bright, use white */ |
150 |
gdk_draw_arc(context->gotoc.compass_pixmap, widget->style->white_gc, TRUE, |
cairo_set_source_rgb(cr, 1, 1, 1); |
151 |
(width-diameter)/2, (height-diameter)/2, diameter, diameter, |
} else |
152 |
0, 360*64); |
cairo_set_source_rgb(cr, 0.87, 0.87, 0.87); |
153 |
} else { |
|
154 |
GdkGC *lgrey_gc = gdk_gc_new(context->gotoc.compass_pixmap); |
cairo_arc(cr, width/2, height/2, diameter/2, 0, 2 * M_PI); |
155 |
gdk_gc_copy(lgrey_gc, widget->style->black_gc); |
cairo_fill(cr); |
|
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); |
|
|
} |
|
156 |
|
|
157 |
/* draw the locked/unlocked icon */ |
/* draw the locked/unlocked icon */ |
158 |
gdk_draw_pixbuf(context->gotoc.compass_pixmap, |
gdk_draw_pixbuf(context->gotoc.compass_pixmap, |
204 |
|
|
205 |
if(!isnan(context->gotoc.heading)) { |
if(!isnan(context->gotoc.heading)) { |
206 |
|
|
207 |
|
/* --------------------------- draw sun ---------------------- */ |
208 |
|
float sun_az = astro_get_sun_azimuth(context->appdata); |
209 |
|
if(!isnan(sun_az)) { |
210 |
|
float sang = sun_az - context->gotoc.heading; |
211 |
|
|
212 |
|
cairo_set_source_rgb(cr, 1.0, 0.8, 0.0); |
213 |
|
|
214 |
|
int sd = diameter/6; |
215 |
|
int sx = xcenter + (diameter/2 - sd/2) * sin(sang); |
216 |
|
int sy = ycenter - (diameter/2 - sd/2) * cos(sang); |
217 |
|
|
218 |
|
int scd = 0.6*sd; |
219 |
|
|
220 |
|
cairo_arc (cr, sx, sy, scd/2, 0, 2 * M_PI); |
221 |
|
cairo_fill(cr); |
222 |
|
|
223 |
|
/* draw sun rays */ |
224 |
|
for(f=0;f<2*M_PI-M_PI/8;f+=M_PI/4) { |
225 |
|
float ang = f - context->gotoc.heading; |
226 |
|
|
227 |
|
cairo_move_to(cr, sx + sd * 0.5 * sin(ang), |
228 |
|
sy + sd * 0.5 * -cos(ang)); |
229 |
|
|
230 |
|
cairo_line_to(cr, sx + sd * 0.2 * sin(ang+0.5), |
231 |
|
sy + sd * 0.2 * -cos(ang+0.5)); |
232 |
|
|
233 |
|
cairo_line_to(cr, sx + sd * 0.2 * sin(ang-0.5), |
234 |
|
sy + sd * 0.2 * -cos(ang-0.5)); |
235 |
|
|
236 |
|
cairo_close_path (cr); |
237 |
|
cairo_fill(cr); |
238 |
|
} |
239 |
|
} |
240 |
|
|
241 |
|
/* ---------------- draw markers -------------------- */ |
242 |
|
cairo_set_source_rgb(cr, 0, 0, 0); |
243 |
|
|
244 |
for(i=0,f=0;f<2*M_PI-M_PI/8;f+=M_PI/4,i++) { |
for(i=0,f=0;f<2*M_PI-M_PI/8;f+=M_PI/4,i++) { |
245 |
float ang = f - context->gotoc.heading; |
float ang = f - context->gotoc.heading; |
246 |
|
|
247 |
if(!(i&1)) { |
if(!(i&1)) { |
|
/* draw diamonds */ |
|
|
GdkPoint diamond[4]; |
|
|
|
|
248 |
#define OUT (1.0-LETTER_SPACE) |
#define OUT (1.0-LETTER_SPACE) |
249 |
|
|
250 |
diamond[0].x = xcenter + radius * OUT * sin(ang); |
cairo_move_to(cr, xcenter + radius * OUT * sin(ang), |
251 |
diamond[0].y = ycenter + radius * OUT * -cos(ang); |
ycenter + radius * OUT * -cos(ang)); |
252 |
|
|
253 |
|
cairo_line_to(cr, xcenter + radius * (OUT-DIAMOND_HEIGHT/2) * |
254 |
|
sin(ang+DIAMOND_WIDTH), |
255 |
|
ycenter + radius * (OUT-DIAMOND_HEIGHT/2)* |
256 |
|
-cos(ang+DIAMOND_WIDTH)); |
257 |
|
|
258 |
|
cairo_line_to(cr, xcenter + radius * (OUT-DIAMOND_HEIGHT) * sin(ang), |
259 |
|
ycenter + radius * (OUT-DIAMOND_HEIGHT) * -cos(ang)); |
260 |
|
|
261 |
|
cairo_line_to(cr, xcenter + radius * (OUT-DIAMOND_HEIGHT/2) * |
262 |
|
sin(ang-DIAMOND_WIDTH), |
263 |
|
ycenter + radius * (OUT-DIAMOND_HEIGHT/2) * |
264 |
|
-cos(ang-DIAMOND_WIDTH)); |
265 |
|
|
266 |
diamond[1].x = xcenter + radius * (OUT-DIAMOND_HEIGHT/2) * |
cairo_close_path (cr); |
267 |
sin(ang+DIAMOND_WIDTH); |
cairo_fill(cr); |
|
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)); |
|
268 |
|
|
269 |
const char *str[] = { "N", "E", "S", "W" }; |
const char *str[] = { "N", "E", "S", "W" }; |
270 |
PangoLayout *layout = gtk_widget_create_pango_layout(widget, _(str[i/2])); |
PangoLayout *layout = |
271 |
|
gtk_widget_create_pango_layout(widget, _(str[i/2])); |
272 |
int tw, th; |
int tw, th; |
273 |
pango_layout_get_pixel_size(layout, &tw, &th); |
pango_layout_get_pixel_size(layout, &tw, &th); |
274 |
|
|
278 |
layout); |
layout); |
279 |
|
|
280 |
g_object_unref(layout); |
g_object_unref(layout); |
281 |
} else |
} else { |
282 |
gdk_draw_line(context->gotoc.compass_pixmap, widget->style->black_gc, |
cairo_move_to(cr, xcenter + radius * 0.9 * sin(ang), |
283 |
xcenter + radius * 0.9 * sin(ang), |
ycenter + radius * 0.9 * -cos(ang)); |
284 |
ycenter + radius * 0.9 * -cos(ang), |
|
285 |
xcenter + radius * 1.0 * sin(ang), |
cairo_line_to(cr, xcenter + radius * 1.0 * sin(ang), |
286 |
ycenter + radius * 1.0 * -cos(ang)); |
ycenter + radius * 1.0 * -cos(ang)); |
287 |
|
|
288 |
|
cairo_stroke(cr); |
289 |
|
} |
290 |
} |
} |
291 |
|
|
292 |
/* draw arrow */ |
/* --------------------------- 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]; |
|
293 |
|
|
294 |
pos_t *pos = gps_get_pos(context->appdata); |
pos_t *pos = gps_get_pos(context->appdata); |
295 |
if(pos && !isnan(pos->lat) && !isnan(pos->lon)) { |
if(pos && !isnan(pos->lat) && !isnan(pos->lon)) { |
299 |
gpx_pos_get_bearing(*pos, context->gotoc.pos) * |
gpx_pos_get_bearing(*pos, context->gotoc.pos) * |
300 |
M_PI/180 - context->gotoc.heading; |
M_PI/180 - context->gotoc.heading; |
301 |
|
|
302 |
arrow[0].x = xcenter + radius * ARROW_LENGTH * sin(arot); |
cairo_move_to(cr, xcenter + radius * ARROW_LENGTH * sin(arot), |
303 |
arrow[0].y = ycenter + radius * ARROW_LENGTH * -cos(arot); |
ycenter + radius * ARROW_LENGTH * -cos(arot)); |
304 |
|
|
305 |
arrow[1].x = xcenter + radius * -ARROW_LENGTH * sin(arot+ARROW_WIDTH); |
cairo_line_to(cr, xcenter + radius * -ARROW_LENGTH * sin(arot+ARROW_WIDTH), |
306 |
arrow[1].y = ycenter + radius * -ARROW_LENGTH * -cos(arot+ARROW_WIDTH); |
ycenter + radius * -ARROW_LENGTH * -cos(arot+ARROW_WIDTH)); |
307 |
|
|
308 |
arrow[2].x = xcenter + radius * -0.5 * ARROW_LENGTH * sin(arot); |
cairo_line_to(cr, xcenter + radius * -0.5 * ARROW_LENGTH * sin(arot), |
309 |
arrow[2].y = ycenter + radius * -0.5 * ARROW_LENGTH * -cos(arot); |
ycenter + radius * -0.5 * ARROW_LENGTH * -cos(arot)); |
310 |
|
|
311 |
arrow[3].x = xcenter + radius * -ARROW_LENGTH * sin(arot-ARROW_WIDTH); |
cairo_line_to(cr, xcenter + radius * -ARROW_LENGTH * sin(arot-ARROW_WIDTH), |
312 |
arrow[3].y = ycenter + radius * -ARROW_LENGTH * -cos(arot-ARROW_WIDTH); |
ycenter + radius * -ARROW_LENGTH * -cos(arot-ARROW_WIDTH)); |
313 |
|
|
314 |
gdk_draw_polygon(context->gotoc.compass_pixmap, arrow_gc, TRUE, |
cairo_set_source_rgb(cr, 0.5, 0.0, 0.0); |
315 |
arrow, sizeof(arrow)/sizeof(GdkPoint)); |
cairo_close_path (cr); |
316 |
|
cairo_fill(cr); |
317 |
|
|
318 |
} else { |
} else { |
319 |
PangoLayout *layout; |
PangoLayout *layout; |
320 |
|
|
332 |
g_object_unref(layout); |
g_object_unref(layout); |
333 |
} |
} |
334 |
} |
} |
335 |
|
cairo_destroy(cr); |
336 |
} |
} |
337 |
|
|
338 |
/* Create a new backing pixmap of the appropriate size */ |
/* Create a new backing pixmap of the appropriate size */ |