diff --git a/app/src/processing/app/Preferences.java b/app/src/processing/app/Preferences.java index 51cdfc4c4..02c0493b9 100644 --- a/app/src/processing/app/Preferences.java +++ b/app/src/processing/app/Preferences.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2004-09 Ben Fry and Casey Reas + Copyright (c) 2004-12 Ben Fry and Casey Reas Copyright (c) 2001-04 Massachusetts Institute of Technology This program is free software; you can redistribute it and/or modify @@ -120,7 +120,9 @@ public class Preferences { JCheckBox autoAssociateBox; JRadioButton bitsThirtyTwoButton; JRadioButton bitsSixtyFourButton; + JComboBox displaySelectionBox; + int displayCount; // the calling editor, so updates can be applied @@ -201,10 +203,8 @@ public class Preferences { } + // setup dialog for the prefs public Preferences() { - - // setup dialog for the prefs - //dialog = new JDialog(editor, "Preferences", true); dialog = new JFrame("Preferences"); dialog.setResizable(false); @@ -348,6 +348,25 @@ public class Preferences { checkUpdatesBox.setBounds(left, top, d.width + 10, d.height); right = Math.max(right, left + d.width); top += d.height + GUI_BETWEEN; + + + // Run sketches on display [ 1 ] + + Container displayBox = Box.createHorizontalBox(); + JLabel displayLabel = new JLabel("Run sketches on display "); + final String tip = "" + + "Sets the display where sketches are initially placed.
" + + "As usual, if the sketch window is moved, it will re-open
" + + "at the same location, however when running in present
" + + "(full screen) mode, this display will always be used."; + displayLabel.setToolTipText(tip); + displayBox.add(displayLabel); + displaySelectionBox = new JComboBox(); + displayBox.add(displaySelectionBox); + pain.add(displayBox); + d = displayBox.getPreferredSize(); + displayBox.setBounds(left, top, d.width, d.height); + top += d.height + GUI_BETWEEN; // [ ] Automatically associate .pde files with Processing @@ -545,6 +564,14 @@ public class Preferences { setBoolean("editor.external", externalEditorBox.isSelected()); setBoolean("update.check", checkUpdatesBox.isSelected()); + int displayIndex = 0; + for (int d = 0; d < displaySelectionBox.getItemCount(); d++) { + if (displaySelectionBox.getSelectedIndex() == d) { + displayIndex = d; + } + } + setInteger("run.display", displayIndex + 1); + setBoolean("run.options.memory", memoryOverrideBox.isSelected()); int memoryMin = Preferences.getInteger("run.options.memory.initial"); int memoryMax = Preferences.getInteger("run.options.memory.maximum"); @@ -626,6 +653,15 @@ public class Preferences { setSelected(getBoolean("editor.external")); checkUpdatesBox. setSelected(getBoolean("update.check")); + + updateDisplayList(); + int displayNum = getInteger("run.display") - 1; +// System.out.println("display is " + displayNum + ", d count is " + displayCount); + if (displayNum >= 0 && displayNum < displayCount) { +// System.out.println("setting num to " + displayNum); + displaySelectionBox.setSelectedIndex(displayNum); + } + memoryOverrideBox. setSelected(getBoolean("run.options.memory")); memoryField. @@ -654,6 +690,21 @@ public class Preferences { } + void updateDisplayList() { + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + displayCount = ge.getScreenDevices().length; +// displaySelectionBox.removeAll(); + String[] items = new String[displayCount]; + for (int i = 0; i < displayCount; i++) { + items[i] = String.valueOf(i + 1); +// displaySelectionBox.add(String.valueOf(i + 1)); + } +// PApplet.println(items); + displaySelectionBox.setModel(new DefaultComboBoxModel(items)); +// displaySelectionBox = new JComboBox(items); + } + + // Workaround for Apple bullsh*t caused by their not releasing a 32-bit // version of Java for Mac OS X 10.5. // static public String checkBits() { diff --git a/app/src/processing/mode/java/runner/Runner.java b/app/src/processing/mode/java/runner/Runner.java index e8068edc6..bc0e9abcd 100644 --- a/app/src/processing/mode/java/runner/Runner.java +++ b/app/src/processing/mode/java/runner/Runner.java @@ -28,7 +28,10 @@ import processing.app.exec.StreamRedirectThread; import processing.core.*; import processing.mode.java.JavaBuild; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; import java.awt.Point; +import java.awt.Rectangle; import java.io.*; import java.util.*; @@ -214,9 +217,13 @@ public class Runner implements MessageConsumer { // http://dev.processing.org/bugs/show_bug.cgi?id=1446 if (build.getFoundMain()) { params.add(build.getSketchClassName()); + } else { params.add("processing.core.PApplet"); + // get the stored device index (starts at 1) + int runDisplay = Preferences.getInteger("run.display") - 1; + // If there was a saved location (this guy has been run more than once) // then the location will be set to the last position of the sketch window. // This will be passed to the PApplet runner using something like @@ -225,20 +232,48 @@ public class Runner implements MessageConsumer { // figure out where to place itself based on the editor location. // --editor-location=150,20 if (editor != null) { // if running processing-cmd, don't do placement + GraphicsDevice editorDevice = + editor.getGraphicsConfiguration().getDevice(); + GraphicsEnvironment ge = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] devices = ge.getScreenDevices(); + GraphicsDevice runDevice = + (runDisplay >= 0 && runDisplay < devices.length) ? devices[runDisplay] : editorDevice; + Point windowLocation = editor.getSketchLocation(); - if (windowLocation != null) { +// if (windowLocation != null) { +// // could check to make sure the sketch location is on the device +// // that's specified in Preferences, but that's going to be annoying +// // if you move a sketch to another window, then it keeps jumping +// // back to the specified window. +//// Rectangle screenRect = +//// runDevice.getDefaultConfiguration().getBounds(); +// } + if (windowLocation == null) { + if (editorDevice == runDevice) { + // If sketches are to be shown on the same display as the editor, + // provide the editor location so the sketch's main() can place it. + Point editorLocation = editor.getLocation(); + params.add(PApplet.ARGS_EDITOR_LOCATION + "=" + + editorLocation.x + "," + editorLocation.y); + } else { + // The sketch's main() will set a location centered on the new + // display. It has to happen in main() because the width/height + // of the sketch are not known here. +// Set a location centered on the other display +// Rectangle screenRect = +// runDevice.getDefaultConfiguration().getBounds(); +// int runX = +// params.add(PApplet.ARGS_LOCATION + "=" + runX + "," + runY); + } + } else { params.add(PApplet.ARGS_LOCATION + "=" + windowLocation.x + "," + windowLocation.y); - } else { - Point editorLocation = editor.getLocation(); - params.add(PApplet.ARGS_EDITOR_LOCATION + "=" + - editorLocation.x + "," + editorLocation.y); } params.add(PApplet.ARGS_EXTERNAL); } - params.add(PApplet.ARGS_DISPLAY + "=" + - Preferences.get("run.display")); + params.add(PApplet.ARGS_DISPLAY + "=" + runDisplay); params.add(PApplet.ARGS_SKETCH_FOLDER + "=" + build.getSketchPath()); diff --git a/build/shared/lib/preferences.txt b/build/shared/lib/preferences.txt index 1b40dc184..c902fd17c 100755 --- a/build/shared/lib/preferences.txt +++ b/build/shared/lib/preferences.txt @@ -172,8 +172,9 @@ run.options.bits.macosx = 32 # example of increasing the memory size for applets run externally #run.options = -Xms128m -Xmx1024m -# index of the default display to use for present mode -# (this setting not yet completely implemented) +# Index of the display to use for running sketches (starts at 1). +# Kept this 1-indexed because older vesions of Processing were setting +# the preference even before it was being used. run.display = 1 # set internally diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index bc3957d19..769cc5eb5 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -233,13 +233,13 @@ public class PApplet extends Applet public Frame frame; // public JFrame frame; - /** - * Usually just 0, but with multiple displays, the X and Y coordinates of - * the screen will depend on the current screen's position relative to - * the other displays. - */ - public int screenX; - public int screenY; +// /** +// * Usually just 0, but with multiple displays, the X and Y coordinates of +// * the screen will depend on the current screen's position relative to +// * the other displays. +// */ +// public int screenX; +// public int screenY; /** * ( begin auto-generated from screenWidth.xml ) @@ -1894,6 +1894,8 @@ public class PApplet extends Applet getGraphicsConfiguration().getDevice(); Rectangle screenRect = displayDevice.getDefaultConfiguration().getBounds(); +// screenX = screenRect.x; +// screenY = screenRect.y; screenWidth = screenRect.width; screenHeight = screenRect.height; @@ -9113,8 +9115,8 @@ public class PApplet extends Applet * the pde, everything goes into the same folder * as processing.exe. * - * --display=n set what display should be used by this applet. - * displays are numbered starting from 1. + * --display=n set what display should be used by this sketch. + * displays are numbered starting from 0. * * Parameters used by Processing when running via the PDE * @@ -9182,7 +9184,7 @@ public class PApplet extends Applet editorLocation = parseInt(split(value, ',')); } else if (param.equals(ARGS_DISPLAY)) { - int deviceIndex = Integer.parseInt(value) - 1; + int deviceIndex = Integer.parseInt(value); GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment(); @@ -9412,7 +9414,7 @@ public class PApplet extends Applet // (applet has been run more than once, user placed window) frame.setLocation(location[0], location[1]); - } else if (external) { + } else if (external && editorLocation != null) { int locationX = editorLocation[0] - 20; int locationY = editorLocation[1]; diff --git a/core/todo.txt b/core/todo.txt index 2480b8585..90684c549 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -3,13 +3,15 @@ X add support for println(long) because it was converting the type to float X http://code.google.com/p/processing/issues/detail?id=969 X also add support for printing arrays of longs (doubles were already there) +_ look into using BufferStrategy again to improve performance +_ there are more improvements to be made ala issue #729 sort out full screen issues X make screenWidth and screenHeight work properly with multiple screens X also set screenX and screenY X boolean sketchFullscreen() ? X for more options, just integrate the fs library? -_ let hansi know when it's integrated so he can update his library +X let hansi know when it's integrated so he can update his library X casey: I think we only want to most basic functionality, X to go full screen across monitors. X http://www.superduper.org/processing/fullscreen_api/ @@ -30,54 +32,21 @@ X size(screen.width, screen.height, OPENGL); X if size is screen.width and screen.height, does its best X needs to get the size of the main screen o this probably works but just needs to be tested -_ ability to select monitor via preferences panel -_ this applies to any applet that's run externally currently (verify) -_ make it also work with anything that's run inside of p5 itself -_ this means changing the frame creation code inside Runner -_ check current present code with multiple monitors o exceptions in full screen mode will quit the app completely o can't keep window open because things are hosed X nah, this is fine--not ideal but fine -_ doc: if you want to use multiple monitors -_ set full screen to true (for one screen) -_ have sketchWidth() and sketchHeight() return the size of both monitors -_ provide example for doing this with multiple displays? -_ there are just too many possibilities for monitor arrangement -_ and display depth changes that there's no way for us to do it correctly -_ frame.setSize() works, but we aren't going to add the title bar back -_ just too problematic and buggy to get this to work perfectly -_ default is that full screen app doesn't cover multiple displays -_ this is fine since opengl can't usually go across both -_ but include an example for how to use full in gl -http://wiki.processing.org/index.php?title=Window_Size_and_Full_Screen&action=edit&redlink=1 - -_ look into using BufferStrategy again to improve performance -_ there are more improvements to be made ala issue #729 - - * It is also possible to resize the Processing window by including - * frame.setResizable(true) inside your setup() method. - * Note that the Java method frame.setSize() will not work unless - * you first set the frame to be resizable. - *

- - *

Processing on multiple displays

- *

I was asked about Processing with multiple displays, and for lack of a - * better place to document it, things will go here.

- *

You can address both screens by making a window the width of both, - * and the height of the maximum of both screens. In this case, do not use - * present mode, because that's exclusive to one screen. Basically it'll - * give you a PApplet that spans both screens. If using one half to control - * and the other half for graphics, you'd just have to put the 'live' stuff - * on one half of the canvas, the control stuff on the other. This works - * better in windows because on the mac we can't get rid of the menu bar - * unless it's running in present mode.

- *

For more control, you need to write straight java code that uses p5. - * You can create two windows, that are shown on two separate screens, - * that have their own PApplet. this is just one of the tradeoffs of one of - * the things that we don't support in p5 from within the environment - * itself (we must draw the line somewhere), because of how messy it would - * get to start talking about multiple screens. It's also not that tough to - * do by hand w/ some Java code.

+X doc: if you want to use multiple monitors +X set full screen to true (for one screen) +X have sketchWidth() and sketchHeight() return the size of both monitors +X provide example for doing this with multiple displays? +X there are just too many possibilities for monitor arrangement +X and display depth changes that there's no way for us to do it correctly +X frame.setSize() works, but we aren't going to add the title bar back +X just too problematic and buggy to get this to work perfectly +X default is that full screen app doesn't cover multiple displays +X this is fine since opengl can't usually go across both +o but include an example for how to use full in gl +X screenX and screenY are both already taken, so not including vars for them _ static mode sketches seem to break ESC... noLoop() problem? diff --git a/todo.txt b/todo.txt index b055e411a..01c3b893b 100644 --- a/todo.txt +++ b/todo.txt @@ -3,6 +3,15 @@ X fix up some of the error messages inside Compiler X when internal tools crash, don't add them to the menu X (prevents the PDE from locking up on startup) +displays +X ability to select monitor via preferences panel +X this applies to any applet that's run externally currently (verify) +X make it also work with anything that's run inside of p5 itself +X this means changing the frame creation code inside Runner +X check current present code with multiple monitors +_ --bgcolor shouldn't be in main() unless 'present' is turned on +o also add option for FSEM or not +X nope, FSEM too buggy and error-prone X add EditorState class, device-aware placement X get rid of restore sketch feature @@ -18,6 +27,17 @@ _ examples button on toolbar? open / recent / sketchbook? _ add "recent files" list to open menu? o http://dev.processing.org/bugs/show_bug.cgi?id=1335 +_ changing number of screens between run causes things to show up off-screen +_ so when running, check to make sure that things are out of the area +_ saved window positions.. if displays has changed, becomes a problem +_ record the display that it was on? +_ GraphicsDevice gd = frame.getGraphicsConfiguration().getDevice(); +_ make sure that the application is within the bounds of the current display? +_ (from 0, 0 to width, height) +_ messy since some displays have negative coords +_ http://dev.processing.org/bugs/show_bug.cgi?id=72 +_ http://code.google.com/p/processing/issues/detail?id=27 +Base.restoreSketches() has commented out code that checked for out of bounds windows with the preferences last.window.x and last.window.y. These prefs don't exist anymore, but it would be quick to implement it again using last.sketch.location instead. It would probably result in less code, because it would mean we could get rid of the windowPositionValid stuff. _ find in reference for copy() (on image) tries to open PVector.copy() _ might need disambiguation pages? @@ -39,9 +59,6 @@ _ http://code.google.com/p/processing/issues/detail?id=837 _ bad tool brings down the environment _ http://code.google.com/p/processing/issues/detail?id=798 -_ --bgcolor shouldn't be in main() unless 'present' is turned on -_ also add option for FSEM or not - _ update the build instructions page _ http://code.google.com/p/processing/wiki/BuildInstructions _ sketch.isReadOnly returns false for examples coming from multiple modes @@ -289,20 +306,6 @@ _ Added some basic Emacs cursor navigator keybindings _ just implement these as a preference _ http://code.google.com/p/processing/issues/detail?id=555 -. . . . - - -_ changing number of screens between run causes things to show up off-screen -_ so when running, check to make sure that things are out of the area -_ saved window positions.. if displays has changed, becomes a problem -_ record the display that it was on? -_ GraphicsDevice gd = frame.getGraphicsConfiguration().getDevice(); -_ make sure that the application is within the bounds of the current display? -_ (from 0, 0 to width, height) -_ messy since some displays have negative coords -_ http://dev.processing.org/bugs/show_bug.cgi?id=72 -_ http://code.google.com/p/processing/issues/detail?id=27 -Base.restoreSketches() has commented out code that checked for out of bounds windows with the preferences last.window.x and last.window.y. These prefs don't exist anymore, but it would be quick to implement it again using last.sketch.location instead. It would probably result in less code, because it would mean we could get rid of the windowPositionValid stuff. . . . .