|
|
|
@@ -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:
|
|
|
|
|
* <ul>
|
|
|
|
|
* <li>new untitled sketch (needs device, needs bounds)</li>
|
|
|
|
|
* <li>restoring sketch from recent menu
|
|
|
|
|
* <ul>
|
|
|
|
|
* <li>device is found and size matches</li>
|
|
|
|
|
* <li>device cannot be found</li>
|
|
|
|
|
* <li>device is found but its size has changed</li>
|
|
|
|
|
* </ul>
|
|
|
|
|
* </li>
|
|
|
|
|
* <li>re-opening sketch in a new mode</li>
|
|
|
|
|
* </ul>
|
|
|
|
|
*/
|
|
|
|
|
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<Editor> editors) {
|
|
|
|
|
defaultConfig();
|
|
|
|
|
defaultLocation(editors);
|
|
|
|
|
static public EditorState nextEditor(List<Editor> 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<Editor> 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)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|