--- trunk/src/osm-gps-map-osd-classic.c 2009/08/24 19:21:46 76 +++ trunk/src/osm-gps-map-osd-classic.c 2009/08/25 12:49:03 77 @@ -22,7 +22,8 @@ #include // M_PI /* parameters that can be overwritten from the config file: */ -/* OSM_GPS_MAP_OSD_DIAMETER */ +/* OSD_DIAMETER */ +/* OSD_X, OSD_Y */ #ifndef USE_CAIRO #error "OSD control display lacks a non-cairo implementation!" @@ -37,20 +38,22 @@ typedef struct { /* the offscreen representation of the OSD */ cairo_surface_t *overlay; - - GdkColor bg, fg, da; - } osd_priv_t; /* position and extent of bounding box */ +#ifndef OSD_X #define OSD_X (10) +#endif + +#ifndef OSD_Y #define OSD_Y (10) +#endif /* parameters of the direction shape */ -#ifndef OSM_GPS_MAP_OSD_DIAMETER +#ifndef OSD_DIAMETER #define D_RAD (30) // diameter of dpad #else -#define D_RAD (OSM_GPS_MAP_OSD_DIAMETER) +#define D_RAD (OSD_DIAMETER) #endif #define D_TIP (4*D_RAD/5) // distance of arrow tip from dpad center #define D_LEN (D_RAD/4) // length of arrow @@ -67,20 +70,33 @@ #define OSD_SHADOW (0) #endif +/* normally the GPS button is in the center of the dpad. if there's */ +/* no dpad it will go into the zoom area */ +#if defined(OSD_GPS_BUTTON) && defined(OSD_NO_DPAD) +#define Z_GPS 1 +#else +#define Z_GPS 0 +#endif + /* total width and height of controls incl. shadow */ -#define OSD_W (2*D_RAD + OSD_SHADOW) +#define OSD_W (2*D_RAD + OSD_SHADOW + Z_GPS * 2 * Z_RAD) +#if !Z_GPS #define OSD_H (2*D_RAD + Z_STEP + 2*Z_RAD + OSD_SHADOW) +#else +#define OSD_H (2*Z_RAD + OSD_SHADOW) +#endif #ifdef OSD_SHADOW_ENABLE #define OSD_LBL_SHADOW (OSD_SHADOW/2) #endif -#define Z_TOP (2 * D_RAD + Z_STEP) +#define Z_TOP ((1-Z_GPS) * (2 * D_RAD + Z_STEP)) + #define Z_MID (Z_TOP + Z_RAD) #define Z_BOT (Z_MID + Z_RAD) #define Z_LEFT (Z_RAD) -#define Z_RIGHT (2 * D_RAD - Z_RAD) - +#define Z_RIGHT (2 * D_RAD - Z_RAD + Z_GPS * 2 * Z_RAD) +#define Z_CENTER ((Z_RIGHT + Z_LEFT)/2) /* create the cairo shape used for the zoom buttons */ static void @@ -114,11 +130,11 @@ osm_gps_map_osd_check_dpad(gint x, gint y) { /* within entire dpad circle */ - if( osm_gps_map_in_circle(x, y, OSD_X + D_RAD, OSD_Y + D_RAD, D_RAD)) + if( osm_gps_map_in_circle(x, y, D_RAD, D_RAD, D_RAD)) { /* convert into position relative to dpads centre */ - x -= (OSD_X + D_RAD); - y -= (OSD_Y + D_RAD); + x -= D_RAD; + y -= D_RAD; #ifdef OSD_GPS_BUTTON /* check for dpad center goes here! */ @@ -147,22 +163,28 @@ /* check whether x/y is within the zoom pads */ static osd_button_t osm_gps_map_osd_check_zoom(gint x, gint y) { - if( x > OSD_X && x < (OSD_X + OSD_W) && y > Z_TOP && y < (OSD_Y+Z_BOT)) { + if( x > 0 && x < OSD_W && y > Z_TOP && y < Z_BOT) { /* within circle around (-) label */ - if( osm_gps_map_in_circle(x, y, OSD_X + Z_LEFT, OSD_Y + Z_MID, Z_RAD)) - return OSD_OUT; - - /* between center of (-) button and center of entire zoom control area */ - if(x > OSD_LEFT && x < OSD_X + D_RAD) + if( osm_gps_map_in_circle(x, y, Z_LEFT, Z_MID, Z_RAD)) return OSD_OUT; /* within circle around (+) label */ - if( osm_gps_map_in_circle(x, y, OSD_X + Z_RIGHT, OSD_Y + Z_MID, Z_RAD)) + if( osm_gps_map_in_circle(x, y, Z_RIGHT, Z_MID, Z_RAD)) return OSD_IN; +#if Z_GPS == 1 + /* within square around center */ + if( x > Z_CENTER - Z_RAD && x < Z_CENTER + Z_RAD) + return OSD_GPS; +#endif + + /* between center of (-) button and center of entire zoom control area */ + if(x > OSD_LEFT && x < D_RAD) + return OSD_OUT; + /* between center of (+) button and center of entire zoom control area */ - if(x < OSD_RIGHT && x > OSD_X + D_RAD) + if(x < OSD_RIGHT && x > D_RAD) return OSD_IN; } @@ -170,13 +192,21 @@ } static osd_button_t -osm_gps_map_osd_check(gint x, gint y) { +osm_gps_map_osd_check(osm_gps_map_osd_t *osd, gint x, gint y) { osd_button_t but = OSD_NONE; + x -= OSD_X; + y -= OSD_Y; + + if(OSD_X < 0) + x -= (osd->widget->allocation.width - OSD_W); + + if(OSD_Y < 0) + y -= (osd->widget->allocation.height - OSD_H); + /* first do a rough test for the OSD area. */ /* this is just to avoid an unnecessary detailed test */ - if(x > OSD_X && x < OSD_X + OSD_W && - y > OSD_Y && y < OSD_Y + OSD_H) { + if(x > 0 && x < OSD_W && y > 0 && y < OSD_H) { #ifndef OSD_NO_DPAD but = osm_gps_map_osd_check_dpad(x, y); #endif @@ -247,16 +277,18 @@ #ifdef OSD_GPS_BUTTON /* draw the satellite dish icon in the center of the dpad */ -#define GPS_V0 (D_RAD/8) +#define GPS_V0 (D_RAD/7) #define GPS_V1 (D_RAD/10) #define GPS_V2 (D_RAD/5) /* draw a satellite receiver dish */ +/* this is either drawn in the center of the dpad (if present) */ +/* or in the middle of the zoom area */ static void osm_gps_map_osd_dpad_gps(cairo_t *cr, gint x, gint y) { /* move reference to dpad center */ - x += D_RAD; - y += D_RAD + GPS_V0; + x += (1-Z_GPS) * D_RAD + Z_GPS * Z_RAD * 3; + y += (1-Z_GPS) * D_RAD + Z_GPS * Z_RAD + GPS_V0; cairo_move_to (cr, x-GPS_V0, y+GPS_V0); cairo_rel_line_to (cr, +GPS_V0, -GPS_V0); @@ -325,6 +357,12 @@ cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.0); cairo_paint(cr); +#ifndef OSD_COLOR + GdkColor bg = GTK_WIDGET(osd->widget)->style->bg[GTK_STATE_NORMAL]; + GdkColor fg = GTK_WIDGET(osd->widget)->style->fg[GTK_STATE_NORMAL]; + GdkColor da = GTK_WIDGET(osd->widget)->style->fg[GTK_STATE_INSENSITIVE]; +#endif + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); /* --------- draw zoom and dpad shape shadow ----------- */ @@ -343,14 +381,14 @@ osm_gps_map_osd_zoom_shape(cr, x, y); #ifndef OSD_COLOR - osm_gps_map_osd_shape(cr, &priv->bg, &priv->fg); + osm_gps_map_osd_shape(cr, &bg, &fg); #else osm_gps_map_osd_shape(cr); #endif #ifndef OSD_NO_DPAD osm_gps_map_osd_dpad_shape(cr, x, y); #ifndef OSD_COLOR - osm_gps_map_osd_shape(cr, &priv->bg, &priv->fg); + osm_gps_map_osd_shape(cr, &bg, &fg); #else osm_gps_map_osd_shape(cr); #endif @@ -375,14 +413,14 @@ osm_gps_map_osd_dpad_labels(cr, x, y); #endif #ifndef OSD_COLOR - osm_gps_map_osd_labels(cr, Z_RAD/3, TRUE, &priv->fg, &priv->da); + osm_gps_map_osd_labels(cr, Z_RAD/3, TRUE, &fg, &da); #else osm_gps_map_osd_labels(cr, Z_RAD/3, TRUE); #endif #ifdef OSD_GPS_BUTTON osm_gps_map_osd_dpad_gps(cr, x, y); #ifndef OSD_COLOR - osm_gps_map_osd_labels(cr, Z_RAD/6, osd->cb != NULL, &priv->fg, &priv->da); + osm_gps_map_osd_labels(cr, Z_RAD/6, osd->cb != NULL, &fg, &da); #else osm_gps_map_osd_labels(cr, Z_RAD/6, osd->cb != NULL); #endif @@ -408,7 +446,15 @@ // now draw this onto the original context cairo_t *cr = gdk_cairo_create(drawable); - cairo_set_source_surface(cr, priv->overlay, OSD_X, OSD_Y); + + int x = OSD_X, y = OSD_Y; + if(OSD_X < 0) + x = osd->widget->allocation.width - OSD_W + OSD_X; + + if(OSD_Y < 0) + y = osd->widget->allocation.height - OSD_H + OSD_Y; + + cairo_set_source_surface(cr, priv->overlay, x, y); cairo_paint(cr); cairo_destroy(cr); } @@ -444,11 +490,6 @@ osd_classic.priv = priv; - /* extract style info from the widget */ - priv->bg = GTK_WIDGET(map)->style->bg[GTK_STATE_NORMAL]; - priv->fg = GTK_WIDGET(map)->style->fg[GTK_STATE_NORMAL]; - priv->da = GTK_WIDGET(map)->style->fg[GTK_STATE_INSENSITIVE]; - osm_gps_map_register_osd(map, &osd_classic); }