1
0
Fork 0
SVEN/StorageSim/src/storagesim/MapPanel.java

207 lines
5.1 KiB
Java

package storagesim;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import javax.swing.JPanel;
/**
* Draws a {@link StorageMap} inside a {@link javax.swing.JPanel}
*
* @author Manuel
*/
public class MapPanel extends JPanel {
private static final long serialVersionUID = 1L;
double scale;
double translateX, translateY;
Point prevMouse;
StorageWindow parent;
StorageMap map;
public MapPanel(StorageWindow parent) {
super();
this.parent = parent;
this.scale = 1.0;
this.translateX = 0.0;
this.translateY = 0.0;
this.setSize(720, 480);
map = new StorageMap(24, 15);
map.updateMap(parent.db);
this.setPreferredSize(this.getSize());
this.setBackground(Color.MAGENTA);
Controls c = new Controls();
this.addMouseListener(c);
this.addMouseMotionListener(c);
this.addMouseWheelListener(c);
this.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
super.componentResized(e);
applyTransform(0, 0, 0, 0, 0);
}
});
}
/**
* Draws the map inside the panel
*/
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
g2.translate(this.translateX, this.translateY);
g2.scale(this.scale, this.scale);
g2.drawImage(this.map.img, 0, 0, null);
if (this.map.selectedTile >= 0) {
int selectedX = (this.map.selectedTile % this.map.tileColumns) * this.map.tileSize;
int selectedY = (this.map.selectedTile / this.map.tileColumns) * this.map.tileSize;
g2.setColor(Color.YELLOW);
g2.drawRect(selectedX, selectedY, this.map.tileSize, this.map.tileSize);
}
// TODO bot entities
}
/**
* Reset the view
*/
public void resetView() {
this.scale = 1.0;
this.translateX = 0.0;
this.translateY = 0.0;
this.applyTransform(0, 0, 0, 0, 0);
}
/**
* PURE FUCKING MAGIC; DON'T TOUCH!
*/
private void applyTransform(double dTranslateX, double dTranslateY, double dScale, int mouseX, int mouseY) {
this.scale += dScale;
double scaleMinX = (double)getWidth() / map.img.getWidth();
double scaleMinY = (double)getHeight() / map.img.getHeight();
double scaleMin = scaleMinX < scaleMinY ? scaleMinY : scaleMinX;
double scaleMax = 24;
// limit scale to image limits
if(this.scale < scaleMin) {
dScale = (this.scale - dScale) % scaleMin;
this.scale = scaleMin;
} else if (this.scale > scaleMax) {
dScale -= (this.scale - scaleMax);
this.scale = scaleMax;
}
// adjust position according to zoom: (new pos - prev pos) * scale
this.translateX += (((mouseX - this.translateX) / this.scale) -
((mouseX - this.translateX) / (this.scale - dScale))) * this.scale;
this.translateY += (((mouseY - this.translateY) / this.scale) -
((mouseY - this.translateY) / (this.scale - dScale))) * this.scale;
this.translateX += dTranslateX;
this.translateY += dTranslateY;
// limit translation to image borders
if (this.translateX > 0) {
this.translateX = 0;
} else if (this.translateX < (getWidth() - (map.img.getWidth() * this.scale))) {
this.translateX = getWidth() - (map.img.getWidth() * this.scale);
}
if (this.translateY > 0) {
this.translateY = 0;
} else if (this.translateY < (getHeight() - (map.img.getHeight() * this.scale))) {
this.translateY = getHeight() - (map.img.getHeight() * this.scale);
}
}
/**
* Holds the interaction controls
*/
private class Controls extends MouseAdapter {
/**
* Updates mouse position on click
*
* @param e mouse event with coordinates
*/
@Override
public void mousePressed(MouseEvent e) {
prevMouse = e.getPoint();
repaint();
}
/**
* Listens to mouse drags to transform the map
*
* @param e mouse event with coordinates
*/
@Override
public void mouseDragged(MouseEvent e) {
if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == MouseEvent.BUTTON1_DOWN_MASK) {
applyTransform(
e.getX() - prevMouse.getX(),
e.getY() - prevMouse.getY(),
0.0, e.getX(), e.getY());
prevMouse = e.getPoint();
repaint();
}
}
/**
* Listens to scroll to scale the map
*
* @param e mouse event with scroll information
*/
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
double scaleChange = e.getPreciseWheelRotation() * (scale / -16.0);
applyTransform(0.0, 0.0, scaleChange, e.getX(), e.getY());
repaint();
}
}
/**
* Listens to mouse clicks to change which tile is in focus
*
* @param e mouse event with position information
*/
public void mouseClicked(MouseEvent e) {
double xOnMap = (e.getX() - translateX) / scale;
double yOnMap = (e.getY() - translateY) / scale;
int xTile = (int) (xOnMap / map.tileSize);
int yTile = (int) (yOnMap / map.tileSize);
map.selectedTile = yTile * map.tileColumns + xTile;
parent.updateSidebar(parent.db);
repaint();
}
}
}