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

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

revision 57 by harbaum, Sun Aug 16 19:29:01 2009 UTC revision 58 by harbaum, Mon Aug 17 10:51:56 2009 UTC
# Line 99  struct _OsmGpsMapPrivate Line 99  struct _OsmGpsMapPrivate
99      gboolean gps_valid;      gboolean gps_valid;
100    
101      //a balloon with additional info      //a balloon with additional info
102      coord_t *balloon;      struct {
103      gboolean balloon_valid;          coord_t *coo;
104            gboolean valid;
105            OsmGpsMapRect_t rect;
106            OsmGpsMapBalloonCallback cb;
107            gpointer data;
108        } balloon;
109    
110      //additional images or tracks added to the map      //additional images or tracks added to the map
111      GSList *tracks;      GSList *tracks;
# Line 639  osm_gps_map_draw_gps_point (OsmGpsMap *m Line 644  osm_gps_map_draw_gps_point (OsmGpsMap *m
644    
645  /* most visual effects are hardcoded by now, but may be made */  /* most visual effects are hardcoded by now, but may be made */
646  /* available via properties later */  /* available via properties later */
647    #define BALLOON_AREA_WIDTH           250
648    #define BALLOON_AREA_HEIGHT           75
649    
650  #define BALLOON_CORNER_RADIUS         20  #define BALLOON_CORNER_RADIUS         20
651  #define BALLOON_WIDTH                150  #define BALLOON_BORDER               (BALLOON_CORNER_RADIUS/4)
652  #define BALLOON_HEIGHT                75  #define BALLOON_WIDTH                (BALLOON_AREA_WIDTH + 2 * BALLOON_BORDER)
653    #define BALLOON_HEIGHT               (BALLOON_AREA_HEIGHT + 2 * BALLOON_BORDER)
654  #define BALLOON_TRANSPARENCY         0.8  #define BALLOON_TRANSPARENCY         0.8
655  #define POINTER_HEIGHT                20  #define POINTER_HEIGHT                20
656  #define POINTER_FOOT_WIDTH            20  #define POINTER_FOOT_WIDTH            20
# Line 649  osm_gps_map_draw_gps_point (OsmGpsMap *m Line 658  osm_gps_map_draw_gps_point (OsmGpsMap *m
658  #define BALLOON_SHADOW                5  #define BALLOON_SHADOW                5
659  #define BALLOON_SHADOW_TRANSPARENCY  0.2  #define BALLOON_SHADOW_TRANSPARENCY  0.2
660    
661    #define CLOSE_BUTTON_RADIUS   (BALLOON_CORNER_RADIUS/3)
662    
663    
664  /* draw the bubble shape. this is used twice, once for the shape and once */  /* draw the bubble shape. this is used twice, once for the shape and once */
665  /* for the shadow */  /* for the shadow */
666  static void  static void
# Line 658  osm_gps_map_draw_balloon_shape (cairo_t Line 670  osm_gps_map_draw_balloon_shape (cairo_t
670      cairo_move_to (cr, x0, y0 + BALLOON_CORNER_RADIUS);      cairo_move_to (cr, x0, y0 + BALLOON_CORNER_RADIUS);
671      cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + BALLOON_CORNER_RADIUS, y0);      cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + BALLOON_CORNER_RADIUS, y0);
672      if(!bottom) {      if(!bottom) {
673          /* insert bottom/left pointer */          /* insert top pointer */
674          cairo_line_to (cr, px1, y0);          cairo_line_to (cr, px1, y0);
675          cairo_line_to (cr, px, py);          cairo_line_to (cr, px, py);
676          cairo_line_to (cr, px0, y0);          cairo_line_to (cr, px0, y0);
# Line 669  osm_gps_map_draw_balloon_shape (cairo_t Line 681  osm_gps_map_draw_balloon_shape (cairo_t
681      cairo_line_to (cr, x1 , y1 - BALLOON_CORNER_RADIUS);      cairo_line_to (cr, x1 , y1 - BALLOON_CORNER_RADIUS);
682      cairo_curve_to (cr, x1, y1, x1, y1, x1 - BALLOON_CORNER_RADIUS, y1);      cairo_curve_to (cr, x1, y1, x1, y1, x1 - BALLOON_CORNER_RADIUS, y1);
683      if(bottom) {      if(bottom) {
684          /* insert bottom/left pointer */          /* insert bottom pointer */
685          cairo_line_to (cr, px0, y1);          cairo_line_to (cr, px0, y1);
686          cairo_line_to (cr, px, py);          cairo_line_to (cr, px, py);
687          cairo_line_to (cr, px1, y1);          cairo_line_to (cr, px1, y1);
# Line 687  osm_gps_map_draw_balloon_int (OsmGpsMap Line 699  osm_gps_map_draw_balloon_int (OsmGpsMap
699  {  {
700      OsmGpsMapPrivate *priv = map->priv;      OsmGpsMapPrivate *priv = map->priv;
701    
702      if (priv->balloon_valid) {      if (priv->balloon.valid) {
703    
704          /* ------- convert given coordinate into screen position --------- */          /* ------- convert given coordinate into screen position --------- */
705          int x0 = lon2pixel(priv->map_zoom, priv->balloon->rlon) -          int x0 = lon2pixel(priv->map_zoom, priv->balloon.coo->rlon) -
706              priv->map_x + EXTRA_BORDER;              priv->map_x + EXTRA_BORDER;
707          int y0 = lat2pixel(priv->map_zoom, priv->balloon->rlat) -          int y0 = lat2pixel(priv->map_zoom, priv->balloon.coo->rlat) -
708              priv->map_y + EXTRA_BORDER;              priv->map_y + EXTRA_BORDER;
709    
710          /* check position of this relative to screen center to determine */          /* check position of this relative to screen center to determine */
# Line 721  osm_gps_map_draw_balloon_int (OsmGpsMap Line 733  osm_gps_map_draw_balloon_int (OsmGpsMap
733          /* calculate bottom/right of box */          /* calculate bottom/right of box */
734          int x1 = x0 + BALLOON_WIDTH, y1 = y0 + BALLOON_HEIGHT;          int x1 = x0 + BALLOON_WIDTH, y1 = y0 + BALLOON_HEIGHT;
735    
736            /* save balloon screen coordinates for later use */
737            priv->balloon.rect.x = x0 + BALLOON_BORDER;
738            priv->balloon.rect.y = y0 + BALLOON_BORDER;
739            priv->balloon.rect.w = x1 - x0 - 2*BALLOON_BORDER;
740            priv->balloon.rect.h = y1 - y0 - 2*BALLOON_BORDER;
741    
742  #ifdef USE_CAIRO  #ifdef USE_CAIRO
743          cairo_t *cr = gdk_cairo_create(priv->pixmap);          cairo_t *cr = gdk_cairo_create(priv->pixmap);
744    
# Line 750  osm_gps_map_draw_balloon_int (OsmGpsMap Line 768  osm_gps_map_draw_balloon_int (OsmGpsMap
768    
769          /* ---------- draw close button --------- */          /* ---------- draw close button --------- */
770    
771          int cx = x1 - BALLOON_CORNER_RADIUS*3/4;          int cx = x1 - BALLOON_BORDER - CLOSE_BUTTON_RADIUS;
772          int cy = y0 + BALLOON_CORNER_RADIUS*3/4;          int cy = y0 + BALLOON_BORDER + CLOSE_BUTTON_RADIUS;
773          int crad = BALLOON_CORNER_RADIUS/3;          int crad = CLOSE_BUTTON_RADIUS;
774    
775          cairo_arc (cr, cx, cy, crad, 0, 2 * M_PI);          cairo_arc (cr, cx, cy, crad, 0, 2 * M_PI);
776          cairo_set_source_rgba (cr, 0.8, 0, 0, 1.0);          cairo_set_source_rgba (cr, 0.8, 0, 0, 1.0);
777          cairo_fill_preserve (cr);          cairo_fill_preserve (cr);
778          cairo_set_source_rgba (cr, 0.3, 0, 0, 1.0);          cairo_set_source_rgba (cr, 0.3, 0, 0, 1.0);
779          cairo_set_line_width (cr, 1);          cairo_set_line_width (cr, 2);
780          cairo_stroke(cr);          cairo_stroke(cr);
781    
         int cs = crad/2;  
782          cairo_set_source_rgba (cr, 1, 1, 1, 1.0);          cairo_set_source_rgba (cr, 1, 1, 1, 1.0);
783          cairo_set_line_width (cr, 3);          cairo_set_line_width (cr, 3);
784          cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);          cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
785          cairo_move_to (cr, cx - cs, cy - cs);          cairo_move_to (cr, cx - crad/2, cy - crad/2);
786          cairo_line_to (cr, cx + cs, cy + cs);          cairo_line_to (cr, cx + crad/2, cy + crad/2);
787          cairo_stroke (cr);          cairo_stroke (cr);
788          cairo_move_to (cr, cx + cs, cy - cs);          cairo_move_to (cr, cx + crad/2, cy - crad/2);
789          cairo_line_to (cr, cx - cs, cy + cs);          cairo_line_to (cr, cx - crad/2, cy + crad/2);
790          cairo_stroke (cr);          cairo_stroke (cr);
791    
792            if (priv->balloon.cb) {
793                /* clip in case application tries to draw in */
794                /* exceed of the balloon */
795                cairo_rectangle (cr, priv->balloon.rect.x, priv->balloon.rect.y,
796                                 priv->balloon.rect.w, priv->balloon.rect.h);
797                cairo_clip (cr);
798                cairo_new_path (cr);  /* current path is not
799                                         consumed by cairo_clip() */
800    
801                priv->balloon.cb(cr, &priv->balloon.rect, priv->balloon.data);
802            }
803    
804          gtk_widget_queue_draw_area (GTK_WIDGET(map),          gtk_widget_queue_draw_area (GTK_WIDGET(map),
805                                      x0, y0, BALLOON_WIDTH,                                      x0, y0, BALLOON_WIDTH,
# Line 782  osm_gps_map_draw_balloon_int (OsmGpsMap Line 810  osm_gps_map_draw_balloon_int (OsmGpsMap
810      }      }
811  }  }
812    
813    /* the user clicked into the balloons main area. handle this */
814    static void
815    osm_gps_map_handle_balloon_click(OsmGpsMap *map, gint x, gint y)
816    {
817        OsmGpsMapPrivate *priv = map->priv;
818    
819        printf("clocked at %d %d\n", x, y);
820    
821        if (!priv->balloon.valid)
822            return;
823    
824        /* check if the close button was clicked */
825        if ((x > priv->balloon.rect.w - 2*CLOSE_BUTTON_RADIUS) &&
826            (x < priv->balloon.rect.w) &&
827            (y > 0) && (y < 2*CLOSE_BUTTON_RADIUS)) {
828    
829            priv->balloon.valid = FALSE;
830            osm_gps_map_map_redraw_idle(map);
831        }
832    }
833    
834    /* return true if balloon is being displayed and if */
835    /* the given coordinate is within this balloon */
836    static gboolean
837    osm_gps_map_in_balloon(OsmGpsMapPrivate *priv, gint x, gint y)
838    {
839        return (priv->balloon.valid &&
840                (x > priv->balloon.rect.x) &&
841                (x < priv->balloon.rect.x + priv->balloon.rect.w) &&
842                (y > priv->balloon.rect.y) &&
843                (y < priv->balloon.rect.y + priv->balloon.rect.h));
844    }
845    
846  static void  static void
847  osm_gps_map_blit_tile(OsmGpsMap *map, GdkPixbuf *pixbuf, int offset_x, int offset_y)  osm_gps_map_blit_tile(OsmGpsMap *map, GdkPixbuf *pixbuf, int offset_x, int offset_y)
848  {  {
# Line 1398  osm_gps_map_init (OsmGpsMap *object) Line 1459  osm_gps_map_init (OsmGpsMap *object)
1459      priv->gps = g_new0(coord_t, 1);      priv->gps = g_new0(coord_t, 1);
1460      priv->gps_valid = FALSE;      priv->gps_valid = FALSE;
1461    
1462      priv->balloon = g_new0(coord_t, 1);      priv->balloon.coo = g_new0(coord_t, 1);
1463      priv->balloon_valid = FALSE;      priv->balloon.valid = FALSE;
1464        priv->balloon.cb = NULL;
1465    
1466      priv->tracks = NULL;      priv->tracks = NULL;
1467      priv->images = NULL;      priv->images = NULL;
# Line 1559  osm_gps_map_dispose (GObject *object) Line 1621  osm_gps_map_dispose (GObject *object)
1621          g_source_remove (priv->idle_map_redraw);          g_source_remove (priv->idle_map_redraw);
1622    
1623      g_free(priv->gps);      g_free(priv->gps);
1624      g_free(priv->balloon);      g_free(priv->balloon.coo);
1625    
1626      G_OBJECT_CLASS (osm_gps_map_parent_class)->dispose (object);      G_OBJECT_CLASS (osm_gps_map_parent_class)->dispose (object);
1627  }  }
# Line 1776  osm_gps_map_button_press (GtkWidget *wid Line 1838  osm_gps_map_button_press (GtkWidget *wid
1838  {  {
1839      OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget);      OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget);
1840    
1841        /* don't drag if the user clicked within the balloon */
1842        if (osm_gps_map_in_balloon(priv,
1843                       event->x + EXTRA_BORDER,
1844                       event->y + EXTRA_BORDER))
1845        {
1846            priv->drag_counter = -1;
1847            return FALSE;
1848        }
1849    
1850      priv->drag_counter = 0;      priv->drag_counter = 0;
1851      priv->drag_start_mouse_x = (int) event->x;      priv->drag_start_mouse_x = (int) event->x;
1852      priv->drag_start_mouse_y = (int) event->y;      priv->drag_start_mouse_y = (int) event->y;
# Line 1790  osm_gps_map_button_release (GtkWidget *w Line 1861  osm_gps_map_button_release (GtkWidget *w
1861  {  {
1862      OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget);      OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget);
1863    
1864        /* released inside the balloon? */
1865        if (osm_gps_map_in_balloon(priv,
1866                       event->x + EXTRA_BORDER,
1867                       event->y + EXTRA_BORDER))
1868        {
1869            osm_gps_map_handle_balloon_click(OSM_GPS_MAP(widget),
1870                 event->x - priv->balloon.rect.x + EXTRA_BORDER,
1871                 event->y - priv->balloon.rect.y + EXTRA_BORDER);
1872            return FALSE;
1873        }
1874    
1875        if (priv->drag_counter < 0)
1876            return FALSE;
1877    
1878      if (priv->dragging)      if (priv->dragging)
1879      {      {
1880          priv->dragging = FALSE;          priv->dragging = FALSE;
# Line 1807  osm_gps_map_button_release (GtkWidget *w Line 1892  osm_gps_map_button_release (GtkWidget *w
1892    
1893      priv->drag_mouse_dx = 0;      priv->drag_mouse_dx = 0;
1894      priv->drag_mouse_dy = 0;      priv->drag_mouse_dy = 0;
1895      priv->drag_counter = 0;      priv->drag_counter = -1;
1896    
1897      return FALSE;      return FALSE;
1898  }  }
# Line 1832  osm_gps_map_motion_notify (GtkWidget *wi Line 1917  osm_gps_map_motion_notify (GtkWidget *wi
1917      if (!(state & GDK_BUTTON1_MASK))      if (!(state & GDK_BUTTON1_MASK))
1918          return FALSE;          return FALSE;
1919    
1920        if (priv->drag_counter < 0)
1921            return FALSE;
1922    
1923      priv->drag_counter++;      priv->drag_counter++;
1924    
1925      // we havent dragged more than 6 pixels      // we havent dragged more than 6 pixels
# Line 1934  osm_gps_map_expose (GtkWidget *widget, G Line 2022  osm_gps_map_expose (GtkWidget *widget, G
2022                         widget->window,                         widget->window,
2023                         widget->style->fg_gc[GTK_WIDGET_STATE (widget)],                         widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
2024                         priv->pixmap,                         priv->pixmap,
2025                         event->area.x + EXTRA_BORDER, event->area.y + EXTRA_BORDER,                         event->area.x + EXTRA_BORDER,
2026                           event->area.y + EXTRA_BORDER,
2027                         event->area.x, event->area.y,                         event->area.x, event->area.y,
2028                         event->area.width, event->area.height);                         event->area.width, event->area.height);
2029    
# Line 2710  osm_gps_map_get_scale(OsmGpsMap *map) Line 2799  osm_gps_map_get_scale(OsmGpsMap *map)
2799  }  }
2800    
2801  void  void
2802  osm_gps_map_draw_balloon (OsmGpsMap *map, float latitude, float longitude)  osm_gps_map_draw_balloon (OsmGpsMap *map, float latitude, float longitude,
2803                              OsmGpsMapBalloonCallback cb, gpointer data)
2804  {  {
2805      OsmGpsMapPrivate *priv;      OsmGpsMapPrivate *priv;
2806    
# Line 2720  osm_gps_map_draw_balloon (OsmGpsMap *map Line 2810  osm_gps_map_draw_balloon (OsmGpsMap *map
2810      g_return_if_fail (OSM_IS_GPS_MAP (map));      g_return_if_fail (OSM_IS_GPS_MAP (map));
2811      priv = map->priv;      priv = map->priv;
2812    
2813      priv->balloon->rlat = deg2rad(latitude);      priv->balloon.coo->rlat = deg2rad(latitude);
2814      priv->balloon->rlon = deg2rad(longitude);      priv->balloon.coo->rlon = deg2rad(longitude);
2815      priv->balloon_valid = TRUE;      priv->balloon.valid = TRUE;
2816    
2817        priv->balloon.cb = cb;
2818        priv->balloon.data = data;
2819    
2820      // this redraws the map      // this redraws the map
2821      osm_gps_map_map_redraw_idle(map);      osm_gps_map_map_redraw_idle(map);
# Line 2736  osm_gps_map_clear_balloon (OsmGpsMap *ma Line 2829  osm_gps_map_clear_balloon (OsmGpsMap *ma
2829      g_return_if_fail (OSM_IS_GPS_MAP (map));      g_return_if_fail (OSM_IS_GPS_MAP (map));
2830      priv = map->priv;      priv = map->priv;
2831    
2832      priv->balloon_valid = FALSE;      priv->balloon.valid = FALSE;
2833    
2834      osm_gps_map_map_redraw_idle(map);      osm_gps_map_map_redraw_idle(map);
2835  }  }

Legend:
Removed from v.57  
changed lines
  Added in v.58