diff --git a/src/micropolisj/gui/MainWindow.java b/src/micropolisj/gui/MainWindow.java index 9d687c9..7ad7f42 100644 --- a/src/micropolisj/gui/MainWindow.java +++ b/src/micropolisj/gui/MainWindow.java @@ -223,9 +223,18 @@ public class MainWindow extends JFrame showErrorMessage(e); } } + public void mouseWheelMoved(MouseWheelEvent evt) + { + try { + onMouseWheelMoved(evt); + } catch (Throwable e) { + showErrorMessage(e); + } + } }; drawingArea.addMouseListener(mouse); drawingArea.addMouseMotionListener(mouse); + drawingArea.addMouseWheelListener(mouse); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent ev) @@ -981,6 +990,28 @@ public class MainWindow extends JFrame notificationPane.showZoneStatus(engine, xpos, ypos, z); } + private void onMouseWheelMoved(MouseWheelEvent evt) + { + boolean zoomOut = evt.getWheelRotation() > 0; + + int oldZoom = drawingArea.getTileSize(); + int newZoom = zoomOut ? (oldZoom / 2) : (oldZoom * 2); + if (newZoom < 16) { newZoom = 16; } + if (newZoom > 32) { newZoom = 32; } + + if (oldZoom != newZoom) + { + // preserve effective mouse position in viewport when changing zoom level + double f = (double)newZoom / (double)oldZoom; + Point pos = drawingAreaScroll.getViewport().getViewPosition(); + int newX = (int)Math.round(evt.getX() * f - (evt.getX() - pos.x)); + int newY = (int)Math.round(evt.getY() * f - (evt.getY() - pos.y)); + drawingArea.selectTileSize(newZoom); + drawingAreaScroll.validate(); + drawingAreaScroll.getViewport().setViewPosition(new Point(newX, newY)); + } + } + // used when a tool is being pressed ToolStroke toolStroke; diff --git a/src/micropolisj/gui/MicropolisDrawingArea.java b/src/micropolisj/gui/MicropolisDrawingArea.java index 2b6234e..6659d6a 100644 --- a/src/micropolisj/gui/MicropolisDrawingArea.java +++ b/src/micropolisj/gui/MicropolisDrawingArea.java @@ -58,11 +58,17 @@ public class MicropolisDrawingArea extends JComponent }); } - private void selectTileSize(int newTileSize) + public void selectTileSize(int newTileSize) { tileImages = TileImages.getInstance(newTileSize); TILE_WIDTH = tileImages.TILE_WIDTH; TILE_HEIGHT = tileImages.TILE_HEIGHT; + revalidate(); + } + + public int getTileSize() + { + return TILE_WIDTH; } public CityLocation getCityLocation(int x, int y) diff --git a/src/micropolisj/gui/TileImages.java b/src/micropolisj/gui/TileImages.java index 3d4968f..0fe9707 100644 --- a/src/micropolisj/gui/TileImages.java +++ b/src/micropolisj/gui/TileImages.java @@ -28,7 +28,13 @@ public class TileImages { this.TILE_WIDTH = size; this.TILE_HEIGHT = size; - this.images = loadTileImages("/tiles.png"); + + //if (size != 16) { + // this.images = loadTileImages("/tiles_"+size+"x"+size+".png", size); + //} + //else { + this.images = loadTileImages("/tiles.png", 16); + //} } public static TileImages getInstance(int size) @@ -42,7 +48,7 @@ public class TileImages return images[tile]; } - private Image [] loadTileImages(String resourceName) + private Image [] loadTileImages(String resourceName, int srcSize) { URL iconUrl = TileImages.class.getResource(resourceName); Image refImage = new ImageIcon(iconUrl).getImage(); @@ -51,14 +57,14 @@ public class TileImages GraphicsDevice dev = env.getDefaultScreenDevice(); GraphicsConfiguration conf = dev.getDefaultConfiguration(); - Image [] images = new Image[refImage.getHeight(null) / TILE_HEIGHT]; + Image [] images = new Image[refImage.getHeight(null) / srcSize]; for (int i = 0; i < images.length; i++) { BufferedImage bi = conf.createCompatibleImage(TILE_WIDTH, TILE_HEIGHT, Transparency.OPAQUE); Graphics2D gr = bi.createGraphics(); gr.drawImage(refImage, 0, 0, TILE_WIDTH, TILE_HEIGHT, - 0, i * TILE_HEIGHT, - TILE_WIDTH, (i+1)*TILE_HEIGHT, + 0, i * srcSize, + 0 + srcSize, i * srcSize + srcSize, null); images[i] = bi;