39 |
/* the offscreen representation of the OSD */ |
/* the offscreen representation of the OSD */ |
40 |
cairo_surface_t *overlay; |
cairo_surface_t *overlay; |
41 |
|
|
42 |
|
#ifdef OSD_SOURCE_SEL |
43 |
/* values to handle the "source" menu */ |
/* values to handle the "source" menu */ |
44 |
cairo_surface_t *map_source; |
cairo_surface_t *map_source; |
45 |
gboolean expanded; |
gboolean expanded; |
46 |
gint shift, dir, count; |
gint shift, dir, count; |
47 |
gint handler_id; |
gint handler_id; |
48 |
gint width, height; |
gint width, height; |
49 |
|
#endif |
50 |
|
|
51 |
} osd_priv_t; |
} osd_priv_t; |
52 |
|
|
260 |
return OSD_NONE; |
return OSD_NONE; |
261 |
} |
} |
262 |
|
|
263 |
|
#ifdef OSD_SOURCE_SEL |
264 |
|
|
265 |
/* place source selection at right border */ |
/* place source selection at right border */ |
266 |
#define OSD_S_RAD (Z_RAD) |
#define OSD_S_RAD (Z_RAD) |
267 |
#define OSD_S_X (-OSD_X) |
#define OSD_S_X (-OSD_X) |
285 |
#define OSD_TEXT_BORDER (OSD_FONT_SIZE/2) |
#define OSD_TEXT_BORDER (OSD_FONT_SIZE/2) |
286 |
#define OSD_TEXT_SKIP (OSD_FONT_SIZE/8) |
#define OSD_TEXT_SKIP (OSD_FONT_SIZE/8) |
287 |
|
|
288 |
|
/* draw the shape of the source selection OSD, either only the puller (not expanded) */ |
289 |
|
/* or the entire menu incl. the puller (expanded) */ |
290 |
static void |
static void |
291 |
osd_source_shape(osd_priv_t *priv, cairo_t *cr, gint x, gint y) { |
osd_source_shape(osd_priv_t *priv, cairo_t *cr, gint x, gint y) { |
292 |
if(!priv->expanded) { |
if(!priv->expanded) { |
342 |
CAIRO_FONT_WEIGHT_BOLD); |
CAIRO_FONT_WEIGHT_BOLD); |
343 |
cairo_set_font_size (cr, OSD_FONT_SIZE); |
cairo_set_font_size (cr, OSD_FONT_SIZE); |
344 |
|
|
345 |
int i, step = (priv->height - 2*OSD_TEXT_BORDER) |
int i, step = (priv->height - 2*OSD_TEXT_BORDER) / |
346 |
/ OSM_GPS_MAP_SOURCE_LAST; |
OSM_GPS_MAP_SOURCE_LAST; |
347 |
for(i=OSM_GPS_MAP_SOURCE_NULL+1;i<=OSM_GPS_MAP_SOURCE_LAST;i++) { |
for(i=OSM_GPS_MAP_SOURCE_NULL+1;i<=OSM_GPS_MAP_SOURCE_LAST;i++) { |
348 |
cairo_text_extents_t extents; |
cairo_text_extents_t extents; |
349 |
const char *src = osm_gps_map_source_get_friendly_name(i); |
const char *src = osm_gps_map_source_get_friendly_name(i); |
431 |
cairo_destroy(cr); |
cairo_destroy(cr); |
432 |
} |
} |
433 |
|
|
434 |
|
/* re-allocate the buffer used to draw the menu. This is used */ |
435 |
|
/* to collapse/expand the buffer */ |
436 |
static void |
static void |
437 |
osd_source_reallocate(osm_gps_map_osd_t *osd) { |
osd_source_reallocate(osm_gps_map_osd_t *osd) { |
438 |
osd_priv_t *priv = (osd_priv_t*)osd->priv; |
osd_priv_t *priv = (osd_priv_t*)osd->priv; |
458 |
const char *src = osm_gps_map_source_get_friendly_name(i); |
const char *src = osm_gps_map_source_get_friendly_name(i); |
459 |
cairo_text_extents (cr, src, &extents); |
cairo_text_extents (cr, src, &extents); |
460 |
|
|
|
// printf("Source %d: %s = %f %f\n", i, src, |
|
|
// extents.width, extents.height); |
|
|
|
|
461 |
if(extents.width > max_w) max_w = extents.width; |
if(extents.width > max_w) max_w = extents.width; |
462 |
if(extents.height > max_h) max_h = extents.height; |
if(extents.height > max_h) max_h = extents.height; |
463 |
} |
} |
508 |
|
|
509 |
/* count runs linearly from 0 to 1000, map this nicely onto a position */ |
/* count runs linearly from 0 to 1000, map this nicely onto a position */ |
510 |
|
|
|
/* simple linear mapping */ |
|
|
// priv->shift = (osd->widget->allocation.width - OSD_S_EXP_W + OSD_S_X) + |
|
|
// (diff * priv->count)/1000; |
|
|
|
|
511 |
/* nicer sinoid mapping */ |
/* nicer sinoid mapping */ |
512 |
float m = 0.5-cos(priv->count * M_PI / 1000.0)/2; |
float m = 0.5-cos(priv->count * M_PI / 1000.0)/2; |
513 |
priv->shift = (osd->widget->allocation.width - OSD_S_EXP_W + OSD_S_X) + |
priv->shift = (osd->widget->allocation.width - OSD_S_EXP_W + OSD_S_X) + |
548 |
priv->handler_id = gtk_timeout_add(OSD_TIME/OSD_HZ, osd_source_animate, osd); |
priv->handler_id = gtk_timeout_add(OSD_TIME/OSD_HZ, osd_source_animate, osd); |
549 |
} |
} |
550 |
|
|
551 |
|
/* check if the user clicked inside the source selection area */ |
552 |
static osd_button_t |
static osd_button_t |
553 |
osd_source_check(osm_gps_map_osd_t *osd, gint x, gint y) { |
osd_source_check(osm_gps_map_osd_t *osd, gint x, gint y) { |
554 |
osd_priv_t *priv = (osd_priv_t*)osd->priv; |
osd_priv_t *priv = (osd_priv_t*)osd->priv; |
575 |
return OSD_BG; |
return OSD_BG; |
576 |
} |
} |
577 |
} |
} |
578 |
|
|
579 |
|
/* check for clicks into data area */ |
580 |
|
if(priv->expanded && !priv->handler_id) { |
581 |
|
if(x > OSD_S_PW && |
582 |
|
x < OSD_S_PW + OSD_S_EXP_W && |
583 |
|
y > 0 && |
584 |
|
y < OSD_S_EXP_H) { |
585 |
|
|
586 |
|
int step = (priv->height - 2*OSD_TEXT_BORDER) |
587 |
|
/ OSM_GPS_MAP_SOURCE_LAST; |
588 |
|
|
589 |
|
y -= OSD_TEXT_BORDER - OSD_TEXT_SKIP; |
590 |
|
y /= step; |
591 |
|
y += 1; |
592 |
|
|
593 |
|
gint old = 0; |
594 |
|
g_object_get(osd->widget, "map-source", &old, NULL); |
595 |
|
|
596 |
|
if(y > OSM_GPS_MAP_SOURCE_NULL && |
597 |
|
y <= OSM_GPS_MAP_SOURCE_LAST && |
598 |
|
old != y) { |
599 |
|
g_object_set(osd->widget, "map-source", y, NULL); |
600 |
|
|
601 |
|
osd_render_source_sel(osd); |
602 |
|
osm_gps_map_repaint(OSM_GPS_MAP(osd->widget)); |
603 |
|
} |
604 |
|
|
605 |
|
/* return "clicked in OSD background" to prevent further */ |
606 |
|
/* processing by application */ |
607 |
|
return OSD_BG; |
608 |
|
} |
609 |
|
} |
610 |
|
|
611 |
return OSD_NONE; |
return OSD_NONE; |
612 |
} |
} |
613 |
|
#endif // OSD_SOURCE_SEL |
614 |
|
|
615 |
static osd_button_t |
static osd_button_t |
616 |
osd_check(osm_gps_map_osd_t *osd, gint x, gint y) { |
osd_check(osm_gps_map_osd_t *osd, gint x, gint y) { |
799 |
|
|
800 |
cairo_destroy(cr); |
cairo_destroy(cr); |
801 |
|
|
802 |
|
#ifdef OSD_SOURCE_SEL |
803 |
osd_render_source_sel(osd); |
osd_render_source_sel(osd); |
804 |
|
#endif |
805 |
} |
} |
806 |
|
|
807 |
static void |
static void |
816 |
priv->overlay = |
priv->overlay = |
817 |
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, OSD_W+2, OSD_H+2); |
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, OSD_W+2, OSD_H+2); |
818 |
|
|
819 |
|
#ifdef OSD_SOURCE_SEL |
820 |
/* the initial OSD state is alway not-expanded */ |
/* the initial OSD state is alway not-expanded */ |
821 |
priv->map_source = |
priv->map_source = |
822 |
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, |
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, |
823 |
OSD_S_W+2, OSD_S_H+2); |
OSD_S_W+2, OSD_S_H+2); |
824 |
|
#endif |
825 |
|
|
826 |
/* ... and render it */ |
/* ... and render it */ |
827 |
osd_render(osd); |
osd_render(osd); |
870 |
{ |
{ |
871 |
osd_priv_t *priv = (osd_priv_t *)(osd->priv); |
osd_priv_t *priv = (osd_priv_t *)(osd->priv); |
872 |
|
|
|
if(priv->handler_id) |
|
|
gtk_timeout_remove(priv->handler_id); |
|
|
|
|
873 |
if (priv->overlay) |
if (priv->overlay) |
874 |
cairo_surface_destroy(priv->overlay); |
cairo_surface_destroy(priv->overlay); |
875 |
|
|
876 |
|
#ifdef OSD_SOURCE_SEL |
877 |
|
if(priv->handler_id) |
878 |
|
gtk_timeout_remove(priv->handler_id); |
879 |
|
|
880 |
if (priv->map_source) |
if (priv->map_source) |
881 |
cairo_surface_destroy(priv->map_source); |
cairo_surface_destroy(priv->map_source); |
882 |
|
#endif |
883 |
|
|
884 |
g_free(priv); |
g_free(priv); |
885 |
} |
} |
886 |
|
|
|
/* this is the only function that's externally visible */ |
|
887 |
static gboolean |
static gboolean |
888 |
osd_busy(osm_gps_map_osd_t *osd) |
osd_busy(osm_gps_map_osd_t *osd) |
889 |
{ |
{ |
890 |
|
#ifdef OSD_SOURCE_SEL |
891 |
osd_priv_t *priv = (osd_priv_t *)(osd->priv); |
osd_priv_t *priv = (osd_priv_t *)(osd->priv); |
892 |
return (priv->handler_id != 0); |
return (priv->handler_id != 0); |
893 |
|
#else |
894 |
|
return FALSE; |
895 |
|
#endif |
896 |
} |
} |
897 |
|
|
898 |
static osm_gps_map_osd_t osd_classic = { |
static osm_gps_map_osd_t osd_classic = { |
899 |
|
.widget = NULL, |
900 |
|
|
901 |
.draw = osd_draw, |
.draw = osd_draw, |
902 |
.check = osd_check, |
.check = osd_check, |
903 |
.render = osd_render, |
.render = osd_render, |