/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ /* * * @author Toni Kalajainen */ package org.simantics.g2d.chassis; import java.awt.AWTException; import java.awt.BufferCapabilities; import java.awt.Component; import java.awt.Cursor; import java.awt.DisplayMode; import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.ImageCapabilities; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.geom.Rectangle2D; import java.awt.image.BufferStrategy; import java.lang.reflect.Method; import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.canvas.IContentContext; import org.simantics.g2d.canvas.IMouseCursorContext; import org.simantics.g2d.canvas.IMouseCursorListener; import org.simantics.g2d.canvas.IContentContext.IContentListener; import org.simantics.g2d.dnd.DragInteractor; import org.simantics.g2d.dnd.DropInteractor; import org.simantics.g2d.participant.RenderingQualityInteractor; import org.simantics.g2d.participant.TransformUtil; import org.simantics.scenegraph.g2d.G2DRenderingHints; import org.simantics.scenegraph.g2d.events.adapter.AWTFocusAdapter; import org.simantics.scenegraph.g2d.events.adapter.AWTKeyEventAdapter; import org.simantics.scenegraph.g2d.events.adapter.AWTMouseEventAdapter; import org.simantics.utils.threads.AWTThread; import org.simantics.utils.threads.Executable; import org.simantics.utils.threads.SyncListenerList; import org.simantics.utils.threads.ThreadUtils; /** * Full screen AWT Frame chassis for canvas editors. */ public class FullscreenChassis extends AbstractChassis implements ICanvasChassis { protected Frame frame; protected java.awt.Canvas canvas; protected BufferStrategy bufferStrategy; protected Graphics2D g2d; protected TransformUtil viewboxInteractor; protected AWTMouseEventAdapter mouseAdapter; protected AWTFocusAdapter focusAdapter; protected AWTKeyEventAdapter keyAdapter; transient boolean dirty = false; KeyListener escapeListener = new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) frame.dispose(); } }; /** * Create full screen chassis in default monitor. *

* This constructor must be ran in AWT Thread. * * @param canvasContext * @param windowTitle * @param ruler */ public FullscreenChassis(String windowTitle, boolean ruler) { this(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(), windowTitle, ruler); } public void redraw() { canvas.repaint(); } /** * Create full screen chassis. *

* This constructor must be ran in AWT Thread. * * @param monitor the monitor device * @param canvasContext * @param windowTitle * @param ruler */ public FullscreenChassis(GraphicsDevice monitor, String windowTitle, boolean ruler) { DisplayMode dm = monitor.getDisplayMode(); frame = new Frame(windowTitle); frame.setSize(dm.getWidth(), dm.getHeight()); frame.setUndecorated(true); // Close click frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { frame.dispose(); } @Override public void windowClosed(WindowEvent e) { if (g2d!=null) { g2d.dispose(); g2d = null; } fireChassisClosed(); } }); canvas = new java.awt.Canvas() { private static final long serialVersionUID = -3520733232931837755L; @Override public void paint(Graphics g) { if (bufferStrategy==null) { BufferCapabilities caps = new BufferCapabilities(new ImageCapabilities(true), new ImageCapabilities(true), BufferCapabilities.FlipContents.COPIED); try { canvas.createBufferStrategy(2, caps); } catch (AWTException e) { canvas.createBufferStrategy(2); } bufferStrategy = canvas.getBufferStrategy(); } if (g2d!=null && bufferStrategy.contentsLost()) { g2d.dispose(); g2d = null; } if (g2d==null) g2d = (Graphics2D) bufferStrategy.getDrawGraphics(); paintCanvas(g2d); bufferStrategy.show(); } @Override public void update(Graphics g) { paint(g); } }; // Esc listener canvas.addKeyListener(escapeListener); frame.addKeyListener(escapeListener); //monitor.setFullScreenWindow(frame); frame.add(canvas); frame.invalidate(); java.awt.Rectangle awtBounds = monitor.getDefaultConfiguration().getBounds(); frame.setBounds(awtBounds); frame.setAlwaysOnTop(true); frame.setVisible(true); } @Override public void setCanvasContext(ICanvasContext canvasContext) { super.setCanvasContext(canvasContext); // quality interactor RenderingQualityInteractor rq = new RenderingQualityInteractor(); canvasContext.add(rq); // Set bridge for mouse cursor changing IMouseCursorContext mctx = canvasContext.getMouseCursorContext(); mctx.addCursorListener(new IMouseCursorListener() { @Override public void onCursorSet(IMouseCursorContext sender, int mouseId, Cursor cursor) { if (mouseId!=0) return; canvas.setCursor(cursor); }}, AWTThread.getThreadAccess()); // drop interactor assert(canvasContext.getAtMostOneItemOfClass(DropInteractor.class)==null); canvasContext.add( new DropInteractor(canvas) ); // Drag interactor assert(canvasContext.getAtMostOneItemOfClass(DragInteractor.class)==null); canvasContext.add( new DragInteractor(canvas) ); // Delegate events to the canvas context mouseAdapter = new AWTMouseEventAdapter(canvasContext, canvasContext.getEventQueue()); keyAdapter = new AWTKeyEventAdapter(canvasContext, canvasContext.getEventQueue()); focusAdapter = new AWTFocusAdapter(canvasContext, canvasContext.getEventQueue()); canvas.addMouseListener(mouseAdapter); canvas.addMouseMotionListener(mouseAdapter); canvas.addMouseWheelListener(mouseAdapter); canvas.addKeyListener(keyAdapter); canvas.addFocusListener(focusAdapter); canvasContext.getContentContext().addPaintableContextListener(new IContentListener() { @Override public void onDirty(IContentContext sender) { if (dirty) return; dirty = true; redraw(); }} ); redraw(); } public void paintCanvas(Graphics2D g) { if (canvasContext == null) return; if (canvasContext.isLocked()) return; dirty = false; // Paint the canvas Rectangle2D bounds = new Rectangle2D.Double(0,0, frame.getSize().width, frame.getSize().height); g.setRenderingHint(G2DRenderingHints.KEY_CONTROL_BOUNDS, bounds); canvasContext.getSceneGraph().render(g); } private final static Method CLOSED_METHOD = SyncListenerList.getMethod(IChassisListener.class, "chassisClosed"); protected void fireChassisClosed() { Executable e[] = listeners.getExecutables(CLOSED_METHOD, this); ThreadUtils.multiSyncExec(e); } public GraphicsConfiguration getGraphicsConfiguration() { return frame.getGraphicsConfiguration(); } public Component getAwtComponent() { return canvas; } public Frame getFrame() { return frame; } }