--- /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
+package org.simantics.g2d.chassis;\r
+\r
+import java.awt.BorderLayout;\r
+import java.awt.DisplayMode;\r
+import java.awt.Frame;\r
+import java.awt.GraphicsDevice;\r
+import java.awt.GraphicsEnvironment;\r
+import java.awt.event.KeyAdapter;\r
+import java.awt.event.KeyEvent;\r
+\r
+import javax.swing.JFrame;\r
+\r
+import org.eclipse.jface.viewers.ArrayContentProvider;\r
+import org.eclipse.jface.viewers.LabelProvider;\r
+import org.eclipse.jface.window.Window;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Monitor;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.dialogs.ListDialog;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;\r
+import org.simantics.g2d.participant.KeyToCommand;\r
+import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;\r
+import org.simantics.scenegraph.g2d.events.command.Command;\r
+import org.simantics.scenegraph.g2d.events.command.CommandEvent;\r
+import org.simantics.scenegraph.g2d.events.command.CommandKeyBinding;\r
+import org.simantics.scenegraph.g2d.events.command.Commands;\r
+import org.simantics.utils.datastructures.cache.IProvider;\r
+\r
+public class FullscreenUtils {\r
+\r
+ \r
+ \r
+ /**\r
+ * Views a canvas in full screen mode\r
+ * @param monitor display device\r
+ * @param ctx canvas context\r
+ * @return\r
+ */\r
+ public static Frame viewFullScreen(GraphicsDevice monitor, ICanvasContext ctx)\r
+ {\r
+ DisplayMode dm = monitor.getDisplayMode();\r
+ final JFrame frame = new JFrame("Fullscreen mode");\r
+ frame.setSize(dm.getWidth(), dm.getHeight());\r
+ frame.setUndecorated(true);\r
+ \r
+ // This is an empty content area in the frame\r
+ AWTChassis chassis = new AWTChassis(); \r
+ // There is a background painter in canvas context (==it is opaque)\r
+ chassis.setOpaque(true);\r
+ // Esc listener\r
+ chassis.addKeyListener(new KeyAdapter() {\r
+ @Override\r
+ public void keyPressed(KeyEvent e) {\r
+ if (e.getKeyCode() == KeyEvent.VK_ESCAPE) \r
+ frame.dispose();\r
+ }});\r
+ \r
+ frame.getContentPane().add(chassis, BorderLayout.CENTER);\r
+ frame.pack(); \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
+ chassis.setCanvasContext(ctx);\r
+ return frame;\r
+ }\r
+ \r
+ /**\r
+ * Adds Alt-Enter full screen handler to a canvas context\r
+ * @param ctx\r
+ */\r
+ public static void addFullScreenHandler(ICanvasContext ctx, final Shell shell, final IProvider<ICanvasContext> fullscreenProvider)\r
+ {\r
+ // Key bindings\r
+ KeyToCommand commands = ctx.getAtMostOneItemOfClass(KeyToCommand.class);\r
+ if (commands==null)\r
+ ctx.add( commands = new KeyToCommand() );\r
+ commands.addBinding( new CommandKeyBinding(Commands.FULL_SCREEN, "View in full screen mode", KeyEvent.VK_ENTER, KeyEvent.VK_CONTROL) );\r
+ ctx.add( new AbstractCanvasParticipant() {\r
+ @SuppressWarnings("unused")\r
+ @EventHandler(priority = 0)\r
+ public boolean handleEvent(CommandEvent e) {\r
+ assertDependencies();\r
+ Command c = e.command;\r
+ // Arrow key panning\r
+ if (c.equals(Commands.FULL_SCREEN))\r
+ {\r
+ shell.getDisplay().asyncExec(new Runnable() {\r
+ @Override\r
+ public void run() {\r
+ GraphicsDevice gd = getOrQueryDisplay(shell);\r
+ if (gd!=null) {\r
+ viewFullScreen(gd, fullscreenProvider.get());\r
+ }}});\r
+ return true;\r
+ }\r
+ return false;\r
+ } \r
+ });\r
+ } \r
+\r
+ /**\r
+ * Gets a single display or dialogs\r
+ * @param shell\r
+ * @return null or a display\r
+ */\r
+ public static GraphicsDevice getOrQueryDisplay(Shell shell)\r
+ {\r
+ GraphicsDevice list[] = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();\r
+ if (list.length==0) return null;\r
+ if (list.length==1) return list[0];\r
+ return doDisplayDialog(shell);\r
+ }\r
+ \r
+ /**\r
+ * Dialog for choosing display device\r
+ * @return\r
+ */\r
+ public static GraphicsDevice doDisplayDialog(Shell shell)\r
+ {\r
+ ListDialog ld = new ListDialog(shell);\r
+ ld.setInput(GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices());\r
+ ld.setTitle("Select display device");\r
+ ld.setInitialSelections(new Object[] {GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice()});\r
+ ld.setMessage("Select display device");\r
+ ld.setContentProvider(new ArrayContentProvider());\r
+ ld.setLabelProvider(new LabelProvider() {\r
+ @Override\r
+ public String getText(Object element) {\r
+ GraphicsDevice gd = (GraphicsDevice) element;\r
+ return gd.getIDstring()+" ("+gd.getDisplayMode().getWidth()+"*"+gd.getDisplayMode().getHeight()+")";\r
+ } \r
+ });\r
+ ld.setBlockOnOpen(true);\r
+ if (ld.open() != Window.OK) return null;\r
+ return (GraphicsDevice)ld.getResult()[0];\r
+ }\r
+ \r
+ /**\r
+ * Adds esc to close full screen view\r
+ * @param ctx\r
+ */\r
+ @SuppressWarnings("unused")\r
+ private static void addCloseHandler(ICanvasContext ctx, final Frame frame)\r
+ {\r
+ // Key bindings\r
+ KeyToCommand commands = ctx.getAtMostOneItemOfClass(KeyToCommand.class);\r
+ if (commands==null)\r
+ ctx.add( commands = new KeyToCommand() );\r
+ commands.addBinding( new CommandKeyBinding(Commands.CLOSE, "Close Canvas", KeyEvent.VK_ESCAPE) );\r
+ ctx.add( new AbstractCanvasParticipant() {\r
+ @EventHandler(priority = 0)\r
+ public boolean handleEvent(CommandEvent e) {\r
+ assertDependencies();\r
+ frame.dispose();\r
+ return true;\r
+ } \r
+ });\r
+ } \r
+ \r
+ /**\r
+ * Get the monitor the shell is mostly in\r
+ * @param shell\r
+ * @return\r
+ */\r
+ public static Monitor getMonitor(Shell shell)\r
+ {\r
+ Monitor result = null;\r
+ long largestArea = 0;\r
+ \r
+ Rectangle shellRectangle = shell.getBounds();\r
+ for (Monitor monitor : Display.getCurrent().getMonitors())\r
+ {\r
+ Rectangle monitorBounds = monitor.getBounds();\r
+ Rectangle intersection = monitorBounds.intersection(shellRectangle);\r
+ long area = intersection.width * intersection.height;\r
+ if (area>largestArea) {\r
+ largestArea = area;\r
+ result = monitor;\r
+ }\r
+ }\r
+ return result; \r
+ } \r
+ \r
+ /**\r
+ * Gets corresponding awt monitor for a swt monitor \r
+ * @param swtMonitor\r
+ * @return\r
+ */\r
+ public static GraphicsDevice getMonitorCorrespondence(Monitor swtMonitor)\r
+ {\r
+ Rectangle swtBounds = swtMonitor.getBounds();\r
+\r
+ for (GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices())\r
+ {\r
+ if (gd.getType() != GraphicsDevice.TYPE_RASTER_SCREEN) continue;\r
+ java.awt.Rectangle awtBounds = gd.getDefaultConfiguration().getBounds();\r
+ if (awtBounds.x == swtBounds.x && awtBounds.y == swtBounds.y && awtBounds.width == swtBounds.width && awtBounds.height == swtBounds.height)\r
+ return gd;\r
+ }\r
+ return null;\r
+ }\r
+ \r
+}\r