diff --git a/README.md b/README.md index 437863c39..dff8a74f2 100644 --- a/README.md +++ b/README.md @@ -15,14 +15,18 @@ We don't have a schedule for a final release. This work is being done by a [tiny As with all releases, we'll do everything possible to avoid breaking API. However, there will still be tweaks that have to be made. We'll try to keep them minor. Our goal is stability, and keeping everyone's code running. +### alpha 4 + +* `EditorState(List editors)` changed to `EditorState.nextEditor(List editors)`, reflecting its nature as closer to a factory method (that makes use of the Editor list) than a constructor that will also be storing information about the list of Editor objects in the created object. + ### alpha 2 * See `changes.md` if you're using `surface.setResizable()` with this release on macOS and with P2D or P3D renderers. * The `static` versions of `selectInput()`, `selectOutput()`, and `selectFolder()` in `PApplet` have been removed. These were not documented, hopefully were not in use anywhere. -* The `frame` object has been removed from `PApplet`. We've been warning folks to use `surface` since 2015, but we still should [warn users](https://github.com/processing/processing4/issues/59) +* The `frame` object has been removed from `PApplet`. We've been warning folks to use `surface` since 2015, but we still should [warn users](https://github.com/processing/processing4/issues/59) or maybe provide an easy way to update code. * `PImage.checkAlpha()` is now `public` instead of `protected` * All AWT calls have been moved out of `PImage`, which may be a problem for anything that was relying on those internals - * For instance, `new PImage(java.awt.Image)` is no longer available. It was an undocumented method that was `public` only because it was required by subclasses. + * ~~For instance, `new PImage(java.awt.Image)` is no longer available. It was an undocumented method that was `public` only because it was required by subclasses.~~ As of alpha 4, this is back, because it wasn't deprecated in 3.x, and is likely to break too many things. * Removed `MouseEvent.getClickCount()` and `MouseEvent.getAmount()`. These had been deprecated, not clear they were used anywhere. ### alpha 1 diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 2a39558ff..909eb6719 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -1296,7 +1296,7 @@ public class Base { * can be set by the caller */ public Editor handleOpen(String path, boolean untitled) { - return handleOpen(path, untitled, new EditorState(editors)); + return handleOpen(path, untitled, EditorState.nextEditor(editors)); } diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index 9e4ce8cb8..7bbf95f09 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -163,7 +163,7 @@ public abstract class Editor extends JFrame implements RunnerListener { protected Editor(final Base base, String path, final EditorState state, final Mode mode) throws EditorException { - super("Processing", state.checkConfig()); + super("Processing", state.getConfig()); this.base = base; this.state = state; this.mode = mode; diff --git a/app/src/processing/app/ui/EditorState.java b/app/src/processing/app/ui/EditorState.java index b560bf8ed..9a8c11059 100644 --- a/app/src/processing/app/ui/EditorState.java +++ b/app/src/processing/app/ui/EditorState.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2012-19 The Processing Foundation + Copyright (c) 2012-21 The Processing Foundation Copyright (c) 2011-12 Ben Fry and Casey Reas This program is free software; you can redistribute it and/or modify @@ -27,61 +27,79 @@ import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; -import java.io.*; import java.util.List; import processing.app.Preferences; -import processing.core.PApplet; - -//import processing.core.PApplet; - - -// scenarios: -// 1) new untitled sketch (needs device, needs bounds) -// 2) restoring sketch from recent menu -// - device cannot be found -// - device is found but it's a different size -// - device is found and size is correct -// 3) re-opening sketch in a new mode +/** + * Stores state information (location, size, display device) for an Editor window. + * Originally was used to restore sketch windows on startup, though that was removed + * at some point (3.0?) because it was unreliable and not always appreciated. + * + * This version is primarily just used to get the location (and display) to open + * a new Editor window, though some of the vestigial bits are still in there in case + * we want to restore the ability to restore windows on startup. + * + * Previous scenarios: + * + */ public class EditorState { - // path to the main .pde file for the sketch -// String path; - // placement of the window -// int windowX, windowY, windowW, windowH; Rectangle editorBounds; int dividerLocation; - // width/height of the screen on which this window was placed -// int displayW, displayH; -// String deviceName; // not really useful b/c it's more about bounds anyway - Rectangle deviceBounds; boolean isMaximized; + GraphicsConfiguration deviceConfig; - // how far to offset a new window from the previous window + /** How far to offset a new window from the previous window */ static final int WINDOW_OFFSET = 28; + /** + * Keep a reference to the last device config so we know which display to + * use when creating a new window after all windows have been closed. + */ + static GraphicsConfiguration lastConfig; + /** * Create a fresh editor state object from the default screen device and * set its placement relative to the last opened window. * @param editors List of active editor objects */ - public EditorState(List editors) { - defaultConfig(); - defaultLocation(editors); + static public EditorState nextEditor(List editors) { + Editor lastEditor = null; + int editorCount = editors.size(); + if (editorCount > 0) { + lastEditor = editors.get(editorCount-1); + } + + // update lastConfig so it can be set for this Editor and + // for the next Editor created if the last window is closed. + if (lastEditor != null) { + lastConfig = lastEditor.getGraphicsConfiguration(); + } + if (lastConfig == null) { + lastConfig = getDefaultConfig(); + } + + EditorState outgoing = new EditorState(); + outgoing.initLocation(lastConfig, lastEditor); + return outgoing; } -// EditorState(BufferedReader reader) throws IOException { -// String line = reader.readLine(); -// EditorState(String[] pieces) throws IOException { + /* EditorState(String info) throws IOException { -// String line = reader.readLine(); -// String[] pieces = PApplet.split(line, '\t'); - String[] pieces = PApplet.split(info, ','); -// path = pieces[0]; - + String[] pieces = PApplet.split(info, ','); editorBounds = new Rectangle(Integer.parseInt(pieces[0]), Integer.parseInt(pieces[1]), Integer.parseInt(pieces[2]), @@ -93,15 +111,8 @@ public class EditorState { Integer.parseInt(pieces[6]), Integer.parseInt(pieces[7]), Integer.parseInt(pieces[8])); - -// windowX = Integer.parseInt(pieces[1]); -// windowY = Integer.parseInt(pieces[2]); -// windowW = Integer.parseInt(pieces[3]); -// windowH = Integer.parseInt(pieces[4]); - -// displayW = Integer.parseInt(pieces[5]); -// displayH = Integer.parseInt(pieces[6]); } + */ public String toString() { @@ -110,19 +121,14 @@ public class EditorState { editorBounds.width + "," + editorBounds.height + "," + dividerLocation + "," + - deviceBounds.x + "," + - deviceBounds.y + "," + - deviceBounds.width + "," + - deviceBounds.height); + deviceConfig); } - - /** - * Returns a GraphicsConfiguration so that a new Editor Frame can be - * constructed. First tries to match the bounds for this state information - * to an existing config (nominally, a display) and if that doesn't work, - * then returns the default configuration/default display. - */ + /* +// * Returns a GraphicsConfiguration so that a new Editor Frame can be +// * constructed. First tries to match the bounds for this state information +// * to an existing config (nominally, a display) and if that doesn't work, +// * then returns the default configuration/default display. GraphicsConfiguration checkConfig() { if (deviceBounds != null) { GraphicsEnvironment graphicsEnvironment = @@ -133,22 +139,31 @@ public class EditorState { for (GraphicsConfiguration config : configurations) { // if (config.getDevice().getIDstring().equals(deviceName)) { if (config.getBounds().equals(deviceBounds)) { + System.out.println("found config " + config + " " + deviceBounds); + System.out.println("device name is " + config.getDevice().getIDstring()); return config; } } } } + System.out.println("using default config"); // otherwise go to the default config return defaultConfig(); } + */ - GraphicsConfiguration defaultConfig() { + public GraphicsConfiguration getConfig() { + return deviceConfig; + } + + + static GraphicsConfiguration getDefaultConfig() { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice device = ge.getDefaultScreenDevice(); GraphicsConfiguration config = device.getDefaultConfiguration(); -// deviceName = device.getIDstring(); - deviceBounds = config.getBounds(); +// deviceName = device.getIDstring(); +// deviceBounds = config.getBounds(); return config; } @@ -156,9 +171,12 @@ public class EditorState { /** * Figure out the next location by sizing up the last editor in the list. * If no editors are opened, it'll just open on the main screen. - * @param editors List of editors currently opened + * @param lastOpened The last Editor opened, used to determine display and location */ - void defaultLocation(List editors) { + void initLocation(GraphicsConfiguration lastConfig, Editor lastOpened) { + deviceConfig = lastConfig; + Rectangle deviceBounds = deviceConfig.getBounds(); + int defaultWidth = Toolkit.zoom(Preferences.getInteger("editor.window.width.default")); int defaultHeight = @@ -166,9 +184,8 @@ public class EditorState { defaultWidth = Math.min(defaultWidth, deviceBounds.width); defaultHeight = Math.min(defaultHeight, deviceBounds.height); - //System.out.println("default w/h = " + defaultWidth + "/" + defaultHeight); - if (editors.size() == 0) { + if (lastOpened == null) { // If no current active editor, use default placement. // Center the window on ths screen, taking into account that the // upper-left corner of the device may have a non (0, 0) origin. @@ -183,39 +200,40 @@ public class EditorState { } else { // With a currently active editor, open the new window using the same // dimensions and divider location, but offset slightly. - synchronized (editors) { - Editor lastOpened = editors.get(editors.size() - 1); - isMaximized = (lastOpened.getExtendedState() == Frame.MAXIMIZED_BOTH); - editorBounds = lastOpened.getBounds(); - editorBounds.x += WINDOW_OFFSET; - editorBounds.y += WINDOW_OFFSET; - dividerLocation = lastOpened.getDividerLocation(); + //GraphicsDevice device = lastOpened.getGraphicsConfiguration().getDevice(); + //System.out.println("last opened device is " + device); - if (!deviceBounds.contains(editorBounds)) { - // Warp the next window to a randomish location on screen. - editorBounds.x = deviceBounds.x + - (int) (Math.random() * (deviceBounds.width - defaultWidth)); - editorBounds.y = deviceBounds.y + - (int) (Math.random() * (deviceBounds.height - defaultHeight)); - } - if (isMaximized) { - editorBounds.width = defaultWidth; - editorBounds.height = defaultHeight; - } + isMaximized = (lastOpened.getExtendedState() == Frame.MAXIMIZED_BOTH); + editorBounds = lastOpened.getBounds(); + editorBounds.x += WINDOW_OFFSET; + editorBounds.y += WINDOW_OFFSET; + dividerLocation = lastOpened.getDividerLocation(); + + if (!deviceBounds.contains(editorBounds)) { + // Warp the next window to a randomish location on screen. + editorBounds.x = deviceBounds.x + + (int) (Math.random() * (deviceBounds.width - defaultWidth)); + editorBounds.y = deviceBounds.y + + (int) (Math.random() * (deviceBounds.height - defaultHeight)); + } + if (isMaximized) { + editorBounds.width = defaultWidth; + editorBounds.height = defaultHeight; } } } + /* void update(Editor editor) { -// path = editor.getSketch().getMainFilePath(); editorBounds = editor.getBounds(); dividerLocation = editor.getDividerLocation(); GraphicsConfiguration config = editor.getGraphicsConfiguration(); -// GraphicsDevice device = config.getDevice(); deviceBounds = config.getBounds(); -// deviceName = device.getIDstring(); +// GraphicsDevice device = config.getDevice(); + deviceName = config.getDevice().getIDstring(); } + */ void apply(Editor editor) { @@ -229,6 +247,10 @@ public class EditorState { if (isMaximized) { editor.setExtendedState(Frame.MAXIMIZED_BOTH); } + + // note: doesn't do anything with the device, though that could be + // added if it's something that would be necessary (i.e. to store windows and + // re-open them on when re-opening Processing) } diff --git a/todo.txt b/todo.txt index 00a5aef4f..c15ca9d4e 100755 --- a/todo.txt +++ b/todo.txt @@ -31,6 +31,10 @@ X https://github.com/processing/processing/issues/5781 X store -1 as display number when using the default X ran into weird situation where '1' was renumbered by adding a screen X so the default was now the external display +X a little modernizing/cleanup in Base, converting things to lambda functions +X editor windows always open on display 1 +X https://github.com/processing/processing/issues/1566 +X rewrote EditorState to better handle devices and clean it up earlier o further streamline the downloader @@ -48,8 +52,6 @@ X https://github.com/processing/processing4/issues/201 X https://github.com/processing/processing/pull/4097 -_ editor windows always open on display 1 -_ https://github.com/processing/processing/issues/1566 may be fixed @@ -112,7 +114,8 @@ _ demo: https://github.com/jcodec/jcodec/blob/master/samples/main/java/org/jco decisions before final 4.0 release _ Add ability to move ~/.processing directory _ use ~/.config as parent, or $XDG_CONFIG_HOME -_ https://github.com/processing/processing/issues/6115 +o https://github.com/processing/processing/issues/6115 (moved) +_ https://github.com/processing/processing4/issues/203 X Shutting off VAqua due to interface ugliness and Contribution Manager freezing _ https://github.com/processing/processing4/issues/129 _ now with a release 9 to cover Big Sur