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

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

revision 56 by harbaum, Fri Aug 14 12:19:45 2009 UTC revision 57 by harbaum, Sun Aug 16 19:29:01 2009 UTC
# Line 98  struct _OsmGpsMapPrivate Line 98  struct _OsmGpsMapPrivate
98      coord_t *gps;      coord_t *gps;
99      gboolean gps_valid;      gboolean gps_valid;
100    
101        //a balloon with additional info
102        coord_t *balloon;
103        gboolean balloon_valid;
104    
105      //additional images or tracks added to the map      //additional images or tracks added to the map
106      GSList *tracks;      GSList *tracks;
107      GSList *images;      GSList *images;
# Line 631  osm_gps_map_draw_gps_point (OsmGpsMap *m Line 635  osm_gps_map_draw_gps_point (OsmGpsMap *m
635                                      (mr*2)+lw+lw);                                      (mr*2)+lw+lw);
636  #endif  #endif
637      }      }
638    }
639    
640    /* most visual effects are hardcoded by now, but may be made */
641    /* available via properties later */
642    #define BALLOON_CORNER_RADIUS         20
643    #define BALLOON_WIDTH                150
644    #define BALLOON_HEIGHT                75
645    #define BALLOON_TRANSPARENCY         0.8
646    #define POINTER_HEIGHT                20
647    #define POINTER_FOOT_WIDTH            20
648    #define POINTER_OFFSET               (BALLOON_CORNER_RADIUS*3/4)
649    #define BALLOON_SHADOW                5
650    #define BALLOON_SHADOW_TRANSPARENCY  0.2
651    
652    /* draw the bubble shape. this is used twice, once for the shape and once */
653    /* for the shadow */
654    static void
655    osm_gps_map_draw_balloon_shape (cairo_t *cr, int x0, int y0, int x1, int y1,
656           gboolean bottom, int px, int py, int px0, int px1) {
657    
658        cairo_move_to (cr, x0, y0 + BALLOON_CORNER_RADIUS);
659        cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + BALLOON_CORNER_RADIUS, y0);
660        if(!bottom) {
661            /* insert bottom/left pointer */
662            cairo_line_to (cr, px1, y0);
663            cairo_line_to (cr, px, py);
664            cairo_line_to (cr, px0, y0);
665        }
666    
667        cairo_line_to (cr, x1 - BALLOON_CORNER_RADIUS, y0);
668        cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + BALLOON_CORNER_RADIUS);
669        cairo_line_to (cr, x1 , y1 - BALLOON_CORNER_RADIUS);
670        cairo_curve_to (cr, x1, y1, x1, y1, x1 - BALLOON_CORNER_RADIUS, y1);
671        if(bottom) {
672            /* insert bottom/left pointer */
673            cairo_line_to (cr, px0, y1);
674            cairo_line_to (cr, px, py);
675            cairo_line_to (cr, px1, y1);
676        }
677    
678        cairo_line_to (cr, x0 + BALLOON_CORNER_RADIUS, y1);
679        cairo_curve_to (cr, x0, y1, x0, y1, x0, y1 - BALLOON_CORNER_RADIUS);
680    
681        cairo_close_path (cr);
682  }  }
683    
684  /* http://cairographics.org/samples/ */  /* http://cairographics.org/samples/ */
685  static void  static void
686  osm_gps_map_draw_balloon (OsmGpsMap *map)  osm_gps_map_draw_balloon_int (OsmGpsMap *map)
687  {  {
688      OsmGpsMapPrivate *priv = map->priv;      OsmGpsMapPrivate *priv = map->priv;
689    
690      /* xyz */      if (priv->balloon_valid) {
 #define X 100  
 #define Y 100  
 #define RADIUS 20  
 #define WIDTH  150  
 #define HEIGHT 75  
 #define TRANSPARENCY  0.7  
 #define PIN_HEIGHT 20  
 #define PIN_FOOT_WIDTH 20  
 #define PIN_X  (X + EXTRA_BORDER)  
 #define PIN_X0 (X + EXTRA_BORDER + RADIUS + PIN_FOOT_WIDTH)  
 #define PIN_X1 (X + EXTRA_BORDER + RADIUS)  
 #define PIN_Y  (Y + EXTRA_BORDER + HEIGHT + PIN_HEIGHT)  
   
 #ifdef USE_CAIRO  
     cairo_t *cr = gdk_cairo_create(priv->pixmap);  
691    
692      int x0 = X + EXTRA_BORDER, y0 = Y + EXTRA_BORDER;          /* ------- convert given coordinate into screen position --------- */
693      int x1 = x0 + WIDTH, y1 = y0 + HEIGHT;          int x0 = lon2pixel(priv->map_zoom, priv->balloon->rlon) -
694                priv->map_x + EXTRA_BORDER;
695            int y0 = lat2pixel(priv->map_zoom, priv->balloon->rlat) -
696                priv->map_y + EXTRA_BORDER;
697    
698      cairo_move_to (cr, x0, y0 + RADIUS);          /* check position of this relative to screen center to determine */
699      cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + RADIUS, y0);          /* pointer direction ... */
700      cairo_line_to (cr, x1 - RADIUS, y0);          int pointer_x = x0, pointer_x0, pointer_x1;
701      cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + RADIUS);          int pointer_y = y0;
     cairo_line_to (cr, x1 , y1 - RADIUS);  
     cairo_curve_to (cr, x1, y1, x1, y1, x1 - RADIUS, y1);  
   
     /* insert pin */  
     cairo_line_to (cr, PIN_X0, y1);  
     cairo_line_to (cr, PIN_X, PIN_Y);  
     cairo_line_to (cr, PIN_X1, y1);  
   
702    
703      cairo_line_to (cr, x0 + RADIUS, y1);          /* ... and calculate position */
704      cairo_curve_to (cr, x0, y1, x0, y1, x0, y1 - RADIUS);          if((x0 - EXTRA_BORDER) > GTK_WIDGET(map)->allocation.width/2) {
705                x0 -= BALLOON_WIDTH - POINTER_OFFSET;
706                pointer_x0 = pointer_x - (BALLOON_CORNER_RADIUS - POINTER_OFFSET);
707                pointer_x1 = pointer_x0 - POINTER_FOOT_WIDTH;
708            } else {
709                x0 -= POINTER_OFFSET;
710                pointer_x1 = pointer_x + (BALLOON_CORNER_RADIUS - POINTER_OFFSET);
711                pointer_x0 = pointer_x1 + POINTER_FOOT_WIDTH;
712            }
713    
714            gboolean bottom = FALSE;
715            if((y0 - EXTRA_BORDER) > GTK_WIDGET(map)->allocation.height/2) {
716                bottom = TRUE;
717                y0 -= BALLOON_HEIGHT + POINTER_HEIGHT;
718            } else
719                y0 += POINTER_HEIGHT;
720    
721            /* calculate bottom/right of box */
722            int x1 = x0 + BALLOON_WIDTH, y1 = y0 + BALLOON_HEIGHT;
723    
724      cairo_close_path (cr);  #ifdef USE_CAIRO
725      cairo_set_source_rgba (cr, 1, 1, 1, TRANSPARENCY);          cairo_t *cr = gdk_cairo_create(priv->pixmap);
726      cairo_fill_preserve (cr);  
727      cairo_set_source_rgba (cr, 0, 0, 0, TRANSPARENCY);          /* --------- draw shadow --------------- */
728      cairo_set_line_width (cr, 1);          osm_gps_map_draw_balloon_shape (cr,
729      cairo_stroke (cr);                      x0 + BALLOON_SHADOW, y0 + BALLOON_SHADOW,
730                        x1 + BALLOON_SHADOW, y1 + BALLOON_SHADOW,
731      gtk_widget_queue_draw_area (GTK_WIDGET(map),                      bottom, pointer_x, pointer_y,
732                                  x0,                      pointer_x0 + BALLOON_SHADOW, pointer_x1 + BALLOON_SHADOW);
733                                  y0,  
734                                  WIDTH,          cairo_set_source_rgba (cr, 0, 0, 0, BALLOON_SHADOW_TRANSPARENCY);
735                                  HEIGHT + PIN_HEIGHT);          cairo_fill_preserve (cr);
736            cairo_set_source_rgba (cr, 1, 0, 0, 1.0);
737            cairo_set_line_width (cr, 0);
738            cairo_stroke (cr);
739    
740            /* --------- draw main shape ----------- */
741            osm_gps_map_draw_balloon_shape (cr, x0, y0, x1, y1,
742                        bottom, pointer_x, pointer_y, pointer_x0, pointer_x1);
743    
744            cairo_set_source_rgba (cr, 1, 1, 1, BALLOON_TRANSPARENCY);
745            cairo_fill_preserve (cr);
746            cairo_set_source_rgba (cr, 0, 0, 0, BALLOON_TRANSPARENCY);
747            cairo_set_line_width (cr, 1);
748            cairo_stroke (cr);
749    
750    
751            /* ---------- draw close button --------- */
752    
753            int cx = x1 - BALLOON_CORNER_RADIUS*3/4;
754            int cy = y0 + BALLOON_CORNER_RADIUS*3/4;
755            int crad = BALLOON_CORNER_RADIUS/3;
756    
757            cairo_arc (cr, cx, cy, crad, 0, 2 * M_PI);
758            cairo_set_source_rgba (cr, 0.8, 0, 0, 1.0);
759            cairo_fill_preserve (cr);
760            cairo_set_source_rgba (cr, 0.3, 0, 0, 1.0);
761            cairo_set_line_width (cr, 1);
762            cairo_stroke(cr);
763    
764            int cs = crad/2;
765            cairo_set_source_rgba (cr, 1, 1, 1, 1.0);
766            cairo_set_line_width (cr, 3);
767            cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
768            cairo_move_to (cr, cx - cs, cy - cs);
769            cairo_line_to (cr, cx + cs, cy + cs);
770            cairo_stroke (cr);
771            cairo_move_to (cr, cx + cs, cy - cs);
772            cairo_line_to (cr, cx - cs, cy + cs);
773            cairo_stroke (cr);
774    
775    
776            gtk_widget_queue_draw_area (GTK_WIDGET(map),
777                                        x0, y0, BALLOON_WIDTH,
778                                        BALLOON_HEIGHT + POINTER_HEIGHT);
779    #else
780    #warning "Balloon display lacks a non-cairo implementation!"
781  #endif  #endif
782        }
783  }  }
784    
785  static void  static void
# Line 1274  osm_gps_map_map_redraw (OsmGpsMap *map) Line 1366  osm_gps_map_map_redraw (OsmGpsMap *map)
1366      osm_gps_map_print_tracks(map);      osm_gps_map_print_tracks(map);
1367      osm_gps_map_draw_gps_point(map);      osm_gps_map_draw_gps_point(map);
1368      osm_gps_map_print_images(map);      osm_gps_map_print_images(map);
1369        osm_gps_map_draw_balloon_int(map);
     osm_gps_map_draw_balloon(map);  
1370    
1371      //osm_gps_map_osd_speed(map, 1.5);      //osm_gps_map_osd_speed(map, 1.5);
1372      osm_gps_map_purge_cache(map);      osm_gps_map_purge_cache(map);
# Line 1307  osm_gps_map_init (OsmGpsMap *object) Line 1398  osm_gps_map_init (OsmGpsMap *object)
1398      priv->gps = g_new0(coord_t, 1);      priv->gps = g_new0(coord_t, 1);
1399      priv->gps_valid = FALSE;      priv->gps_valid = FALSE;
1400    
1401        priv->balloon = g_new0(coord_t, 1);
1402        priv->balloon_valid = FALSE;
1403    
1404      priv->tracks = NULL;      priv->tracks = NULL;
1405      priv->images = NULL;      priv->images = NULL;
1406    
# Line 1464  osm_gps_map_dispose (GObject *object) Line 1558  osm_gps_map_dispose (GObject *object)
1558      if (priv->idle_map_redraw != 0)      if (priv->idle_map_redraw != 0)
1559          g_source_remove (priv->idle_map_redraw);          g_source_remove (priv->idle_map_redraw);
1560    
1561        g_free(priv->gps);
1562        g_free(priv->balloon);
1563    
1564      G_OBJECT_CLASS (osm_gps_map_parent_class)->dispose (object);      G_OBJECT_CLASS (osm_gps_map_parent_class)->dispose (object);
1565  }  }
1566    
# Line 2612  osm_gps_map_get_scale(OsmGpsMap *map) Line 2709  osm_gps_map_get_scale(OsmGpsMap *map)
2709      return osm_gps_map_get_scale_at_point(priv->map_zoom, priv->center_rlat, priv->center_rlon);      return osm_gps_map_get_scale_at_point(priv->map_zoom, priv->center_rlat, priv->center_rlon);
2710  }  }
2711    
2712    void
2713    osm_gps_map_draw_balloon (OsmGpsMap *map, float latitude, float longitude)
2714    {
2715        OsmGpsMapPrivate *priv;
2716    
2717        /* remove and previously installed balloon */
2718        osm_gps_map_clear_balloon (map);
2719    
2720        g_return_if_fail (OSM_IS_GPS_MAP (map));
2721        priv = map->priv;
2722    
2723        priv->balloon->rlat = deg2rad(latitude);
2724        priv->balloon->rlon = deg2rad(longitude);
2725        priv->balloon_valid = TRUE;
2726    
2727        // this redraws the map
2728        osm_gps_map_map_redraw_idle(map);
2729    }
2730    
2731    void
2732    osm_gps_map_clear_balloon (OsmGpsMap *map)
2733    {
2734        OsmGpsMapPrivate *priv;
2735    
2736        g_return_if_fail (OSM_IS_GPS_MAP (map));
2737        priv = map->priv;
2738    
2739        priv->balloon_valid = FALSE;
2740    
2741        osm_gps_map_map_redraw_idle(map);
2742    }

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