--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.graphviz.drawable;\r
+\r
+import java.awt.Canvas;\r
+import java.awt.Color;\r
+import java.awt.Graphics;\r
+import java.awt.Graphics2D;\r
+import java.awt.Point;\r
+import java.awt.RenderingHints;\r
+import java.awt.event.ComponentAdapter;\r
+import java.awt.event.ComponentEvent;\r
+import java.awt.event.KeyAdapter;\r
+import java.awt.event.KeyEvent;\r
+import java.awt.event.MouseAdapter;\r
+import java.awt.event.MouseEvent;\r
+import java.awt.event.MouseWheelEvent;\r
+import java.awt.event.MouseWheelListener;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Rectangle2D;\r
+import java.awt.image.VolatileImage;\r
+\r
+/**\r
+ * A canvas showing a given Drawable.\r
+ * \r
+ * @author Hannu Niemist�\r
+ */\r
+public class ViewerCanvas extends Canvas {\r
+\r
+ private static final long serialVersionUID = -1094658958968314511L;\r
+ \r
+ AffineTransform transform;\r
+ Point prev;\r
+ VolatileImage im;\r
+ \r
+ Drawable drawable;\r
+\r
+ public ViewerCanvas(Drawable drawable) {\r
+ this.drawable = drawable;\r
+ setBackground(Color.WHITE); \r
+ addKeyListener(new KeyAdapter() {\r
+\r
+ @Override\r
+ public void keyPressed(KeyEvent e) {\r
+ if(e.getKeyChar()=='1') {\r
+ fit();\r
+ repaint();\r
+ }\r
+ }\r
+\r
+ });\r
+ addMouseListener(new MouseAdapter() {\r
+\r
+ @Override\r
+ public void mousePressed(MouseEvent e) {\r
+ prev = e.getPoint();\r
+ } \r
+ });\r
+ addMouseMotionListener(new MouseAdapter() {\r
+ @Override\r
+ public void mouseDragged(MouseEvent e) {\r
+ Point cur = e.getPoint();\r
+ double deltaX = cur.getX()-prev.getX();\r
+ double deltaY = cur.getY()-prev.getY(); \r
+ transform.preConcatenate(AffineTransform.getTranslateInstance(deltaX, deltaY)); \r
+ repaint();\r
+ prev = cur;\r
+ }\r
+ });\r
+ addMouseWheelListener(new MouseWheelListener() {\r
+\r
+ @Override\r
+ public void mouseWheelMoved(MouseWheelEvent e) {\r
+ if(transform != null) {\r
+ double scale = Math.exp(-0.1*e.getUnitsToScroll());\r
+ Point p = e.getPoint();\r
+ AffineTransform mod = new AffineTransform();\r
+ mod.translate(p.getX(), p.getY());\r
+ mod.scale(scale, scale);\r
+ mod.translate(-p.getX(), -p.getY());\r
+ transform.preConcatenate(mod); \r
+ repaint();\r
+ }\r
+ }\r
+\r
+ });\r
+ addComponentListener(new ComponentAdapter() {\r
+ @Override\r
+ public void componentResized(ComponentEvent e) {\r
+ if(getWidth() > 0 && getHeight() > 0) {\r
+ im = createVolatileImage(getWidth(), getHeight());\r
+ repaint();\r
+ }\r
+ }\r
+ });\r
+ }\r
+\r
+ public void fit() {\r
+ Rectangle2D bounds = drawable.getBounds();\r
+\r
+ Rectangle2D container = getBounds();\r
+ double scale = Math.min(\r
+ container.getWidth() / bounds.getWidth(), \r
+ container.getHeight() / bounds.getHeight());\r
+\r
+ transform = new AffineTransform(\r
+ scale, 0.0,\r
+ 0.0, scale,\r
+ container.getX() + container.getWidth() * 0.5 - bounds.getCenterX() * scale,\r
+ container.getY() + container.getHeight() * 0.5 - bounds.getCenterY() * scale\r
+ );\r
+ }\r
+\r
+ @Override\r
+ public void paint(Graphics _g) {\r
+ do {\r
+ if (im == null || im.validate(getGraphicsConfiguration()) ==\r
+ VolatileImage.IMAGE_INCOMPATIBLE) {\r
+ im = createVolatileImage(getWidth(), getHeight());\r
+ }\r
+ \r
+ Graphics2D g = (Graphics2D)im.getGraphics();\r
+ \r
+ g.clearRect(0, 0, im.getWidth(null), im.getHeight(null));\r
+ \r
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\r
+ g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);\r
+ g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);\r
+ \r
+ if(transform == null)\r
+ fit();\r
+ g.setTransform(transform);\r
+ \r
+ drawable.draw(g, null);\r
+ g.dispose();\r
+ } while(im.contentsLost());\r
+\r
+ _g.drawImage(im, 0, 0, this);\r
+ }\r
+\r
+ @Override\r
+ public void update(Graphics g) {\r
+ paint(g);\r
+ }\r
+ \r
+ public AffineTransform getTransform() {\r
+ return transform;\r
+ }\r
+\r
+}\r
+\r