Diff of /trunk/src/osm-gps-map.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 62 by harbaum, Tue Aug 18 20:33:08 2009 UTC revision 63 by harbaum, Wed Aug 19 12:35:25 2009 UTC
# Line 1409  osm_gps_map_purge_cache (OsmGpsMap *map) Line 1409  osm_gps_map_purge_cache (OsmGpsMap *map)
1409    
1410  #ifdef ENABLE_OSD  #ifdef ENABLE_OSD
1411  /* position and extent of bounding box */  /* position and extent of bounding box */
1412  #define OSD_X  (10)  #define OSD_X      (10)
1413  #define OSD_Y  (10)  #define OSD_Y      (10)
1414  #define OSD_W  (80+5)  
1415  #define OSD_H  (120+5)  #define OSD_COLOR  0.5, 0.5, 1
1416    
1417    /* parameters of the direction shape */
1418    #define D_RAD  (20)         // diameter of dpad
1419    #define D_TIP  (4*D_RAD/5)  // distance of arrow tip from dpad center
1420    #define D_LEN  (D_RAD/4)    // length of arrow
1421    #define D_WID  (D_LEN)      // width of arrow
1422    
1423    /* parameters of the "zoom" pad */
1424    #define Z_STEP   (-D_RAD/8) // distance between dpad and zoom
1425    #define Z_RAD    (D_RAD/2)  // radius of "caps" of zoom bar
1426    
1427    /* shadow also depends on control size */
1428    #define OSD_SHADOW (D_RAD/8)
1429    
1430    /* total width and height of controls incl. shadow */
1431    #define OSD_W    (2*D_RAD + OSD_SHADOW)
1432    #define OSD_H    (2*D_RAD + Z_STEP + 2*Z_RAD + OSD_SHADOW)
1433    
1434    #define OSD_LBL_SHADOW (OSD_SHADOW/2)
1435    
1436    #define Z_TOP    (2 * D_RAD + Z_STEP)
1437    #define Z_MID    (Z_TOP + Z_RAD)
1438    #define Z_BOT    (Z_MID + Z_RAD)
1439    #define Z_LEFT   (Z_RAD)
1440    #define Z_RIGHT  (2 * D_RAD - Z_RAD)
1441    
1442    /* create the cairo shape used for the zoom buttons */
1443    static void
1444    osm_gps_map_osd_zoom_shape(cairo_t *cr, gint x, gint y) {
1445        cairo_move_to (cr, x+Z_LEFT,    y+Z_TOP);
1446        cairo_line_to (cr, x+Z_RIGHT,   y+Z_TOP);
1447        cairo_arc     (cr, x+Z_RIGHT,   y+Z_MID, Z_RAD, -M_PI/2,  M_PI/2);
1448        cairo_line_to (cr, x+Z_LEFT,    y+Z_BOT);
1449        cairo_arc     (cr, x+Z_LEFT,    y+Z_MID, Z_RAD,  M_PI/2, -M_PI/2);
1450    }
1451    
1452    /* create the cairo shape used for the dpad */
1453    static void
1454    osm_gps_map_osd_dpad_shape(cairo_t *cr, gint x, gint y) {
1455        cairo_arc (cr, x+D_RAD, y+D_RAD, D_RAD, 0, 2 * M_PI);
1456    }
1457    
1458    typedef enum {
1459        OSD_NONE = 0,
1460        OSD_BG,
1461        OSD_UP,
1462        OSD_DOWN,
1463        OSD_LEFT,
1464        OSD_RIGHT,
1465        OSD_IN,
1466        OSD_OUT,
1467        OSD_GPS
1468    } osd_button_t;
1469    
1470    static gboolean
1471    osm_gps_map_in_circle(gint x, gint y, gint cx, gint cy, gint rad)
1472    {
1473        return( pow(cx - x, 2) + pow(cy - y, 2) < rad * rad);
1474    }
1475    
1476    /* check whether x/y is within the dpad */
1477    static osd_button_t
1478    osm_gps_map_osd_check_dpad(gint x, gint y)
1479    {
1480        /* within entire dpad circle */
1481        if( osm_gps_map_in_circle(x, y, OSD_X + D_RAD, OSD_Y + D_RAD, D_RAD))
1482        {
1483            /* convert into position relative to dpads centre */
1484            x -= (OSD_X + D_RAD);
1485            y -= (OSD_Y + D_RAD);
1486    
1487            /* check for dpad center goes here! */
1488            if( osm_gps_map_in_circle(x, y, OSD_X + D_RAD, OSD_Y + D_RAD, D_RAD/3))
1489                return OSD_GPS;
1490    
1491            if( y < 0 && abs(x) < abs(y))
1492                return OSD_UP;
1493    
1494            if( y > 0 && abs(x) < abs(y))
1495                return OSD_DOWN;
1496    
1497            if( x < 0 && abs(y) < abs(x))
1498                return OSD_LEFT;
1499    
1500            if( x > 0 && abs(y) < abs(x))
1501                return OSD_RIGHT;
1502    
1503            return OSD_BG;
1504        }
1505        return OSD_NONE;
1506    }
1507    
1508    /* check whether x/y is within the zoom pads */
1509    static osd_button_t
1510    osm_gps_map_osd_check_zoom(gint x, gint y) {
1511        if( x > OSD_X && x < (OSD_X + OSD_W) && y > Z_TOP && y < Z_BOT) {
1512    
1513            /* within circle around (-) label */
1514            if( osm_gps_map_in_circle(x, y, OSD_X + Z_LEFT, OSD_Y + Z_MID, Z_RAD))
1515                return OSD_OUT;
1516    
1517            /* between center of (-) button and center of entire zoom control area */
1518            if(x > OSD_LEFT && x < OSD_X + D_RAD)
1519                return OSD_OUT;
1520    
1521            /* within circle around (+) label */
1522            if( osm_gps_map_in_circle(x, y, OSD_X + Z_RIGHT, OSD_Y + Z_MID, Z_RAD))
1523                return OSD_IN;
1524    
1525            /* between center of (+) button and center of entire zoom control area */
1526            if(x < OSD_RIGHT && x > OSD_X + D_RAD)
1527                return OSD_IN;
1528        }
1529    
1530        return OSD_NONE;
1531    }
1532    
1533    static osd_button_t
1534    osm_gps_map_osd_check(gint x, gint y) {
1535        osd_button_t but = OSD_NONE;
1536    
1537        /* first do a rough test for the OSD area. */
1538        /* this is just to avoid an unnecessary detailed test */
1539        if(x > OSD_X && x < OSD_X + OSD_W &&
1540           y > OSD_Y && y < OSD_Y + OSD_H) {
1541    
1542            but = osm_gps_map_osd_check_dpad(x, y);
1543    
1544            if(but == OSD_NONE)
1545                but = osm_gps_map_osd_check_zoom(x, y);
1546        }
1547    
1548        return but;
1549    }
1550    
1551    static void
1552    osm_gps_map_osd_shape_shadow(cairo_t *cr) {
1553        cairo_set_source_rgba (cr, 0, 0, 0, 0.2);
1554        cairo_fill (cr);
1555        cairo_stroke (cr);
1556    }
1557    
1558    static void
1559    osm_gps_map_osd_shape(cairo_t *cr) {
1560        cairo_set_source_rgb (cr, 1, 1, 1);
1561        cairo_fill_preserve (cr);
1562        cairo_set_source_rgb (cr, OSD_COLOR);
1563        cairo_set_line_width (cr, 1);
1564        cairo_stroke (cr);
1565    }
1566    
1567  static void  static void
1568  osm_gps_map_draw_osd_controls (OsmGpsMap *map, gint xoffset, gint yoffset)  osm_gps_map_osd_dpad_labels(cairo_t *cr, gint x, gint y) {
1569        /* move reference to dpad center */
1570        x += D_RAD;
1571        y += D_RAD;
1572    
1573        const static gint offset[][3][2] = {
1574            /* left arrow/triangle */
1575            { { -D_TIP+D_LEN, -D_WID }, { -D_LEN, D_WID }, { +D_LEN, D_WID } },
1576            /* right arrow/triangle */
1577            { { +D_TIP-D_LEN, -D_WID }, { +D_LEN, D_WID }, { -D_LEN, D_WID } },
1578            /* top arrow/triangle */
1579            { { -D_WID, -D_TIP+D_LEN }, { D_WID, -D_LEN }, { D_WID, +D_LEN } },
1580            /* bottom arrow/triangle */
1581            { { -D_WID, +D_TIP-D_LEN }, { D_WID, +D_LEN }, { D_WID, -D_LEN } }
1582        };
1583    
1584        int i;
1585        for(i=0;i<4;i++) {
1586            cairo_move_to (cr, x + offset[i][0][0], y + offset[i][0][1]);
1587            cairo_rel_line_to (cr, offset[i][1][0], offset[i][1][1]);
1588            cairo_rel_line_to (cr, offset[i][2][0], offset[i][2][1]);
1589        }
1590    }
1591    
1592    /* draw the sattelite dish icon in the center of the dpad */
1593    #define GPS_V0  (D_RAD/8)
1594    #define GPS_V1  (D_RAD/10)
1595    #define GPS_V2  (D_RAD/5)
1596    
1597    /* draw a satellite receiver dish */
1598    static void
1599    osm_gps_map_osd_dpad_gps(cairo_t *cr, gint x, gint y) {
1600        /* move reference to dpad center */
1601        x += D_RAD;
1602        y += D_RAD + GPS_V0;
1603    
1604        cairo_move_to (cr, x-GPS_V0, y+GPS_V0);
1605        cairo_rel_line_to (cr, +GPS_V0, -GPS_V0);
1606        cairo_rel_line_to (cr, +GPS_V0, +GPS_V0);
1607        cairo_close_path (cr);
1608    
1609        cairo_move_to (cr, x+GPS_V1-GPS_V2, y-2*GPS_V2);
1610        cairo_curve_to (cr, x-GPS_V2, y, x+GPS_V1, y+GPS_V1, x+GPS_V1+GPS_V2, y);
1611        cairo_close_path (cr);
1612    
1613        x += GPS_V1;
1614        cairo_move_to (cr, x, y-GPS_V2);
1615        cairo_rel_line_to (cr, +GPS_V1, -GPS_V1);
1616    }
1617    
1618    #define Z_LEN  (2*Z_RAD/3)
1619    
1620    static void
1621    osm_gps_map_osd_zoom_labels(cairo_t *cr, gint x, gint y) {
1622        cairo_move_to (cr, x + Z_LEFT  - Z_LEN, y + Z_MID);
1623        cairo_line_to (cr, x + Z_LEFT  + Z_LEN, y + Z_MID);
1624    
1625        cairo_move_to (cr, x + Z_RIGHT,         y + Z_MID - Z_LEN);
1626        cairo_line_to (cr, x + Z_RIGHT,         y + Z_MID + Z_LEN);
1627        cairo_move_to (cr, x + Z_RIGHT - Z_LEN, y + Z_MID);
1628        cairo_line_to (cr, x + Z_RIGHT + Z_LEN, y + Z_MID);
1629    }
1630    
1631    static void
1632    osm_gps_map_osd_labels(cairo_t *cr, gint width) {
1633        cairo_set_source_rgb (cr, OSD_COLOR);
1634        cairo_set_line_width (cr, width);
1635        cairo_stroke (cr);
1636    }
1637    
1638    static void
1639    osm_gps_map_osd_labels_shadow(cairo_t *cr, gint width) {
1640        cairo_set_source_rgba (cr, 0, 0, 0, 0.2);
1641        cairo_set_line_width (cr, width);
1642        cairo_stroke (cr);
1643    }
1644    
1645    static void
1646    osm_gps_map_osd_draw_controls (OsmGpsMap *map, gint xoffset, gint yoffset)
1647  {  {
     /* xyz */  
1648      OsmGpsMapPrivate *priv = map->priv;      OsmGpsMapPrivate *priv = map->priv;
1649    
1650      /* backup previous contents */      /* backup previous contents */
# Line 1457  osm_gps_map_draw_osd_controls (OsmGpsMap Line 1684  osm_gps_map_draw_osd_controls (OsmGpsMap
1684      //    cairo_t *cr = cairo_create(surface);      //    cairo_t *cr = cairo_create(surface);
1685      cairo_t *cr = gdk_cairo_create(priv->pixmap);      cairo_t *cr = gdk_cairo_create(priv->pixmap);
1686    
1687  #define RAD  40      /* --------- draw zoom and dpad shape shadow ----------- */
 #define TIP  35  
 #define LEN  15  
 #define WID  15  
   
 #define Z_STEP   -5  
 #define Z_RAD    15  
 #define Z_TOP    2*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*RAD-Z_RAD  
   
     /* --------- the direction "pad" shape and shadow ----------- */  
   
     cairo_move_to (cr, x+Z_LEFT+5,    y+Z_TOP+5);  
     cairo_line_to (cr, x+Z_RIGHT+5,   y+Z_TOP+5);  
     cairo_arc     (cr, x+Z_RIGHT+5,   y+Z_MID+5, Z_RAD, -M_PI/2,  M_PI/2);  
     cairo_line_to (cr, x+Z_LEFT+5,    y+Z_BOT+5);  
     cairo_arc     (cr, x+Z_LEFT+5,    y+Z_MID+5, Z_RAD,  M_PI/2, -M_PI/2);  
     cairo_close_path (cr);  
   
     cairo_set_source_rgba (cr, 0, 0, 0, 0.2);  
     cairo_fill (cr);  
     cairo_stroke (cr);  
   
     cairo_arc (cr, x+RAD+5, y+RAD+5, RAD, 0, 2 * M_PI);  
     cairo_close_path (cr);  
   
     cairo_set_source_rgba (cr, 0, 0, 0, 0.2);  
     cairo_fill (cr);  
     cairo_stroke (cr);  
   
   
     cairo_move_to (cr, x+Z_LEFT,    y+Z_TOP);  
     cairo_line_to (cr, x+Z_RIGHT,   y+Z_TOP);  
     cairo_arc     (cr, x+Z_RIGHT,   y+Z_MID, Z_RAD, -M_PI/2,  M_PI/2);  
     cairo_line_to (cr, x+Z_LEFT,    y+Z_BOT);  
     cairo_arc     (cr, x+Z_LEFT,    y+Z_MID, Z_RAD,  M_PI/2, -M_PI/2);  
     cairo_close_path (cr);  
   
     cairo_set_source_rgb (cr, 1, 1, 1);  
     cairo_fill_preserve (cr);  
     cairo_set_source_rgb (cr, 0.6, 0.6, 1);  
     cairo_set_line_width (cr, 1);  
     cairo_stroke (cr);  
   
     cairo_arc (cr, x+RAD, y+RAD, RAD, 0, 2 * M_PI);  
     cairo_close_path (cr);  
   
     cairo_set_source_rgb (cr, 1, 1, 1);  
     cairo_fill_preserve (cr);  
     cairo_set_source_rgb (cr, 0.6, 0.6, 1);  
     cairo_set_line_width (cr, 1);  
     cairo_stroke (cr);  
   
     /* ---------- the zoom pad shape and shadow  -------------- */  
   
   
   
     /* left arrow/triangle */  
     cairo_move_to (cr, x+RAD-TIP, y+RAD);  
     cairo_rel_line_to (cr, +LEN, -WID/2);  
     cairo_rel_line_to (cr,    0,   +WID);  
     cairo_rel_line_to (cr, -LEN, -WID/2);  
     cairo_close_path (cr);  
   
     /* right arrow/triangle */  
     cairo_move_to (cr, x+RAD+TIP, y+RAD);  
     cairo_rel_line_to (cr, -LEN, -WID/2);  
     cairo_rel_line_to (cr,    0,   +WID);  
     cairo_rel_line_to (cr, +LEN, -WID/2);  
     cairo_close_path (cr);  
   
     /* top arrow/triangle */  
     cairo_move_to (cr, x+RAD, y+RAD-TIP);  
     cairo_rel_line_to (cr, -WID/2, +LEN);  
     cairo_rel_line_to (cr,   +WID,    0);  
     cairo_rel_line_to (cr, -WID/2, -LEN);  
     cairo_close_path (cr);  
   
     /* bottom arrow/triangle */  
     cairo_move_to (cr, x+RAD, y+RAD+TIP);  
     cairo_rel_line_to (cr, -WID/2, -LEN);  
     cairo_rel_line_to (cr,   +WID,    0);  
     cairo_rel_line_to (cr, -WID/2, +LEN);  
     cairo_close_path (cr);  
   
     cairo_set_source_rgb (cr, 0.6, 0.6, 1);  
     cairo_fill_preserve (cr);  
     cairo_set_line_width (cr, 0);  
     cairo_set_source_rgba (cr, 0, 0, 0, 1);  
     cairo_stroke (cr);  
1688    
1689        osm_gps_map_osd_zoom_shape(cr, x + OSD_SHADOW, y + OSD_SHADOW);
1690        osm_gps_map_osd_shape_shadow(cr);
1691        osm_gps_map_osd_dpad_shape(cr, x + OSD_SHADOW, y + OSD_SHADOW);
1692        osm_gps_map_osd_shape_shadow(cr);
1693    
1694        /* --------- draw zoom and dpad shape ----------- */
1695    
1696        osm_gps_map_osd_zoom_shape(cr, x, y);
1697        osm_gps_map_osd_shape(cr);
1698        osm_gps_map_osd_dpad_shape(cr, x, y);
1699        osm_gps_map_osd_shape(cr);
1700    
1701        /* --------- draw zoom and dpad labels --------- */
1702    
1703        osm_gps_map_osd_zoom_labels(cr, x + OSD_LBL_SHADOW, y + OSD_LBL_SHADOW);
1704        osm_gps_map_osd_dpad_labels(cr, x + OSD_LBL_SHADOW, y + OSD_LBL_SHADOW);
1705        osm_gps_map_osd_labels_shadow(cr, Z_RAD/3);
1706        osm_gps_map_osd_dpad_gps(cr, x + OSD_LBL_SHADOW, y + OSD_LBL_SHADOW);
1707        osm_gps_map_osd_labels_shadow(cr, Z_RAD/6);
1708    
1709        osm_gps_map_osd_zoom_labels(cr, x, y);
1710        osm_gps_map_osd_dpad_labels(cr, x, y);
1711        osm_gps_map_osd_labels(cr, Z_RAD/3);
1712        osm_gps_map_osd_dpad_gps(cr, x, y);
1713        osm_gps_map_osd_labels(cr, Z_RAD/6);
1714    
1715      cairo_destroy(cr);      cairo_destroy(cr);
1716    
# Line 1608  osm_gps_map_map_redraw (OsmGpsMap *map) Line 1768  osm_gps_map_map_redraw (OsmGpsMap *map)
1768      osm_gps_map_print_images(map);      osm_gps_map_print_images(map);
1769      osm_gps_map_draw_balloon_int(map);      osm_gps_map_draw_balloon_int(map);
1770  #ifdef ENABLE_OSD  #ifdef ENABLE_OSD
1771      osm_gps_map_draw_osd_controls(map, 0, 0);      osm_gps_map_osd_draw_controls(map, 0, 0);
1772  #endif  #endif
1773    
1774      //osm_gps_map_osd_speed(map, 1.5);      //osm_gps_map_osd_speed(map, 1.5);
# Line 2038  osm_gps_map_button_press (GtkWidget *wid Line 2198  osm_gps_map_button_press (GtkWidget *wid
2198          return FALSE;          return FALSE;
2199      }      }
2200    
2201    #ifdef ENABLE_OSD
2202        /* also don't drag on clicks into the control OSD */
2203        if(osm_gps_map_osd_check(event->x, event->y) != OSD_NONE)
2204        {
2205            priv->drag_counter = -1;
2206            return FALSE;
2207        }
2208    #endif
2209    
2210      priv->drag_counter = 0;      priv->drag_counter = 0;
2211      priv->drag_start_mouse_x = (int) event->x;      priv->drag_start_mouse_x = (int) event->x;
2212      priv->drag_start_mouse_y = (int) event->y;      priv->drag_start_mouse_y = (int) event->y;
# Line 2052  osm_gps_map_button_release (GtkWidget *w Line 2221  osm_gps_map_button_release (GtkWidget *w
2221  {  {
2222      OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget);      OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget);
2223    
2224    #ifdef ENABLE_OSD
2225        /* released inside OSD control? */
2226        osd_button_t but = osm_gps_map_osd_check(event->x, event->y);
2227        if(but != OSD_NONE)
2228        {
2229            switch(but) {
2230            case OSD_UP:
2231                priv->map_y -= GTK_WIDGET(widget)->allocation.height/4;
2232                priv->center_coord_set = FALSE;
2233                break;
2234    
2235            case OSD_DOWN:
2236                priv->map_y += GTK_WIDGET(widget)->allocation.height/4;
2237                priv->center_coord_set = FALSE;
2238                break;
2239    
2240            case OSD_LEFT:
2241                priv->map_x -= GTK_WIDGET(widget)->allocation.width/4;
2242                priv->center_coord_set = FALSE;
2243                break;
2244    
2245            case OSD_RIGHT:
2246                priv->map_x += GTK_WIDGET(widget)->allocation.width/4;
2247                priv->center_coord_set = FALSE;
2248                break;
2249    
2250            case OSD_IN:
2251                osm_gps_map_set_zoom(OSM_GPS_MAP(widget), priv->map_zoom+1);
2252                break;
2253    
2254            case OSD_OUT:
2255                osm_gps_map_set_zoom(OSM_GPS_MAP(widget), priv->map_zoom-1);
2256                break;
2257    
2258            default:
2259                break;
2260            }
2261    
2262            osm_gps_map_map_redraw_idle(OSM_GPS_MAP(widget));
2263    
2264            return FALSE;
2265        }
2266    #endif
2267    
2268      /* released inside the balloon? */      /* released inside the balloon? */
2269      if (osm_gps_map_in_balloon(priv,      if (osm_gps_map_in_balloon(priv,
2270                     event->x + EXTRA_BORDER,                     event->x + EXTRA_BORDER,
# Line 2060  osm_gps_map_button_release (GtkWidget *w Line 2273  osm_gps_map_button_release (GtkWidget *w
2273          osm_gps_map_handle_balloon_click(OSM_GPS_MAP(widget),          osm_gps_map_handle_balloon_click(OSM_GPS_MAP(widget),
2274               event->x - priv->balloon.rect.x + EXTRA_BORDER,               event->x - priv->balloon.rect.x + EXTRA_BORDER,
2275               event->y - priv->balloon.rect.y + EXTRA_BORDER);               event->y - priv->balloon.rect.y + EXTRA_BORDER);
         return FALSE;  
2276      }      }
2277    
     if (priv->drag_counter < 0)  
         return FALSE;  
   
2278      if (priv->dragging)      if (priv->dragging)
2279      {      {
2280          priv->dragging = FALSE;          priv->dragging = FALSE;
# Line 2130  osm_gps_map_motion_notify (GtkWidget *wi Line 2339  osm_gps_map_motion_notify (GtkWidget *wi
2339      osm_gps_map_osd_restore (OSM_GPS_MAP(widget));      osm_gps_map_osd_restore (OSM_GPS_MAP(widget));
2340    
2341      /* draw new OSD */      /* draw new OSD */
2342      osm_gps_map_draw_osd_controls (OSM_GPS_MAP(widget),      osm_gps_map_osd_draw_controls (OSM_GPS_MAP(widget),
2343                                     -priv->drag_mouse_dx,                                     -priv->drag_mouse_dx,
2344                                     -priv->drag_mouse_dy);                                     -priv->drag_mouse_dy);
2345  #endif  #endif

Legend:
Removed from v.62  
changed lines
  Added in v.63