]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graphviz/src/org/simantics/graphviz/drawable/ViewerCanvas.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.graphviz / src / org / simantics / graphviz / drawable / ViewerCanvas.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.graphviz.drawable;\r
13 \r
14 import java.awt.Canvas;\r
15 import java.awt.Color;\r
16 import java.awt.Graphics;\r
17 import java.awt.Graphics2D;\r
18 import java.awt.Point;\r
19 import java.awt.RenderingHints;\r
20 import java.awt.event.ComponentAdapter;\r
21 import java.awt.event.ComponentEvent;\r
22 import java.awt.event.KeyAdapter;\r
23 import java.awt.event.KeyEvent;\r
24 import java.awt.event.MouseAdapter;\r
25 import java.awt.event.MouseEvent;\r
26 import java.awt.event.MouseWheelEvent;\r
27 import java.awt.event.MouseWheelListener;\r
28 import java.awt.geom.AffineTransform;\r
29 import java.awt.geom.Rectangle2D;\r
30 import java.awt.image.VolatileImage;\r
31 \r
32 /**\r
33  * A canvas showing a given Drawable.\r
34  * \r
35  * @author Hannu Niemist�\r
36  */\r
37 public class ViewerCanvas extends Canvas {\r
38 \r
39     private static final long serialVersionUID = -1094658958968314511L;\r
40     \r
41     AffineTransform transform;\r
42     Point prev;\r
43     VolatileImage im;\r
44     \r
45     Drawable drawable;\r
46 \r
47     public ViewerCanvas(Drawable drawable) {\r
48         this.drawable = drawable;\r
49         setBackground(Color.WHITE);    \r
50         addKeyListener(new KeyAdapter() {\r
51 \r
52             @Override\r
53             public void keyPressed(KeyEvent e) {\r
54                 if(e.getKeyChar()=='1') {\r
55                     fit();\r
56                     repaint();\r
57                 }\r
58             }\r
59 \r
60         });\r
61         addMouseListener(new MouseAdapter() {\r
62 \r
63             @Override\r
64             public void mousePressed(MouseEvent e) {\r
65                 prev = e.getPoint();\r
66             }                           \r
67         });\r
68         addMouseMotionListener(new MouseAdapter() {\r
69             @Override\r
70             public void mouseDragged(MouseEvent e) {\r
71                 Point cur = e.getPoint();\r
72                 double deltaX = cur.getX()-prev.getX();\r
73                 double deltaY = cur.getY()-prev.getY();                                 \r
74                 transform.preConcatenate(AffineTransform.getTranslateInstance(deltaX, deltaY));                                         \r
75                 repaint();\r
76                 prev = cur;\r
77             }\r
78         });\r
79         addMouseWheelListener(new MouseWheelListener() {\r
80 \r
81             @Override\r
82             public void mouseWheelMoved(MouseWheelEvent e) {\r
83                 if(transform != null) {\r
84                     double scale = Math.exp(-0.1*e.getUnitsToScroll());\r
85                     Point p = e.getPoint();\r
86                     AffineTransform mod = new AffineTransform();\r
87                     mod.translate(p.getX(), p.getY());\r
88                     mod.scale(scale, scale);\r
89                     mod.translate(-p.getX(), -p.getY());\r
90                     transform.preConcatenate(mod);                                              \r
91                     repaint();\r
92                 }\r
93             }\r
94 \r
95         });\r
96         addComponentListener(new ComponentAdapter() {\r
97             @Override\r
98             public void componentResized(ComponentEvent e) {\r
99                 if(getWidth() > 0 && getHeight() > 0) {\r
100                         im = createVolatileImage(getWidth(), getHeight());\r
101                         repaint();\r
102                 }\r
103             }\r
104         });\r
105     }\r
106 \r
107     public void fit() {\r
108         Rectangle2D bounds = drawable.getBounds();\r
109 \r
110         Rectangle2D container = getBounds();\r
111         double scale = Math.min(\r
112             container.getWidth() / bounds.getWidth(), \r
113             container.getHeight() / bounds.getHeight());\r
114 \r
115         transform = new AffineTransform(\r
116             scale, 0.0,\r
117             0.0, scale,\r
118             container.getX() + container.getWidth() * 0.5 - bounds.getCenterX() * scale,\r
119             container.getY() + container.getHeight() * 0.5 - bounds.getCenterY() * scale\r
120         );\r
121     }\r
122 \r
123     @Override\r
124     public void paint(Graphics _g) {\r
125         do {\r
126                 if (im == null || im.validate(getGraphicsConfiguration()) ==\r
127                         VolatileImage.IMAGE_INCOMPATIBLE) {\r
128                     im = createVolatileImage(getWidth(), getHeight());\r
129                 }\r
130                 \r
131                 Graphics2D g = (Graphics2D)im.getGraphics();\r
132                 \r
133                 g.clearRect(0, 0, im.getWidth(null), im.getHeight(null));\r
134         \r
135                 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\r
136                 g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);\r
137                 g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);\r
138         \r
139                 if(transform == null)\r
140                     fit();\r
141                 g.setTransform(transform);\r
142         \r
143                 drawable.draw(g, null);\r
144             g.dispose();\r
145         } while(im.contentsLost());\r
146 \r
147         _g.drawImage(im, 0, 0, this);\r
148     }\r
149 \r
150     @Override\r
151     public void update(Graphics g) {\r
152         paint(g);\r
153     }\r
154     \r
155     public AffineTransform getTransform() {\r
156         return transform;\r
157     }\r
158 \r
159 }\r
160 \r