]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/chassis/FullscreenChassis.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / chassis / FullscreenChassis.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 /*\r
13  *\r
14  * @author Toni Kalajainen\r
15  */\r
16 package org.simantics.g2d.chassis;\r
17 \r
18 import java.awt.AWTException;\r
19 import java.awt.BufferCapabilities;\r
20 import java.awt.Component;\r
21 import java.awt.Cursor;\r
22 import java.awt.DisplayMode;\r
23 import java.awt.Frame;\r
24 import java.awt.Graphics;\r
25 import java.awt.Graphics2D;\r
26 import java.awt.GraphicsConfiguration;\r
27 import java.awt.GraphicsDevice;\r
28 import java.awt.GraphicsEnvironment;\r
29 import java.awt.ImageCapabilities;\r
30 import java.awt.event.KeyAdapter;\r
31 import java.awt.event.KeyEvent;\r
32 import java.awt.event.KeyListener;\r
33 import java.awt.event.WindowAdapter;\r
34 import java.awt.event.WindowEvent;\r
35 import java.awt.geom.Rectangle2D;\r
36 import java.awt.image.BufferStrategy;\r
37 import java.lang.reflect.Method;\r
38 \r
39 import org.simantics.g2d.canvas.ICanvasContext;\r
40 import org.simantics.g2d.canvas.IContentContext;\r
41 import org.simantics.g2d.canvas.IMouseCursorContext;\r
42 import org.simantics.g2d.canvas.IMouseCursorListener;\r
43 import org.simantics.g2d.canvas.IContentContext.IContentListener;\r
44 import org.simantics.g2d.dnd.DragInteractor;\r
45 import org.simantics.g2d.dnd.DropInteractor;\r
46 import org.simantics.g2d.participant.RenderingQualityInteractor;\r
47 import org.simantics.g2d.participant.TransformUtil;\r
48 import org.simantics.scenegraph.g2d.G2DRenderingHints;\r
49 import org.simantics.scenegraph.g2d.events.adapter.AWTFocusAdapter;\r
50 import org.simantics.scenegraph.g2d.events.adapter.AWTKeyEventAdapter;\r
51 import org.simantics.scenegraph.g2d.events.adapter.AWTMouseEventAdapter;\r
52 import org.simantics.utils.threads.AWTThread;\r
53 import org.simantics.utils.threads.Executable;\r
54 import org.simantics.utils.threads.SyncListenerList;\r
55 import org.simantics.utils.threads.ThreadUtils;\r
56 \r
57 \r
58 /**\r
59  * Full screen AWT Frame chassis for canvas editors.\r
60  */\r
61 public class FullscreenChassis extends AbstractChassis implements ICanvasChassis {\r
62 \r
63     protected Frame                               frame;\r
64 \r
65     protected java.awt.Canvas                     canvas;\r
66 \r
67     protected BufferStrategy                      bufferStrategy;\r
68 \r
69     protected Graphics2D                          g2d;\r
70 \r
71     protected TransformUtil                  viewboxInteractor;\r
72 \r
73     protected AWTMouseEventAdapter                mouseAdapter;\r
74     protected AWTFocusAdapter                                           focusAdapter;\r
75     protected AWTKeyEventAdapter                  keyAdapter;\r
76 \r
77     transient boolean dirty = false;\r
78 \r
79     KeyListener                         escapeListener = new KeyAdapter() {\r
80         @Override\r
81         public void keyPressed(KeyEvent e) {\r
82             if (e.getKeyCode() == KeyEvent.VK_ESCAPE)\r
83                 frame.dispose();\r
84         }\r
85     };\r
86 \r
87     /**\r
88      * Create full screen chassis in default monitor.\r
89      * <p>\r
90      * This constructor must be ran in AWT Thread.\r
91      * \r
92      * @param canvasContext\r
93      * @param windowTitle\r
94      * @param ruler\r
95      */\r
96     public FullscreenChassis(String windowTitle, boolean ruler) {\r
97         this(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(), windowTitle, ruler);\r
98     }\r
99 \r
100     public void redraw() {\r
101         canvas.repaint();\r
102     }\r
103 \r
104     /**\r
105      * Create full screen chassis.\r
106      * <p>\r
107      * This constructor must be ran in AWT Thread.\r
108      * \r
109      * @param monitor the monitor device\r
110      * @param canvasContext\r
111      * @param windowTitle\r
112      * @param ruler\r
113      */\r
114     public FullscreenChassis(GraphicsDevice monitor, String windowTitle, boolean ruler) {\r
115         DisplayMode dm = monitor.getDisplayMode();\r
116 \r
117         frame = new Frame(windowTitle);\r
118         frame.setSize(dm.getWidth(), dm.getHeight());\r
119         frame.setUndecorated(true);\r
120 \r
121         // Close click\r
122         frame.addWindowListener(new WindowAdapter() {\r
123             @Override\r
124             public void windowClosing(WindowEvent e) {\r
125                 frame.dispose();\r
126             }\r
127 \r
128             @Override\r
129             public void windowClosed(WindowEvent e) {\r
130                 if (g2d!=null) {\r
131                     g2d.dispose();\r
132                     g2d = null;\r
133                 }\r
134                 fireChassisClosed();\r
135             }\r
136         });\r
137 \r
138         canvas = new java.awt.Canvas() {\r
139             private static final long serialVersionUID = -3520733232931837755L;\r
140 \r
141             @Override\r
142             public void paint(Graphics g) {\r
143                 if (bufferStrategy==null)\r
144                 {\r
145                     BufferCapabilities caps = new BufferCapabilities(new ImageCapabilities(true),\r
146                             new ImageCapabilities(true), BufferCapabilities.FlipContents.COPIED);\r
147                     try {\r
148                         canvas.createBufferStrategy(2, caps);\r
149                     } catch (AWTException e) {\r
150                         canvas.createBufferStrategy(2);\r
151                     }\r
152                     bufferStrategy = canvas.getBufferStrategy();\r
153                 }\r
154                 if (g2d!=null && bufferStrategy.contentsLost()) {\r
155                     g2d.dispose();\r
156                     g2d = null;\r
157                 }\r
158                 if (g2d==null)\r
159                     g2d = (Graphics2D) bufferStrategy.getDrawGraphics();\r
160                 paintCanvas(g2d);\r
161                 bufferStrategy.show();\r
162             }\r
163 \r
164             @Override\r
165             public void update(Graphics g) {\r
166                 paint(g);\r
167             }\r
168         };\r
169 \r
170 \r
171         // Esc listener\r
172         canvas.addKeyListener(escapeListener);\r
173         frame.addKeyListener(escapeListener);\r
174 \r
175         //monitor.setFullScreenWindow(frame);\r
176 \r
177         frame.add(canvas);\r
178 \r
179         frame.invalidate();\r
180         java.awt.Rectangle awtBounds         = monitor.getDefaultConfiguration().getBounds();\r
181         frame.setBounds(awtBounds);\r
182         frame.setAlwaysOnTop(true);\r
183         frame.setVisible(true);\r
184 \r
185 \r
186     }\r
187 \r
188     @Override\r
189     public void setCanvasContext(ICanvasContext canvasContext) {\r
190         super.setCanvasContext(canvasContext);\r
191 \r
192         // quality interactor\r
193         RenderingQualityInteractor rq = new RenderingQualityInteractor();\r
194         canvasContext.add(rq);\r
195 \r
196         // Set bridge for mouse cursor changing\r
197         IMouseCursorContext mctx = canvasContext.getMouseCursorContext();\r
198         mctx.addCursorListener(new IMouseCursorListener() {\r
199             @Override\r
200             public void onCursorSet(IMouseCursorContext sender, int mouseId, Cursor cursor) {\r
201                 if (mouseId!=0) return;\r
202                 canvas.setCursor(cursor);\r
203             }}, AWTThread.getThreadAccess());\r
204 \r
205 \r
206         // drop interactor\r
207         assert(canvasContext.getAtMostOneItemOfClass(DropInteractor.class)==null);\r
208         canvasContext.add( new DropInteractor(canvas) );\r
209 \r
210         // Drag interactor\r
211         assert(canvasContext.getAtMostOneItemOfClass(DragInteractor.class)==null);\r
212         canvasContext.add( new DragInteractor(canvas) );\r
213 \r
214         // Delegate events to the canvas context\r
215         mouseAdapter = new AWTMouseEventAdapter(canvasContext, canvasContext.getEventQueue());\r
216         keyAdapter = new AWTKeyEventAdapter(canvasContext, canvasContext.getEventQueue());\r
217         focusAdapter = new AWTFocusAdapter(canvasContext, canvasContext.getEventQueue());\r
218         canvas.addMouseListener(mouseAdapter);\r
219         canvas.addMouseMotionListener(mouseAdapter);\r
220         canvas.addMouseWheelListener(mouseAdapter);\r
221         canvas.addKeyListener(keyAdapter);\r
222         canvas.addFocusListener(focusAdapter);\r
223 \r
224         canvasContext.getContentContext().addPaintableContextListener(new IContentListener() {\r
225             @Override\r
226             public void onDirty(IContentContext sender) {\r
227                 if (dirty) return;\r
228                 dirty = true;\r
229                 redraw();\r
230             }}\r
231         );\r
232 \r
233         redraw();\r
234     }\r
235 \r
236     public void paintCanvas(Graphics2D g) {\r
237         if (canvasContext == null)\r
238             return;\r
239         if (canvasContext.isLocked())\r
240             return;\r
241 \r
242         dirty = false;\r
243 \r
244         // Paint the canvas\r
245         Rectangle2D bounds = new Rectangle2D.Double(0,0, frame.getSize().width, frame.getSize().height);\r
246         g.setRenderingHint(G2DRenderingHints.KEY_CONTROL_BOUNDS, bounds);\r
247         canvasContext.getSceneGraph().render(g);\r
248     }\r
249 \r
250 \r
251     private final static Method CLOSED_METHOD = SyncListenerList.getMethod(IChassisListener.class, "chassisClosed");\r
252 \r
253     protected void fireChassisClosed() {\r
254         Executable e[] = listeners.getExecutables(CLOSED_METHOD, this);\r
255         ThreadUtils.multiSyncExec(e);\r
256     }\r
257 \r
258     public GraphicsConfiguration getGraphicsConfiguration() {\r
259         return frame.getGraphicsConfiguration();\r
260     }\r
261 \r
262     public Component getAwtComponent() {\r
263         return canvas;\r
264     }\r
265 \r
266     public Frame getFrame() {\r
267         return frame;\r
268     }\r
269 \r
270 \r
271 }\r