]> err.no Git - mapper/commitdiff
Copy over some more code
authorKaj-Michael Lang <milang@tal.org>
Wed, 30 Apr 2008 07:18:58 +0000 (10:18 +0300)
committerKaj-Michael Lang <milang@tal.org>
Wed, 30 Apr 2008 07:18:58 +0000 (10:18 +0300)
src/gtkmap.c

index 6a8dd861614da0d9f248c6be5e1fd37b267cd905..c16b639f466f4b3bccddbd96d7d8af8ed361f944 100644 (file)
@@ -184,6 +184,10 @@ enum {
        MAP_ZOOMED_IN,
        MAP_ZOOMED_OUT,
 
+       MAP_PANNED,
+
+       MARKER_CLICK,
+
        LAST_SIGNAL
 };
 
@@ -271,6 +275,8 @@ if (priv->gl_config) {
 }
 #endif
 
+priv->buffer=NULL;
+
 gtk_widget_set_extension_events(GTK_WIDGET(map), GDK_EXTENSION_EVENTS_ALL);
 
 gtk_widget_add_events(GTK_WIDGET(map), GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
@@ -376,9 +382,11 @@ g_return_val_if_fail(event != NULL, FALSE);
 map=GTK_MAP(widget);
 priv=GTK_MAP_GET_PRIVATE(map);
 
+g_return_val_if_fail(priv->buffer, FALSE);
+
 style=widget->style;
 
-gdk_draw_drawable(GDK_DRAWABLE(map->map),
+gdk_draw_drawable(GDK_DRAWABLE(map),
                style->fg_gc[GTK_STATE_NORMAL],
                priv->buffer,
                event->area.x + priv->offsetx, 
@@ -565,6 +573,147 @@ do {
 while ((dest_dim >>= ratio_p2) > 1);
 }
 
+static gboolean
+gtk_map_render_tile(GtkWidget *widget, guint tilex, guint tiley, guint destx, guint desty, gboolean fast_fail)
+{
+GtkMap *map;
+GtkMapPriv *priv;
+GdkPixbuf *pixbuf=NULL;
+gint zoff;
+
+g_return_if_fail(GTK_IS_MAP(widget));
+map=GTK_MAP(widget);
+priv=GTK_MAP_GET_PRIVATE(map);
+
+g_return_val_if_fail(priv->buffer, FALSE);
+
+if (destx > priv->buf_width_pixels || desty > priv->buf_height_pixels)
+       return FALSE;
+
+if (tilex > priv->world_size_tiles || tiley > priv->world_size_tiles)
+       return FALSE;
+
+/* g_debug("MAP RT: %u %u (%u) %u %u (%u, %u)", tilex, tiley, priv->world_size_tiles, destx, desty, buf_width_tiles, buf_height_tiles); */
+
+/* The tile is possible. */
+for (zoff = (_curr_repo->double_size ? 1 : 0); !pixbuf && (priv->zoom + zoff) <= priv->max_zoom && zoff <= TILE_SIZE_P2; zoff += 1) {
+       pixbuf=gtk_map_tile_load(map, tilex, tiley, zoff, !fast_fail);
+       if (!pixbuf) {
+               if (!fast_fail)
+                       fast_fail=TRUE;
+       } else {
+               /* Check if we need to blit. */
+               if (zoff) {
+                       gtk_map_pixbuf_scale_inplace(pixbuf, zoff,
+                                       (tilex - ((tilex >> zoff) << zoff)) << (TILE_SIZE_P2 - zoff),
+                                       (tiley - ((tiley >> zoff) << zoff)) << (TILE_SIZE_P2 - zoff));
+                       image_cache_invalidate_by_image(priv->icache, pixbuf);
+               }
+       }
+}
+
+if (pixbuf) {
+       gdk_draw_pixbuf(priv->buffer, _gc[COLORABLE_MARK], pixbuf, 0, 0, destx, desty, TILE_SIZE_PIXELS, TILE_SIZE_PIXELS, GDK_RGB_DITHER_NONE, 0, 0);
+       g_object_unref(pixbuf);
+       return TRUE;
+}
+gdk_draw_rectangle(priv->buffer, map->style->black_gc, TRUE, destx, desty, TILE_SIZE_PIXELS, TILE_SIZE_PIXELS);
+return TRUE;
+}
+
+gboolean
+gtk_map_set_center(GtkWidget *map, guint new_center_unitx, guint new_center_unity)
+{
+GtkMap *map;
+GtkMapPriv *priv;
+
+g_return_val_if_fail(GTK_IS_MAP(widget), FALSE);
+
+map=GTK_MAP(widget);
+priv=GTK_MAP_GET_PRIVATE(map);
+
+gint new_base_tilex, new_base_tiley;
+guint new_x, new_y;
+guint j, k, base_new_x, base_old_x, old_x, old_y, iox, ioy;
+
+/* Assure that _center.unitx/y are bounded. */
+BOUND(new_center_unitx, priv->min_center.unitx, priv->max_center.unitx);
+BOUND(new_center_unity, priv->min_center.unity, priv->max_center.unity);
+
+priv->center.unitx = new_center_unitx;
+priv->center.unity = new_center_unity;
+
+new_base_tilex = grid2tile((gint) pixel2grid((gint)unit2pixel((gint) priv->center.unitx)) - (gint)priv->screen_grids_halfwidth);
+new_base_tiley = grid2tile(pixel2grid(unit2pixel(priv->center.unity)) - priv->screen_grids_halfheight);
+
+/* Same zoom level, so it's likely that we can reuse some of the old
+ * buffer's pixels. */
+
+if (new_base_tilex != priv->base_tilex || new_base_tiley != priv->base_tiley) {
+       /* If copying from old parts to new parts, we need to make sure we
+        * don't overwrite the old parts when copying, so set up new_x,
+        * new_y, old_x, old_y, iox, and ioy with that in mind. */
+       if (new_base_tiley < priv->base_tiley) {
+               /* New is lower than old - start at bottom and go up. */
+               new_y = buf_height_tiles - 1;
+               ioy = -1;
+       } else {
+               /* New is higher than old - start at top and go down. */
+               new_y = 0;
+               ioy = 1;
+       }
+       if (new_base_tilex < priv->base_tilex) {
+               /* New is righter than old - start at right and go left. */
+               base_new_x = buf_width_tiles - 1;
+               iox = -1;
+       } else {
+               /* New is lefter than old - start at left and go right. */
+               base_new_x = 0;
+               iox = 1;
+       }
+
+       /* Iterate over the y tile values. */
+       old_y = new_y + new_base_tiley - priv->base_tiley;
+       base_old_x = base_new_x + new_base_tilex - priv->base_tilex;
+       priv->base_tilex = new_base_tilex;
+       priv->base_tiley = new_base_tiley;
+
+       for (j = 0; j < buf_height_tiles; ++j, new_y += ioy, old_y += ioy) {
+               new_x = base_new_x;
+               old_x = base_old_x;
+               /* Iterate over the x tile values. */
+               for (k = 0; k < buf_width_tiles; ++k, new_x += iox, old_x += iox) {
+                       /* Can we get this grid block from the old buffer?. */
+                       if (old_x >= 0 && old_x < buf_width_tiles && old_y >= 0 && old_y < buf_height_tiles) {
+                               /* Copy from old buffer to new buffer. */
+                               gdk_draw_drawable(priv->buffer,
+                                                 _gc[COLORABLE_MARK],
+                                                 priv->buffer,
+                                                 old_x * TILE_SIZE_PIXELS,
+                                                 old_y * TILE_SIZE_PIXELS,
+                                                 new_x * TILE_SIZE_PIXELS,
+                                                 new_y * TILE_SIZE_PIXELS,
+                                                 TILE_SIZE_PIXELS,
+                                                 TILE_SIZE_PIXELS);
+                       } else {
+                               gtk_map_render_tile(map, new_base_tilex + new_x,
+                                               new_base_tiley + new_y,
+                                               new_x * TILE_SIZE_PIXELS,
+                                               new_y * TILE_SIZE_PIXELS,
+                                               map_drag_id!=0 ? TRUE : FALSE);
+                       }
+               }
+       }
+       gtk_map_render_data(map);
+}
+
+MACRO_RECALC_OFFSET();
+MACRO_RECALC_FOCUS_BASE(priv->center_ratio);
+
+gtk_map_set_mark(&_gps->data);
+gtk_map_refresh(map);
+}
+
 void
 gtk_map_refresh(GtkWidget *widget)
 {
@@ -576,7 +725,8 @@ map=GTK_MAP(widget);
 gtk_widget_queue_draw_area(widget, 0, 0, map->width, map->height);
 }
 
-gint gtk_map_get_zoom(GtkWidget *map)
+gint 
+gtk_map_get_zoom(GtkWidget *map)
 {
 GtkMap *map;
 GtkMapPriv *priv;
@@ -589,6 +739,54 @@ priv=GTK_MAP_GET_PRIVATE(map);
 return priv->zoom;
 }
 
+gboolean
+gtk_map_set_zoom(GtkWidget *map, gint new_zoom)
+{
+GtkMap *map;
+GtkMapPriv *priv;
+
+g_return_val_if_fail(GTK_IS_MAP(widget), FALSE);
+
+map=GTK_MAP(widget);
+priv=GTK_MAP_GET_PRIVATE(map);
+
+if (new_zoom > (priv->max_zoom - 1))
+       return FALSE;
+
+if (new_zoom == priv->zoom)
+       return FALSE;
+
+priv->zoom = new_zoom / _curr_repo->view_zoom_steps * _curr_repo->view_zoom_steps;
+priv->world_size_tiles = unit2tile(WORLD_SIZE_UNITS);
+
+/* If we're leading, update the center to reflect new zoom level. */
+MACRO_RECALC_CENTER(_gps->data, priv->center.unitx, priv->center.unity);
+
+/* Update center bounds to reflect new zoom level. */
+priv->min_center.unitx = pixel2unit(grid2pixel(priv->screen_grids_halfwidth));
+priv->min_center.unity = pixel2unit(grid2pixel(priv->screen_grids_halfheight));
+priv->max_center.unitx = WORLD_SIZE_UNITS - grid2unit(priv->screen_grids_halfwidth) - 1;
+priv->max_center.unity = WORLD_SIZE_UNITS - grid2unit(priv->screen_grids_halfheight) - 1;
+
+BOUND(priv->center.unitx, priv->min_center.unitx, priv->max_center.unitx);
+BOUND(priv->center.unity, priv->min_center.unity, priv->max_center.unity);
+
+priv->base_tilex = grid2tile((gint) pixel2grid((gint) unit2pixel((gint) priv->center.unitx)) - (gint) priv->screen_grids_halfwidth);
+priv->base_tiley = grid2tile(pixel2grid(unit2pixel(priv->center.unity)) - priv->screen_grids_halfheight);
+
+/* New zoom level, so we can't reuse the old buffer's pixels. */
+/* Update state variables. */
+MACRO_RECALC_OFFSET();
+MACRO_RECALC_FOCUS_BASE(priv->center_ratio);
+MACRO_RECALC_FOCUS_SIZE(priv->center_ratio);
+
+gtk_map_set_mark(&_gps->data);
+gtk_map_refresh(map);
+
+return TRUE;
+}
+
+
 gint 
 gtk_map_zoom(GtkWidget *widget, gint zdir)
 {