X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.g2d%2Fsrc%2Forg%2Fsimantics%2Fg2d%2Fchassis%2FFullscreenChassis.java;fp=bundles%2Forg.simantics.g2d%2Fsrc%2Forg%2Fsimantics%2Fg2d%2Fchassis%2FFullscreenChassis.java;h=3ab4a77e07c189eb41a8be85e55da83d8c1df904;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/chassis/FullscreenChassis.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/chassis/FullscreenChassis.java new file mode 100644 index 000000000..3ab4a77e0 --- /dev/null +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/chassis/FullscreenChassis.java @@ -0,0 +1,271 @@ +/******************************************************************************* + * 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; + } + + +}