diff --git a/java/org/artisanlogiciel/games/Display.java b/java/org/artisanlogiciel/games/Display.java index ee87d70..effe374 100644 --- a/java/org/artisanlogiciel/games/Display.java +++ b/java/org/artisanlogiciel/games/Display.java @@ -1,6 +1,7 @@ package org.artisanlogiciel.games; import java.awt.BorderLayout; +import java.awt.image.BufferedImage; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; @@ -8,6 +9,8 @@ import java.awt.Graphics; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -15,10 +18,13 @@ import java.io.IOException; import java.util.LinkedList; import java.util.Scanner; +import javax.imageio.ImageIO; + import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JButton; import javax.swing.JComponent; +import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; @@ -41,6 +47,7 @@ public class Display extends JFrame MazeControler controler; LabyModel model; JPanel controlPanel; + boolean autoSize; Display(LabyModel model, MazeComponent comp) { @@ -51,6 +58,16 @@ public class Display extends JFrame con.add(new JScrollPane(comp), BorderLayout.CENTER); controler = new MazeControler(); con.add(controler, BorderLayout.NORTH); + + addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + if ( autoSize ) + { + maze.getAutoSize(); + } + } + }); } void resolve() @@ -83,6 +100,33 @@ public class Display extends JFrame maze.setWallSize(size); } + void setAutoSize(boolean autoSize) + { + this.autoSize = autoSize; + if ( autoSize ) + { + maze.getAutoSize(); + } + } + + void savePng() + { + File file = new File("snapshot.png"); + BufferedImage bi = new BufferedImage(this.getSize().width, this.getSize().height, BufferedImage.TYPE_INT_ARGB); + Graphics g = bi.createGraphics(); + this.paint(g); + g.dispose(); + try{ + ImageIO.write(bi,"png",file); + }catch (Exception e) { + e.printStackTrace(); + } + } + + private class MazeSettings extends JPanel + { + // TODO set width and height and depth of maze with gui + } private class MazeControler extends JPanel { @@ -160,6 +204,10 @@ public class Display extends JFrame controlPanel.add(east, BorderLayout.EAST); controlPanel.add(south, BorderLayout.SOUTH); add(controlPanel, BorderLayout.NORTH); + + // control display panel contains controls for display + // zoom , autozoom. + final JPanel controlDisplayPanel = new JPanel(); final JSlider slider = new JSlider(2, 40); slider.addChangeListener(new ChangeListener() { @@ -168,7 +216,30 @@ public class Display extends JFrame setWallSize(slider.getValue()); } }); - add(slider, BorderLayout.EAST); + final JCheckBox autoSlide = new JCheckBox("autoslide"); + autoSlide.addChangeListener(new ChangeListener() + { + public void stateChanged(ChangeEvent e) + { + setAutoSize( autoSlide.isSelected()); + } + }); + final JButton savePngButton = new JButton("Save png"); + Action savePngAction = new AbstractAction() { + public void actionPerformed(ActionEvent evt) + { + // + System.out.println("save png"); + savePng(); + } + }; + savePngButton.addActionListener(savePngAction); + controlDisplayPanel.add(slider, BorderLayout.WEST); + controlDisplayPanel.add(autoSlide, BorderLayout.EAST); + controlDisplayPanel.add(savePngButton, BorderLayout.SOUTH); + + + add(controlDisplayPanel, BorderLayout.SOUTH); } } @@ -186,19 +257,125 @@ public class Display extends JFrame return button; } + private static class MazeCellParameters + { + double width = 10; // width of one cell + double height = 10; // height of one cell + int offsetX = 5; // x offset of upper corner left + int offsetY = 5; // y offset of upper corner left + + int mapWidth = 0; + int mapHeight = 0; + + public MazeCellParameters(int mapw, int maph, int W, int H, int x, int y) + { + double w = ( W - x )/ mapw; + double h = ( H - y )/ maph; + mapWidth = mapw; + mapHeight = maph; + if (w < 5) + w = 5; + if (h < 5) + h = 5; + setCellSize(w,h); + offsetX = x; + offsetY = y; + } + + public void adaptTo(double W, double H) + { + double w = ( W - offsetX ) / mapWidth; + double h = ( H - offsetY ) / mapHeight; + mapWidth = mapWidth; + mapHeight = mapHeight; + if (w < 5) + w = 5; + if (h < 5) + h = 5; + setCellSize(w,h); + } + + public void setCellSize(double w, double h) + { + width = w; + height = h; + } + + public double getWidth() + { + return width; + } + + public double getHeight() + { + return height; + } + + public int getOffsetX() + { + return offsetX; + } + + public int getOffsetY() + { + return offsetY; + } + + public Dimension getDimension() + { + return new Dimension(offsetX + (int) (mapWidth * width), + offsetY + (int) (mapHeight * height)); + } + + public void drawWalls(Graphics g, int pX, int pY, short walls) + { + int x = offsetX + (int) (pX * width); + int y = offsetY + (int) (pY * height); + if ( (pY == 0) && ((walls & Brick.UP) == Brick.UP)) + g.drawLine(x, y, x + (int) width, y); + if ((walls & Brick.DOWN) == Brick.DOWN) + g.drawLine(x, y + (int) height, x + (int) width, y + (int) height); + if ((walls & Brick.RIGHT) == Brick.RIGHT) + g.drawLine(x + (int) width, y, x + (int) width, y + (int) height); + if ( (pX == 0 ) && ((walls & Brick.LEFT) == Brick.LEFT)) + g.drawLine(x, y, x, y + (int) height); + } + + public void drawDot(Graphics g, Position dot, int pX, int pY, int mX, int mY) + { + double radius = (height > width) ? width : height; + int a = (int) ( radius / 4 ); + if ((dot.getX() >= pX) && (dot.getY() >= pY) && (dot.getX() < mX) && (dot.getY() < mY)) + { + int x = offsetX + (int) (dot.getX() * width); + int y = offsetY + (int) (dot.getY() * height); + int r2 = (int) ( (radius * 3)/4 ); + g.drawOval(x + 1, y + 1, r2, r2); + // g.drawLine(x+a,y+a,x+width-a,y+height-a); + // g.drawLine(x+a,y+height-a,x+width-a,y+a); + + } + else + { + int x = offsetX + (int) (pX * width); + int y = offsetY + (int) (pY * height); + g.drawLine(x + 1, y + 1, x + (int) width - 1, y + (int) height - 1); + } + } + + } + private static class MazeComponent extends JComponent implements MazeCreationListener, MazeResolutionListener { private static final long serialVersionUID = 3163272907991176390L; + WallsProvider map; - int width = 10; - int height = 10; - int offsetX = 5; - int offsetY = 5; + final MazeCellParameters cp; Position current = null; LinkedList solvedPath = null; final Object lockChange = new Object(); - // current postion of human resolution + // current postion of human resolving int sX = 0; int sY = 0; // goal exit @@ -272,30 +449,38 @@ public class Display extends JFrame } - public MazeComponent(WallsProvider map, int width, int height, int offsetX, int offsetY) + /** + width, height of one cell, + offsetX, offsetY of upper left corner + **/ + public MazeComponent(WallsProvider map, MazeCellParameters cp) { super(); + this.cp = cp; this.map = map; - this.width = width; - this.height = height; - this.offsetX = offsetX; - this.offsetY = offsetY; - setPreferredSize(new Dimension(1 + 2 * offsetX + map.getWidth() * width, - 1 + 2 * offsetY + map.getHeight() * height)); + setPreferredSize(cp.getDimension()); gX = map.getWidth() - 1; gY = map.getHeight() - 1; } public void setWallSize(int size) { - - width = size; - height = size; + cp.setCellSize((double) size,(double) size); // should redraw ... invalidate(); repaint(); } + public int getAutoSize() + { + Rectangle r = getBounds(); + cp.adaptTo((int) r.getWidth(),(int) r.getHeight()); + // should redraw ... + invalidate(); + repaint(); + return 50; + } + public void changed(Position cl, Position cr, WallsProvider map) { // should redraw ... @@ -315,18 +500,6 @@ public class Display extends JFrame } } - private void drawWalls(Graphics g, int x, int y, short walls, boolean full) - { - if ((full) && ((walls & Brick.UP) == Brick.UP)) - g.drawLine(x, y, x + width, y); - if ((walls & Brick.DOWN) == Brick.DOWN) - g.drawLine(x, y + height, x + width, y + height); - if ((walls & Brick.RIGHT) == Brick.RIGHT) - g.drawLine(x + width, y, x + width, y + height); - if ((full) && ((walls & Brick.LEFT) == Brick.LEFT)) - g.drawLine(x, y, x, y + height); - } - @Override protected void paintComponent(Graphics g) { @@ -340,10 +513,10 @@ public class Display extends JFrame // Shape s=g.getClip(); Rectangle r = g.getClipBounds(); - int mX = (int) ((double) r.getWidth() / width); - int mY = (int) ((double) r.getHeight() / height); - int pX = (int) ((double) (r.getX() - offsetX) / width); - int pY = (int) ((double) (r.getY() - offsetY) / height); + int mX = (int) ((double) r.getWidth() / cp.getWidth()); + int mY = (int) ((double) r.getHeight() / cp.getHeight()); + int pX = (int) ((double) (r.getX() - cp.getOffsetX()) / cp.getWidth()); + int pY = (int) ((double) (r.getY() - cp.getOffsetY()) / cp.getHeight()); if (pX < 0) pX = 0; @@ -372,22 +545,24 @@ public class Display extends JFrame } else { + g.setColor(Color.green); + cp.drawDot(g, new Position(gX, gY), pX, pY, mX, mY); g.setColor(Color.blue); } - drawDot(g, new Position(sX, sY), pX, pY, mX, mY); + cp.drawDot(g, new Position(sX, sY), pX, pY, mX, mY); synchronized (lockChange) { g.setColor(Color.red); if (current != null) { - drawDot(g, current, pX, pY, mX, mY); + cp.drawDot(g, current, pX, pY, mX, mY); } if (solvedPath != null) { for (Position resolved : solvedPath) { - drawDot(g, resolved, pX, pY, mX, mY); + cp.drawDot(g, resolved, pX, pY, mX, mY); } } } @@ -397,35 +572,12 @@ public class Display extends JFrame { for (pX = 0; pX < mX; pX++) { - x = offsetX + pX * width; - y = offsetY + pY * height; walls = map.getWalls(pX, pY); - drawWalls(g, x, y, walls, (pX == 0) || (pY == 0)); - + cp.drawWalls(g, pX, pY, walls); } } } - private void drawDot(Graphics g, Position dot, int pX, int pY, int mX, int mY) - { - int radius = (height > width) ? width : height; - int a = radius / 4; - if ((dot.getX() >= pX) && (dot.getY() >= pY) && (dot.getX() < mX) && (dot.getY() < mY)) - { - int x = offsetX + dot.getX() * width; - int y = offsetY + dot.getY() * height; - g.drawOval(x + 1, y + 1, radius - a, radius - a); - // g.drawLine(x+a,y+a,x+width-a,y+height-a); - // g.drawLine(x+a,y+height-a,x+width-a,y+a); - - } - else - { - int x = offsetX + pX * width; - int y = offsetY + pY * height; - g.drawLine(x + 1, y + 1, x + width - 1, y + height - 1); - } - } public boolean notifySearch(Position pPosition) { @@ -464,6 +616,18 @@ public class Display extends JFrame } } + private static MazeComponent setupDisplay(LabyModel model, int W, int H) + { + MazeCellParameters cp = new MazeCellParameters(model.getWidth(),model.getHeight(), W, H, 3, 3); + MazeComponent comp = new MazeComponent(model, cp); + Display display = new Display(model, comp); + model.setMazeListener(comp); + display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + display.setBounds(W, H, W, H); + display.setVisible(true); + return comp; + } + public static void main(String pArgs[]) { LabyModel model = null; @@ -482,18 +646,7 @@ public class Display extends JFrame System.exit(1); } - int w = W / model.getWidth(); - int h = H / model.getHeight(); - if (w < 5) - w = 5; - if (h < 5) - h = 5; - MazeComponent comp = new MazeComponent(model, w, h, 3, 3); - Display display = new Display(model, comp); - model.setMazeListener(comp); - display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - display.setBounds(W, H, W, H); - display.setVisible(true); + setupDisplay(model, W,H); } else { @@ -501,18 +654,8 @@ public class Display extends JFrame MazeParamEditor params = new MazeParamEditor(new File("lab")); params.read(new Scanner(System.in)); model = new LabyModel(params, new java.util.Random()); - int w = W / params.getWidth(); - int h = H / params.getHeight(); - if (w < 5) - w = 5; - if (h < 5) - h = 5; - MazeComponent comp = new MazeComponent(model, w, h, 3, 3); - Display display = new Display(model, comp); - model.setMazeListener(comp); - display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - display.setBounds(W, H, W, H); - display.setVisible(true); + + setupDisplay(model,W,H); model.generateWithEntry(0, 0);