]> err.no Git - mapper/commitdiff
Copy & Paste some more code from map.c to gtkmap.c
authorKaj-Michael Lang <milang@tal.org>
Tue, 29 Apr 2008 10:36:50 +0000 (13:36 +0300)
committerKaj-Michael Lang <milang@tal.org>
Tue, 29 Apr 2008 10:36:50 +0000 (13:36 +0300)
src/gtkmap.c

index b12f55fb038b314bf297b77734defbd68ebb0492..d3cd94f546a1672c35aa70e99707856517776ba1 100644 (file)
@@ -132,7 +132,7 @@ gtk_map_new(void)
 GtkMap *map;
 GtkWidget *widget;
 
-map=gtk_type_new(gtk_map_get_type ());
+map=g_object_new(GTK_MAP_TYPE, NULL);
 widget=GTK_WIDGET(map);
 map->heading=0;
 
@@ -184,7 +184,7 @@ map->height=256;
 }
 
 static void 
-gtk_map_realize (GtkWidget *widget)
+gtk_map_realize(GtkWidget *widget)
 {
 GtkMap *map;
        
@@ -202,9 +202,183 @@ g_return_val_if_fail(event != NULL, FALSE);
 
 map=GTK_MAP(widget);
 
+gdk_draw_drawable(GDK_DRAWABLE(map->widget->window),
+               map->gc[COLORABLE_MARK],
+               map->pixmap,
+               event->area.x + map->offsetx, event->area.y + map->offsety,
+               event->area.x, event->area.y,
+               event->area.width, event->area.height);
+
 return TRUE;
 }
 
+static void 
+map_scale_draw(GtkWidget *widget, GdkEventExpose *event)
+{
+GtkMap *map;
+gchar buffer[16];
+gdouble distance;
+gdouble lat1, lon1, lat2, lon2;
+gint width;
+
+g_return_if_fail(GTK_IS_MAP(widget));
+map=GTK_MAP(widget);
+
+pango_layout_set_text(scale_layout, "0", -1);
+pango_layout_get_pixel_size(scale_layout, NULL, &scale_rect.height);
+scale_rect.y = _screen_height_pixels - scale_rect.height - 1;
+
+gdk_rectangle_intersect(&event->area, &scale_rect, &event->area);
+
+if (event->area.width && event->area.height) {
+       gdk_draw_rectangle(_map_widget->window,
+                          _map_widget->style->bg_gc[GTK_WIDGET_STATE(_map_widget)],
+                          TRUE, scale_rect.x, scale_rect.y,
+                          scale_rect.width,
+                          scale_rect.height);
+       gdk_draw_rectangle(_map_widget->window,
+                          _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)],
+                          FALSE, scale_rect.x, scale_rect.y,
+                          scale_rect.width,
+                          scale_rect.height);
+
+       /* Now calculate and draw the distance. */
+       unit2latlon(_center.unitx - pixel2unit(SCALE_WIDTH / 2 - 4), _center.unity, lat1, lon1);
+       unit2latlon(_center.unitx + pixel2unit(SCALE_WIDTH / 2 - 4), _center.unity, lat2, lon2);
+       distance=calculate_distance(lat1, lon1, lat2, lon2) * UNITS_CONVERT[_units];
+
+       if (distance < 1.f)
+               g_snprintf(buffer, sizeof(buffer), "%0.2f %s", distance, UNITS_TEXT[_units]);
+       else if (distance < 10.f)
+               g_snprintf(buffer, sizeof(buffer), "%0.1f %s", distance, UNITS_TEXT[_units]);
+       else
+               g_snprintf(buffer, sizeof(buffer), "%0.f %s", distance, UNITS_TEXT[_units]);
+
+       pango_layout_set_text(scale_layout, buffer, -1);
+       pango_layout_get_pixel_size(scale_layout, &width, NULL);
+
+       /* Draw the layout itself. */
+       gdk_draw_layout(_map_widget->window,
+                       _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)],
+                       scale_rect.x + (scale_rect.width - width) / 2,
+                       scale_rect.y, scale_layout);
+
+       /* Draw little hashes on the ends. */
+       gdk_draw_line(_map_widget->window,
+                     _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)],
+                     scale_rect.x + 4,
+                     scale_rect.y + scale_rect.height / 2 - 4,
+                     scale_rect.x + 4,
+                     scale_rect.y + scale_rect.height / 2 + 4);
+       gdk_draw_line(_map_widget->window,
+                     _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)],
+                     scale_rect.x + 4,
+                     scale_rect.y + scale_rect.height / 2,
+                     scale_rect.x + (scale_rect.width - width) / 2 - 4,
+                     scale_rect.y + scale_rect.height / 2);
+       gdk_draw_line(_map_widget->window,
+                     _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)],
+                     scale_rect.x + scale_rect.width - 4,
+                     scale_rect.y + scale_rect.height / 2 - 4,
+                     scale_rect.x + scale_rect.width - 4,
+                     scale_rect.y + scale_rect.height / 2 + 4);
+       gdk_draw_line(_map_widget->window,
+                     _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)],
+                     scale_rect.x + scale_rect.width - 4,
+                     scale_rect.y + scale_rect.height / 2,
+                     scale_rect.x + (scale_rect.width + width) / 2 + 4,
+                     scale_rect.y + scale_rect.height / 2);
+       }
+}
+
+static void
+map_information_text(GtkWidget *widget, guint x, guint y, GdkGC *gc, gchar *msg)
+{
+guint width, height;
+
+g_return_if_fail(GTK_IS_MAP(widget));
+map=GTK_MAP(widget);
+
+pango_layout_set_text(speed_layout, msg, -1);
+pango_layout_get_pixel_size(speed_layout, &width, &height);
+gtk_widget_queue_draw_area(_map_widget, x - 5, y - 5, width * 3 + 15, height + 5);
+gdk_window_process_all_updates();
+gdk_draw_layout(_map_widget->window, gc, x, y, speed_layout);
+gdk_window_process_all_updates();
+}
+
+static void
+map_speed_draw(GtkWidget *widget, gfloat speed, gboolean overspeed)
+{
+GdkGC *gc;
+gfloat cur_speed;
+gchar *buffer;
+
+g_return_if_fail(GTK_IS_MAP(widget));
+map=GTK_MAP(widget);
+
+gc=(overspeed) ? speed_gc1 : speed_gc2;
+buffer = g_strdup_printf("%0.0f", speed);
+map_information_text(10, 10, gc, buffer);
+g_free(buffer);
+}
+
+/**
+ * Do an in-place scaling of a pixbuf's pixels at the given ratio from the
+ * given source location.  It would have been nice if gdk_pixbuf provided
+ * this method, but I guess it's not general-purpose enough.
+ */
+static void
+map_pixbuf_scale_inplace(GdkPixbuf *pixbuf, guint ratio_p2, guint src_x, guint src_y)
+{
+guint dest_x = 0, dest_y = 0, dest_dim = TILE_SIZE_PIXELS;
+guint rowstride = gdk_pixbuf_get_rowstride(pixbuf);
+guint n_channels = gdk_pixbuf_get_n_channels(pixbuf);
+guchar *pixels = gdk_pixbuf_get_pixels(pixbuf);
+
+/* Sweep through the entire dest area, copying as necessary, but
+ * DO NOT OVERWRITE THE SOURCE AREA.  We'll copy it afterward. */
+do {
+       guint src_dim = dest_dim >> ratio_p2;
+       guint src_endx = src_x - dest_x + src_dim;
+       gint x, y;
+
+       for (y = dest_dim - 1; y >= 0; y--) {
+               guint src_offset_y, dest_offset_y;
+
+               src_offset_y = (src_y + (y >> ratio_p2)) * rowstride;
+               dest_offset_y = (dest_y + y) * rowstride;
+               x = dest_dim - 1;
+
+               if ((unsigned)(dest_y + y - src_y) < src_dim && (unsigned)(dest_x + x - src_x) < src_dim)
+                       x -= src_dim;
+
+               for (; x >= 0; x--) {
+                       guint src_offset, dest_offset, i;
+
+                       src_offset = src_offset_y + (src_x + (x >> ratio_p2)) * n_channels;
+                       dest_offset = dest_offset_y + (dest_x + x) * n_channels;
+
+                       pixels[dest_offset] = pixels[src_offset];
+                       for (i = n_channels - 1; i; i--)
+                               pixels[dest_offset + i] = pixels[src_offset + i];
+
+                       if ((unsigned)(dest_y + y - src_y) < src_dim && x == src_endx)
+                               x -= src_dim;
+               }
+       }
+
+       /* Reuse src_dim and src_endx to store new src_x and src_y. */
+       src_dim = src_x + ((src_x - dest_x) >> ratio_p2);
+       src_endx = src_y + ((src_y - dest_y) >> ratio_p2);
+       dest_x = src_x;
+       dest_y = src_y;
+       src_x = src_dim;
+       src_y = src_endx;
+}
+while ((dest_dim >>= ratio_p2) > 1);
+}
+
 void
 gtk_map_refresh(GtkWidget *widget)
 {
@@ -215,3 +389,36 @@ g_return_if_fail(GTK_IS_MAP(widget));
 map=GTK_MAP(widget);
 gtk_widget_queue_draw_area(widget, 0, 0, map->width, map->height);
 }
+
+gint 
+map_zoom(GtkWidget *widget, gint zdir)
+{
+gint nzoom;
+GtkMap *map;
+
+g_return_val_if_fail(GTK_IS_MAP(widget), -1);
+
+map=GTK_MAP(widget);
+
+nzoom=map->zoom+zdir;
+if ((nzoom >= 0) && (nzoom < map->max_zoom - 1)) {
+       map_set_zoom(widget, nzoom);
+}
+return nzoom;
+}
+
+gboolean
+map_zoom_in(GtkWidget *widget)
+{
+g_return_val_if_fail(GTK_IS_MAP(widget), FALSE);
+map_zoom(widget, -1);
+return FALSE;
+}
+
+gboolean
+map_zoom_out(GtkWidget *widget)
+{
+g_return_val_if_fail(GTK_IS_MAP(widget), FALSE);
+map_zoom(widget, 1);
+return FALSE;
+}