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 59 by harbaum, Mon Aug 17 14:23:38 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        if (!priv->balloon.valid)
820            return;
821    
822        /* check if the close button was clicked */
823        if ((x > priv->balloon.rect.w - 2*CLOSE_BUTTON_RADIUS) &&
824            (x < priv->balloon.rect.w) &&
825            (y > 0) && (y < 2*CLOSE_BUTTON_RADIUS)) {
826    
827            priv->balloon.valid = FALSE;
828            osm_gps_map_map_redraw_idle(map);
829        }
830    }
831    
832    /* return true if balloon is being displayed and if */
833    /* the given coordinate is within this balloon */
834    static gboolean
835    osm_gps_map_in_balloon(OsmGpsMapPrivate *priv, gint x, gint y)
836    {
837        return (priv->balloon.valid &&
838                (x > priv->balloon.rect.x) &&
839                (x < priv->balloon.rect.x + priv->balloon.rect.w) &&
840                (y > priv->balloon.rect.y) &&
841                (y < priv->balloon.rect.y + priv->balloon.rect.h));
842    }
843    
844  static void  static void
845  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)
846  {  {
# Line 1398  osm_gps_map_init (OsmGpsMap *object) Line 1457  osm_gps_map_init (OsmGpsMap *object)
1457      priv->gps = g_new0(coord_t, 1);      priv->gps = g_new0(coord_t, 1);
1458      priv->gps_valid = FALSE;      priv->gps_valid = FALSE;
1459    
1460      priv->balloon = g_new0(coord_t, 1);      priv->balloon.coo = g_new0(coord_t, 1);
1461      priv->balloon_valid = FALSE;      priv->balloon.valid = FALSE;
1462        priv->balloon.cb = NULL;
1463    
1464      priv->tracks = NULL;      priv->tracks = NULL;
1465      priv->images = NULL;      priv->images = NULL;
# Line 1559  osm_gps_map_dispose (GObject *object) Line 1619  osm_gps_map_dispose (GObject *object)
1619          g_source_remove (priv->idle_map_redraw);          g_source_remove (priv->idle_map_redraw);
1620    
1621      g_free(priv->gps);      g_free(priv->gps);
1622      g_free(priv->balloon);      g_free(priv->balloon.coo);
1623    
1624      G_OBJECT_CLASS (osm_gps_map_parent_class)->dispose (object);      G_OBJECT_CLASS (osm_gps_map_parent_class)->dispose (object);
1625  }  }
# Line 1776  osm_gps_map_button_press (GtkWidget *wid Line 1836  osm_gps_map_button_press (GtkWidget *wid
1836  {  {
1837      OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget);      OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget);
1838    
1839        /* don't drag if the user clicked within the balloon */
1840        if (osm_gps_map_in_balloon(priv,
1841                       event->x + EXTRA_BORDER,
1842                       event->y + EXTRA_BORDER))
1843        {
1844            priv->drag_counter = -1;
1845            return FALSE;
1846        }
1847    
1848      priv->drag_counter = 0;      priv->drag_counter = 0;
1849      priv->drag_start_mouse_x = (int) event->x;      priv->drag_start_mouse_x = (int) event->x;
1850      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 1859  osm_gps_map_button_release (GtkWidget *w
1859  {  {
1860      OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget);      OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget);
1861    
1862        /* released inside the balloon? */
1863        if (osm_gps_map_in_balloon(priv,
1864                       event->x + EXTRA_BORDER,
1865                       event->y + EXTRA_BORDER))
1866        {
1867            osm_gps_map_handle_balloon_click(OSM_GPS_MAP(widget),
1868                 event->x - priv->balloon.rect.x + EXTRA_BORDER,
1869                 event->y - priv->balloon.rect.y + EXTRA_BORDER);
1870            return FALSE;
1871        }
1872    
1873        if (priv->drag_counter < 0)
1874            return FALSE;
1875    
1876      if (priv->dragging)      if (priv->dragging)
1877      {      {
1878          priv->dragging = FALSE;          priv->dragging = FALSE;
# Line 1807  osm_gps_map_button_release (GtkWidget *w Line 1890  osm_gps_map_button_release (GtkWidget *w
1890    
1891      priv->drag_mouse_dx = 0;      priv->drag_mouse_dx = 0;
1892      priv->drag_mouse_dy = 0;      priv->drag_mouse_dy = 0;
1893      priv->drag_counter = 0;      priv->drag_counter = -1;
1894    
1895      return FALSE;      return FALSE;
1896  }  }
# Line 1832  osm_gps_map_motion_notify (GtkWidget *wi Line 1915  osm_gps_map_motion_notify (GtkWidget *wi
1915      if (!(state & GDK_BUTTON1_MASK))      if (!(state & GDK_BUTTON1_MASK))
1916          return FALSE;          return FALSE;
1917    
1918        if (priv->drag_counter < 0)
1919            return FALSE;
1920    
1921      priv->drag_counter++;      priv->drag_counter++;
1922    
1923      // we havent dragged more than 6 pixels      // we havent dragged more than 6 pixels
# Line 1934  osm_gps_map_expose (GtkWidget *widget, G Line 2020  osm_gps_map_expose (GtkWidget *widget, G
2020                         widget->window,                         widget->window,
2021                         widget->style->fg_gc[GTK_WIDGET_STATE (widget)],                         widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
2022                         priv->pixmap,                         priv->pixmap,
2023                         event->area.x + EXTRA_BORDER, event->area.y + EXTRA_BORDER,                         event->area.x + EXTRA_BORDER,
2024                           event->area.y + EXTRA_BORDER,
2025                         event->area.x, event->area.y,                         event->area.x, event->area.y,
2026                         event->area.width, event->area.height);                         event->area.width, event->area.height);
2027    
# Line 2710  osm_gps_map_get_scale(OsmGpsMap *map) Line 2797  osm_gps_map_get_scale(OsmGpsMap *map)
2797  }  }
2798    
2799  void  void
2800  osm_gps_map_draw_balloon (OsmGpsMap *map, float latitude, float longitude)  osm_gps_map_draw_balloon (OsmGpsMap *map, float latitude, float longitude,
2801                              OsmGpsMapBalloonCallback cb, gpointer data)
2802  {  {
2803      OsmGpsMapPrivate *priv;      OsmGpsMapPrivate *priv;
2804    
# Line 2720  osm_gps_map_draw_balloon (OsmGpsMap *map Line 2808  osm_gps_map_draw_balloon (OsmGpsMap *map
2808      g_return_if_fail (OSM_IS_GPS_MAP (map));      g_return_if_fail (OSM_IS_GPS_MAP (map));
2809      priv = map->priv;      priv = map->priv;
2810    
2811      priv->balloon->rlat = deg2rad(latitude);      priv->balloon.coo->rlat = deg2rad(latitude);
2812      priv->balloon->rlon = deg2rad(longitude);      priv->balloon.coo->rlon = deg2rad(longitude);
2813      priv->balloon_valid = TRUE;      priv->balloon.valid = TRUE;
2814    
2815        priv->balloon.cb = cb;
2816        priv->balloon.data = data;
2817    
2818      // this redraws the map      // this redraws the map
2819      osm_gps_map_map_redraw_idle(map);      osm_gps_map_map_redraw_idle(map);
# Line 2736  osm_gps_map_clear_balloon (OsmGpsMap *ma Line 2827  osm_gps_map_clear_balloon (OsmGpsMap *ma
2827      g_return_if_fail (OSM_IS_GPS_MAP (map));      g_return_if_fail (OSM_IS_GPS_MAP (map));
2828      priv = map->priv;      priv = map->priv;
2829    
2830      priv->balloon_valid = FALSE;      priv->balloon.valid = FALSE;
2831    
2832      osm_gps_map_map_redraw_idle(map);      osm_gps_map_map_redraw_idle(map);
2833  }  }

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