Created
May 25, 2014 18:17
-
-
Save Longor1996/6a3f70c0cb125c4c8274 to your computer and use it in GitHub Desktop.
Testomatiko: Testing a special CanvasRenderer for Paint.JAVA.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
WARNING: This code is: | |
- NOT commented. | |
- NOT fully tested. | |
- NOT safe for instant usage. | |
- A bit messy. | |
Also note that there is no exception/error/problem-checking at all. | |
Use at your own caution. | |
*/ | |
import java.awt.Color; | |
import java.awt.Dimension; | |
import java.awt.Graphics; | |
import java.awt.Graphics2D; | |
import java.awt.RenderingHints; | |
import java.awt.TexturePaint; | |
import java.awt.event.KeyEvent; | |
import java.awt.event.KeyListener; | |
import java.awt.event.MouseEvent; | |
import java.awt.event.MouseListener; | |
import java.awt.event.MouseMotionListener; | |
import java.awt.event.MouseWheelEvent; | |
import java.awt.event.MouseWheelListener; | |
import java.awt.geom.AffineTransform; | |
import java.awt.geom.NoninvertibleTransformException; | |
import java.awt.geom.Point2D; | |
import java.awt.geom.Point2D.Float; | |
import java.awt.geom.Rectangle2D; | |
import java.awt.image.BufferedImage; | |
import java.text.NumberFormat; | |
import javax.swing.JComponent; | |
/** | |
* Handles: | |
* - Handling of the Camera | |
* - Drawing of any given Image. | |
**/ | |
@SuppressWarnings("serial") | |
public class PaintCanvas extends JComponent implements MouseListener, MouseMotionListener, MouseWheelListener, KeyListener | |
{ | |
// MISC | |
final Mainframe mainframe; | |
final float maxDegreeOfRotation = 45F / 4F; | |
BufferedImage image; | |
// DEBUG | |
NumberFormat numberFormat; | |
// Camera | |
float cam_zoom; | |
float cam_rotation; | |
float cam_positionX; | |
float cam_positionY; | |
// Controls | |
boolean isSpacebarDown; | |
int mouseLastDragPosX; | |
int mouseLastDragPosY; | |
// Paint | |
BufferedImage backgroundImage; | |
TexturePaint backgroundPaint; | |
Rectangle2D backgroundRectangle; | |
public PaintCanvas(Mainframe mainframe) | |
{ | |
this.mainframe = mainframe; | |
this.setMinimumSize(new Dimension(8,8)); | |
this.setDoubleBuffered(true); | |
this.setFocusable(true); | |
this.addMouseListener(this); | |
this.addMouseMotionListener(this); | |
this.addMouseWheelListener(this); | |
this.addKeyListener(this); | |
this.numberFormat = NumberFormat.getInstance(); | |
{ | |
this.numberFormat.setMaximumFractionDigits(4); | |
this.numberFormat.setMinimumFractionDigits(4); | |
this.numberFormat.setGroupingUsed(true); | |
this.numberFormat.setMinimumIntegerDigits(8); | |
this.numberFormat.setMaximumIntegerDigits(8); | |
} | |
{ | |
this.backgroundImage = new BufferedImage(2,2, BufferedImage.TYPE_BYTE_GRAY); | |
this.backgroundImage.setRGB(0, 0, 0x111111); | |
this.backgroundImage.setRGB(1, 1, 0x111111); | |
this.backgroundImage.setRGB(0, 1, 0x555555); | |
this.backgroundImage.setRGB(1, 0, 0x555555); | |
} | |
this.cam_zoom = 1; | |
this.cam_rotation = 0; | |
this.cam_positionX = 0; | |
this.cam_positionY = 0;; | |
this.updateBackground(); | |
this.isSpacebarDown = false; | |
this.mouseLastDragPosX = 0; | |
this.mouseLastDragPosY = 0; | |
try | |
{ | |
// XXX: Replace the example image file here with any image file to test this JComponent. | |
BufferedImage testimage = javax.imageio.ImageIO.read(new java.io.File("vray-PhyCam-Test.png")); | |
this.setImage(testimage); | |
} | |
catch (java.io.IOException e) | |
{ | |
e.printStackTrace(); | |
} | |
} | |
public void setImage(BufferedImage image) | |
{ | |
this.image = image; | |
this.cam_zoom = 1; | |
this.cam_rotation = 0; | |
this.cam_positionX = image.getWidth() / 2; | |
this.cam_positionY = image.getHeight() / 2; | |
this.updateBackground(); | |
this.repaint(); | |
} | |
public void setImageContent(int[] rawARGB) | |
{ | |
int width = this.image.getWidth(); | |
int height = this.image.getHeight(); | |
int surface = width * height; | |
if(surface != rawARGB.length) | |
{ | |
throw new RuntimeException("Given ARGB-array is not equal in surface area compared to current image. Unable to replace contents!"); | |
} | |
this.image.setRGB(0, 0, width, height, rawARGB, 0, width); | |
// full update | |
this.updateBackground(); | |
this.repaint(); | |
} | |
@Override | |
public void paint(Graphics g) | |
{ | |
Graphics2D g2d = (Graphics2D) g; | |
// clear background | |
g2d.setColor(Color.BLACK); | |
g2d.setPaint(this.backgroundPaint); | |
g2d.fillRect(0, 0, this.getWidth(), this.getHeight()); | |
// rendering hints for image drawing | |
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); | |
AffineTransform Tx = new AffineTransform(); | |
Tx.translate(this.getWidth()/2, this.getHeight()/2); | |
Tx.scale(this.cam_zoom, this.cam_zoom); | |
Tx.rotate(this.cam_rotation); | |
Tx.translate(-this.cam_positionX, -this.cam_positionY); | |
g2d.transform(Tx); | |
g2d.drawImage(this.image, 0, 0, null); | |
// System.out.println("repainted canvas"); | |
} | |
@Override | |
public void mouseClicked(MouseEvent e) | |
{ | |
if((e.getClickCount() == 2) && (e.getButton() == MouseEvent.BUTTON2)) | |
{ | |
this.cam_zoom = 1; | |
this.cam_rotation = 0; | |
this.repaint(); | |
} | |
} | |
@Override | |
public void mousePressed(MouseEvent e) | |
{ | |
this.mouseLastDragPosX = e.getX(); | |
this.mouseLastDragPosY = e.getY(); | |
if(e.getButton() == MouseEvent.BUTTON1) | |
{ | |
Point2D p = this.transformCanvasPointToImagePoint(e.getPoint()); | |
int Cx = (int) p.getX(); | |
int Cy = (int) p.getY(); | |
for(int y = Cy-2; y < (Cy+2); y++) | |
{ | |
for(int x = Cx-2; x < (Cx+2); x++) | |
{ | |
this.image.setRGB(x,y, 0xFFFFFFFF); | |
} | |
} | |
this.repaint(); | |
} | |
} | |
public final Point2D.Float transformCanvasPointToImagePoint(Point2D in) | |
{ | |
AffineTransform Tx = new AffineTransform(); | |
Tx.translate(this.getWidth()/2, this.getHeight()/2); | |
Tx.rotate(this.cam_rotation); | |
Tx.scale(this.cam_zoom, this.cam_zoom); | |
Tx.translate(-this.cam_positionX, -this.cam_positionY); | |
try | |
{ | |
Tx.invert(); | |
} | |
catch (NoninvertibleTransformException e1) | |
{ | |
e1.printStackTrace(); | |
} | |
return (Float) Tx.transform(in, null); | |
} | |
@Override | |
public void mouseReleased(MouseEvent e) | |
{ | |
} | |
@Override | |
public void mouseEntered(MouseEvent e) | |
{ | |
} | |
@Override | |
public void mouseExited(MouseEvent e) | |
{ | |
} | |
@Override | |
public void mouseWheelMoved(MouseWheelEvent e) | |
{ | |
int ctrlMod = MouseWheelEvent.CTRL_MASK | MouseWheelEvent.CTRL_DOWN_MASK; | |
int modifier = e.getModifiers(); | |
boolean ctrlDown = (modifier & ctrlMod) != 0; | |
if(ctrlDown) | |
{ | |
int sign = e.getWheelRotation(); | |
if(sign > 0) | |
{ | |
this.cam_zoom_increase(); | |
return; | |
} | |
if(sign < 0) | |
{ | |
this.cam_zoom_decrease(); | |
return; | |
} | |
} | |
} | |
@Override | |
public void mouseDragged(MouseEvent e) | |
{ | |
int ctrlMod = MouseWheelEvent.CTRL_MASK | MouseWheelEvent.CTRL_DOWN_MASK; | |
int middleMouseMod = MouseEvent.BUTTON2_DOWN_MASK | MouseEvent.BUTTON2_MASK; | |
int modifier = e.getModifiers(); | |
boolean ctrlDown = (modifier & ctrlMod) != 0; | |
boolean middleMouseDown = (modifier & middleMouseMod) != 0; | |
boolean returned = true; | |
if(ctrlDown && returned) | |
{ | |
float mouseX = e.getX(); | |
float mouseY = e.getY(); | |
// screen center | |
mouseX -= this.getWidth()/2; | |
mouseY -= this.getHeight()/2; | |
float mouseLength = (float) Math.sqrt((mouseX*mouseX) + (mouseY*mouseY)); | |
mouseX /= mouseLength; | |
mouseY /= mouseLength; | |
float rotation = (float) Math.atan2(mouseY, mouseX); | |
if(e.isShiftDown()) | |
{ | |
rotation = (float) Math.toDegrees(rotation); | |
rotation /= this.maxDegreeOfRotation; | |
rotation = Math.round(rotation); | |
rotation *= this.maxDegreeOfRotation; | |
rotation = (float) Math.toRadians(rotation); | |
} | |
this.cam_rotation = rotation; | |
this.repaint(); | |
returned = false; | |
} | |
if(middleMouseDown && returned) | |
{ | |
float dragX = e.getX() - this.mouseLastDragPosX; | |
float dragY = e.getY() - this.mouseLastDragPosY; | |
float ROT = -this.cam_rotation; | |
float new_dragX = (float) ((dragX * Math.cos(ROT)) - (dragY * Math.sin(ROT))); | |
float new_dragY = (float) ((dragX * Math.sin(ROT)) + (dragY * Math.cos(ROT))); | |
dragX = new_dragX; | |
dragY = new_dragY; | |
this.cam_positionX -= dragX / this.cam_zoom; | |
this.cam_positionY -= dragY / this.cam_zoom; | |
if(this.cam_positionX < 0) { | |
this.cam_positionX = 0; | |
} | |
if(this.cam_positionY < 0) { | |
this.cam_positionY = 0; | |
} | |
if(this.cam_positionX > this.image.getWidth()) { | |
this.cam_positionX = this.image.getWidth(); | |
} | |
if(this.cam_positionY > this.image.getHeight()) { | |
this.cam_positionY = this.image.getHeight(); | |
} | |
this.updateBackground(); | |
this.repaint(); | |
returned = false; | |
} | |
this.mouseLastDragPosX = e.getX(); | |
this.mouseLastDragPosY = e.getY(); | |
} | |
@Override | |
public void mouseMoved(MouseEvent e) | |
{ | |
} | |
private void cam_zoom_decrease() | |
{ | |
float scale = this.cam_zoom; | |
if(scale > 1) | |
{ | |
scale = (int) scale - 1; | |
} | |
else if(scale > (1 / 10f)) | |
{ | |
scale = scale - (1 / 10f); | |
} | |
this.setScale(scale); | |
} | |
private void cam_zoom_increase() | |
{ | |
float scale = this.cam_zoom; | |
if(scale < 1) | |
{ | |
scale = scale + (1 / 10f); | |
} | |
else if(scale < 64) | |
{ | |
scale = (int) scale + 1; | |
} | |
this.setScale(scale); | |
} | |
private void setScale(float scale) | |
{ | |
this.cam_zoom = scale; | |
this.updateBackground(); | |
this.repaint(); | |
} | |
private void updateBackground() | |
{ | |
this.backgroundRectangle = new Rectangle2D.Float(-this.cam_positionX, -this.cam_positionY, 32f * this.cam_zoom, 32f * this.cam_zoom); | |
this.backgroundPaint = new TexturePaint(this.backgroundImage, this.backgroundRectangle); | |
} | |
@Override | |
public void keyTyped(KeyEvent e) | |
{ | |
} | |
@Override | |
public void keyPressed(KeyEvent e) | |
{ | |
int key = e.getKeyCode(); | |
if(key == KeyEvent.VK_SPACE) | |
{ | |
this.isSpacebarDown = true; | |
} | |
} | |
@Override | |
public void keyReleased(KeyEvent e) | |
{ | |
int key = e.getKeyCode(); | |
if(key == KeyEvent.VK_SPACE) | |
{ | |
this.isSpacebarDown = false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment