--- /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
+/*\r
+ *\r
+ * @author Toni Kalajainen\r
+ */\r
+package org.simantics.g2d.chassis;\r
+\r
+import java.awt.AWTException;\r
+import java.awt.BufferCapabilities;\r
+import java.awt.Component;\r
+import java.awt.Cursor;\r
+import java.awt.DisplayMode;\r
+import java.awt.Frame;\r
+import java.awt.Graphics;\r
+import java.awt.Graphics2D;\r
+import java.awt.GraphicsConfiguration;\r
+import java.awt.GraphicsDevice;\r
+import java.awt.GraphicsEnvironment;\r
+import java.awt.ImageCapabilities;\r
+import java.awt.event.KeyAdapter;\r
+import java.awt.event.KeyEvent;\r
+import java.awt.event.KeyListener;\r
+import java.awt.event.WindowAdapter;\r
+import java.awt.event.WindowEvent;\r
+import java.awt.geom.Rectangle2D;\r
+import java.awt.image.BufferStrategy;\r
+import java.lang.reflect.Method;\r
+\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.canvas.IContentContext;\r
+import org.simantics.g2d.canvas.IMouseCursorContext;\r
+import org.simantics.g2d.canvas.IMouseCursorListener;\r
+import org.simantics.g2d.canvas.IContentContext.IContentListener;\r
+import org.simantics.g2d.dnd.DragInteractor;\r
+import org.simantics.g2d.dnd.DropInteractor;\r
+import org.simantics.g2d.participant.RenderingQualityInteractor;\r
+import org.simantics.g2d.participant.TransformUtil;\r
+import org.simantics.scenegraph.g2d.G2DRenderingHints;\r
+import org.simantics.scenegraph.g2d.events.adapter.AWTFocusAdapter;\r
+import org.simantics.scenegraph.g2d.events.adapter.AWTKeyEventAdapter;\r
+import org.simantics.scenegraph.g2d.events.adapter.AWTMouseEventAdapter;\r
+import org.simantics.utils.threads.AWTThread;\r
+import org.simantics.utils.threads.Executable;\r
+import org.simantics.utils.threads.SyncListenerList;\r
+import org.simantics.utils.threads.ThreadUtils;\r
+\r
+\r
+/**\r
+ * Full screen AWT Frame chassis for canvas editors.\r
+ */\r
+public class FullscreenChassis extends AbstractChassis implements ICanvasChassis {\r
+\r
+ protected Frame frame;\r
+\r
+ protected java.awt.Canvas canvas;\r
+\r
+ protected BufferStrategy bufferStrategy;\r
+\r
+ protected Graphics2D g2d;\r
+\r
+ protected TransformUtil viewboxInteractor;\r
+\r
+ protected AWTMouseEventAdapter mouseAdapter;\r
+ protected AWTFocusAdapter focusAdapter;\r
+ protected AWTKeyEventAdapter keyAdapter;\r
+\r
+ transient boolean dirty = false;\r
+\r
+ KeyListener escapeListener = new KeyAdapter() {\r
+ @Override\r
+ public void keyPressed(KeyEvent e) {\r
+ if (e.getKeyCode() == KeyEvent.VK_ESCAPE)\r
+ frame.dispose();\r
+ }\r
+ };\r
+\r
+ /**\r
+ * Create full screen chassis in default monitor.\r
+ * <p>\r
+ * This constructor must be ran in AWT Thread.\r
+ * \r
+ * @param canvasContext\r
+ * @param windowTitle\r
+ * @param ruler\r
+ */\r
+ public FullscreenChassis(String windowTitle, boolean ruler) {\r
+ this(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(), windowTitle, ruler);\r
+ }\r
+\r
+ public void redraw() {\r
+ canvas.repaint();\r
+ }\r
+\r
+ /**\r
+ * Create full screen chassis.\r
+ * <p>\r
+ * This constructor must be ran in AWT Thread.\r
+ * \r
+ * @param monitor the monitor device\r
+ * @param canvasContext\r
+ * @param windowTitle\r
+ * @param ruler\r
+ */\r
+ public FullscreenChassis(GraphicsDevice monitor, String windowTitle, boolean ruler) {\r
+ DisplayMode dm = monitor.getDisplayMode();\r
+\r
+ frame = new Frame(windowTitle);\r
+ frame.setSize(dm.getWidth(), dm.getHeight());\r
+ frame.setUndecorated(true);\r
+\r
+ // Close click\r
+ frame.addWindowListener(new WindowAdapter() {\r
+ @Override\r
+ public void windowClosing(WindowEvent e) {\r
+ frame.dispose();\r
+ }\r
+\r
+ @Override\r
+ public void windowClosed(WindowEvent e) {\r
+ if (g2d!=null) {\r
+ g2d.dispose();\r
+ g2d = null;\r
+ }\r
+ fireChassisClosed();\r
+ }\r
+ });\r
+\r
+ canvas = new java.awt.Canvas() {\r
+ private static final long serialVersionUID = -3520733232931837755L;\r
+\r
+ @Override\r
+ public void paint(Graphics g) {\r
+ if (bufferStrategy==null)\r
+ {\r
+ BufferCapabilities caps = new BufferCapabilities(new ImageCapabilities(true),\r
+ new ImageCapabilities(true), BufferCapabilities.FlipContents.COPIED);\r
+ try {\r
+ canvas.createBufferStrategy(2, caps);\r
+ } catch (AWTException e) {\r
+ canvas.createBufferStrategy(2);\r
+ }\r
+ bufferStrategy = canvas.getBufferStrategy();\r
+ }\r
+ if (g2d!=null && bufferStrategy.contentsLost()) {\r
+ g2d.dispose();\r
+ g2d = null;\r
+ }\r
+ if (g2d==null)\r
+ g2d = (Graphics2D) bufferStrategy.getDrawGraphics();\r
+ paintCanvas(g2d);\r
+ bufferStrategy.show();\r
+ }\r
+\r
+ @Override\r
+ public void update(Graphics g) {\r
+ paint(g);\r
+ }\r
+ };\r
+\r
+\r
+ // Esc listener\r
+ canvas.addKeyListener(escapeListener);\r
+ frame.addKeyListener(escapeListener);\r
+\r
+ //monitor.setFullScreenWindow(frame);\r
+\r
+ frame.add(canvas);\r
+\r
+ frame.invalidate();\r
+ java.awt.Rectangle awtBounds = monitor.getDefaultConfiguration().getBounds();\r
+ frame.setBounds(awtBounds);\r
+ frame.setAlwaysOnTop(true);\r
+ frame.setVisible(true);\r
+\r
+\r
+ }\r
+\r
+ @Override\r
+ public void setCanvasContext(ICanvasContext canvasContext) {\r
+ super.setCanvasContext(canvasContext);\r
+\r
+ // quality interactor\r
+ RenderingQualityInteractor rq = new RenderingQualityInteractor();\r
+ canvasContext.add(rq);\r
+\r
+ // Set bridge for mouse cursor changing\r
+ IMouseCursorContext mctx = canvasContext.getMouseCursorContext();\r
+ mctx.addCursorListener(new IMouseCursorListener() {\r
+ @Override\r
+ public void onCursorSet(IMouseCursorContext sender, int mouseId, Cursor cursor) {\r
+ if (mouseId!=0) return;\r
+ canvas.setCursor(cursor);\r
+ }}, AWTThread.getThreadAccess());\r
+\r
+\r
+ // drop interactor\r
+ assert(canvasContext.getAtMostOneItemOfClass(DropInteractor.class)==null);\r
+ canvasContext.add( new DropInteractor(canvas) );\r
+\r
+ // Drag interactor\r
+ assert(canvasContext.getAtMostOneItemOfClass(DragInteractor.class)==null);\r
+ canvasContext.add( new DragInteractor(canvas) );\r
+\r
+ // Delegate events to the canvas context\r
+ mouseAdapter = new AWTMouseEventAdapter(canvasContext, canvasContext.getEventQueue());\r
+ keyAdapter = new AWTKeyEventAdapter(canvasContext, canvasContext.getEventQueue());\r
+ focusAdapter = new AWTFocusAdapter(canvasContext, canvasContext.getEventQueue());\r
+ canvas.addMouseListener(mouseAdapter);\r
+ canvas.addMouseMotionListener(mouseAdapter);\r
+ canvas.addMouseWheelListener(mouseAdapter);\r
+ canvas.addKeyListener(keyAdapter);\r
+ canvas.addFocusListener(focusAdapter);\r
+\r
+ canvasContext.getContentContext().addPaintableContextListener(new IContentListener() {\r
+ @Override\r
+ public void onDirty(IContentContext sender) {\r
+ if (dirty) return;\r
+ dirty = true;\r
+ redraw();\r
+ }}\r
+ );\r
+\r
+ redraw();\r
+ }\r
+\r
+ public void paintCanvas(Graphics2D g) {\r
+ if (canvasContext == null)\r
+ return;\r
+ if (canvasContext.isLocked())\r
+ return;\r
+\r
+ dirty = false;\r
+\r
+ // Paint the canvas\r
+ Rectangle2D bounds = new Rectangle2D.Double(0,0, frame.getSize().width, frame.getSize().height);\r
+ g.setRenderingHint(G2DRenderingHints.KEY_CONTROL_BOUNDS, bounds);\r
+ canvasContext.getSceneGraph().render(g);\r
+ }\r
+\r
+\r
+ private final static Method CLOSED_METHOD = SyncListenerList.getMethod(IChassisListener.class, "chassisClosed");\r
+\r
+ protected void fireChassisClosed() {\r
+ Executable e[] = listeners.getExecutables(CLOSED_METHOD, this);\r
+ ThreadUtils.multiSyncExec(e);\r
+ }\r
+\r
+ public GraphicsConfiguration getGraphicsConfiguration() {\r
+ return frame.getGraphicsConfiguration();\r
+ }\r
+\r
+ public Component getAwtComponent() {\r
+ return canvas;\r
+ }\r
+\r
+ public Frame getFrame() {\r
+ return frame;\r
+ }\r
+\r
+\r
+}\r