package tk.amberide.ide.gui.editor.map.res; import tk.amberide.ide.data.res.Tileset; import tk.amberide.ide.data.res.Tileset.TileSprite; import javax.swing.*; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; /** * @author Tudor */ public class TileSheetRenderer extends JComponent { private Tileset sheet; private Point clickLocation; private Point mouseLocation; private TileSelector parent; /** * Constructs a new TileSheetRenderer * * @param sheet the TileSheet to render * @param parent the TileSelector to whom to pass selection updates to */ public TileSheetRenderer(final Tileset sheet, final TileSelector parent) { this.sheet = sheet; this.parent = parent; MouseAdapter ma = new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { mouseLocation = clickLocation = relative(e.getPoint()); if (isInBounds(clickLocation)) { parent.setSelection(new TileSprite[][]{{sheet.getTile(clickLocation.x, clickLocation.y)}}); repaint(); } } @Override public void mouseDragged(MouseEvent e) { mouseLocation = relative(e.getPoint()); if (isInBounds(mouseLocation)) { TileSprite[][] selection; if (mouseLocation.equals(clickLocation)) { selection = new TileSprite[][]{{sheet.getTile(clickLocation.x, clickLocation.y)}}; } else { int x1 = Math.min(clickLocation.x, mouseLocation.x); int x2 = Math.max(clickLocation.x, mouseLocation.x) + 1; int y1 = Math.min(clickLocation.y, mouseLocation.y); int y2 = Math.max(clickLocation.y, mouseLocation.y) + 1; selection = new TileSprite[x2 - x1][y2 - y1]; for (int x = 0; x != x2 - x1; x++) { for (int y = 0; y != y2 - y1; y++) { selection[x][y] = sheet.getTile(x + x1, y + y1); } } } parent.setSelection(selection); repaint(); } } }; addMouseListener(ma); addMouseMotionListener(ma); setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); } @Override public Dimension getPreferredSize() { return getMaximumSize(); } @Override public Dimension getMinimumSize() { return getMaximumSize(); } @Override public Dimension getMaximumSize() { return new Dimension(8 * 32, sheet.getHeight() * 32); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Dimension size = sheet.getTile(0, 0).getSize(); BufferedImage image = sheet.getImage(); double rx = 32 / size.width; double ry = 32 / size.height; g.drawImage(image, 0, 0, (int)(image.getWidth() * rx), (int)(image.getHeight() * ry), 0, 0, image.getWidth(), image.getHeight(), null); if (mouseLocation != null && clickLocation != null) { int x1 = Math.min(clickLocation.x, mouseLocation.x); int x2 = Math.max(clickLocation.x, mouseLocation.x); int y1 = Math.min(clickLocation.y, mouseLocation.y); int y2 = Math.max(clickLocation.y, mouseLocation.y); ((Graphics2D) g).setStroke(new BasicStroke(2F)); TileSprite[][] selection = parent.getSelection(); if (selection != null) { g.drawRect(x1 * 32, y1 * 32, selection.length * 32, selection[0].length * 32); g.setColor(new Color(.1f, .2f, 1f, .4f)); g.fillRect(x1 * 32, y1 * 32, selection.length * 32, selection[0].length * 32); } } } private Point relative(Point onScreen) { return new Point(onScreen.x / 32, onScreen.y / 32); } private boolean isInBounds(Point rel) { return rel.x >= 0 && rel.y >= 0 && rel.x <= sheet.getWidth() - 2 && rel.y <= sheet.getHeight() - 2; } }