diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 4ba4fc132..9063ae086 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2012-14 The Processing Foundation + Copyright (c) 2012-15 The Processing Foundation Copyright (c) 2004-12 Ben Fry and Casey Reas Copyright (c) 2001-04 Massachusetts Institute of Technology @@ -24,15 +24,14 @@ package processing.core; -// used for setting bg colors and whatnot import java.awt.Canvas; +// used for setting bg colors and whatnot import java.awt.Color; // use for the link() command (and maybe open()?) import java.awt.Desktop; import java.awt.EventQueue; import java.awt.FileDialog; import java.awt.Font; -// for the Frame object (deprecate?) import java.awt.Frame; import java.awt.Image; import java.awt.Toolkit; @@ -66,26 +65,33 @@ import processing.opengl.*; * Window Size and Full Screen page on the Wiki has useful information * about sizing, multiple displays, full screen, etc. *

- * Processing uses active mode rendering in all cases. All animation tasks - * happen on the "Processing Animation Thread". The setup() and draw() methods - * are handled by that thread, and events (like mouse movement and key presses, - * which are fired by the event dispatch thread or EDT) are queued to be safely - * handled at the end of draw(). For code that needs to run on the EDT, - * use EventQueue.invokeLater(). When doing so, be careful to synchronize - * between that code (since invokeLater() will make your code run from the EDT) - * and the Processing animation thread. Use of a callback function or the - * registerXxx() methods in PApplet can help ensure that your code doesn't do - * something naughty. + * Processing uses active mode rendering. All animation tasks happen on the + * "Processing Animation Thread". The setup() and draw() methods are handled + * by that thread, and events (like mouse movement and key presses, which are + * fired by the event dispatch thread or EDT) are queued to be safely handled + * at the end of draw(). *

- * As of Processing 2.0, we have discontinued support for versions of Java - * prior to 1.6. We don't have enough people to support it, and for a - * project of our (tiny) size, we should be focusing on the future, rather - * than working around legacy Java code. + * Starting with 3.0a6, blit operations are on the EDT, so as not to cause + * GUI problems with Swing and AWT. In the case of the default renderer, the + * sketch renders to an offscreen image, then the EDT is asked to bring that + * image to the screen. + *

+ * For code that needs to run on the EDT, use EventQueue.invokeLater(). When + * doing so, be careful to synchronize between that code and the Processing + * animation thread. That is, you can't call Processing methods from the EDT + * or at any random time from another thread. Use of a callback function or + * the registerXxx() methods in PApplet can help ensure that your code doesn't + * do something naughty. *

* As of Processing 3.0, we have removed Applet as the base class for PApplet. * This means that we can remove lots of legacy code, however one downside is * that it's no longer possible (without extra code) to embed a PApplet into * another Java application. + *

+ * As of Processing 3.0, we have discontinued support for versions of Java + * prior to 1.8. We don't have enough people to support it, and for a + * project of our (tiny) size, we should be focusing on the future, rather + * than working around legacy Java code. */ public class PApplet implements PConstants { //public class PApplet extends Applet @@ -1614,9 +1620,7 @@ public class PApplet implements PConstants { * */ public PGraphics createGraphics(int w, int h, String renderer) { - PGraphics pg = makeGraphics(w, h, renderer, null, false); - //pg.parent = this; // make save() work - return pg; + return createGraphics(w, h, renderer, null); } @@ -1627,12 +1631,17 @@ public class PApplet implements PConstants { */ public PGraphics createGraphics(int w, int h, String renderer, String path) { + return makeGraphics(w, h, renderer, savePath(path), false); + /* if (path != null) { path = savePath(path); } PGraphics pg = makeGraphics(w, h, renderer, path, false); - pg.parent = this; // make save() work + //pg.parent = this; // why wasn't setParent() used before 3.0a6? + //pg.setParent(this); // make save() work + // Nevermind, parent is set in makeGraphics() return pg; + */ } @@ -1641,13 +1650,12 @@ public class PApplet implements PConstants { // } - /** Create default renderer, likely to be resized, but needed for surface init. */ - protected PGraphics makePrimaryGraphics() { - return makeGraphics(sketchWidth(), sketchHeight(), sketchRenderer(), null, true); - } - - - /** Version of createGraphics() used internally. */ + /** + * Version of createGraphics() used internally. + * @param path A full (not relative) path. + * {@link PApplet#createGraphics} will call + * {@link PApplet#savePath} first. + */ protected PGraphics makeGraphics(int w, int h, String renderer, String path, boolean primary) { @@ -1677,13 +1685,12 @@ public class PApplet implements PConstants { pg.setParent(this); pg.setPrimary(primary); if (path != null) { - // Wrap in sketchPath() because it has to be absolute - pg.setPath(sketchPath(path)); + pg.setPath(path); } // pg.setQuality(sketchQuality()); - if (!primary) { - surface.initImage(pg, w, h); - } +// if (!primary) { +// surface.initImage(pg, w, h); +// } pg.setSize(w, h); // everything worked, return it @@ -1738,12 +1745,19 @@ public class PApplet implements PConstants { if (platform == MACOSX) { e.printStackTrace(System.out); // OS X bug (still true?) } + e.printStackTrace(); throw new RuntimeException(e.getMessage()); } } } + /** Create default renderer, likely to be resized, but needed for surface init. */ + protected PGraphics createPrimaryGraphics() { + return makeGraphics(sketchWidth(), sketchHeight(), sketchRenderer(), null, true); + } + + /** * ( begin auto-generated from createImage.xml ) * @@ -9370,9 +9384,8 @@ public class PApplet implements PConstants { /** - * Moving this to the EDT for 3.0a6 because the main() messes with AWT - * components (or even Swing components, presumably). Hoping to get more - * consistent behavior across platforms and implementations. + * Moving this to the EDT for 3.0a6 because that's the proper thing to do + * when messing with AWT/Swing components. And boy, do we mess with 'em. */ static protected void runSketchEDT(final String[] args, final PApplet constructedApplet) { @@ -9512,6 +9525,7 @@ public class PApplet implements PConstants { // Frame frame = // surface.initFrame(applet, backgroundColor, // displayIndex, present, spanDisplays); + PSurface surface = applet.initSurface(backgroundColor, displayIndex, fullScreen, spanDisplays); @@ -9528,15 +9542,15 @@ public class PApplet implements PConstants { // // In a static mode app, this will be after setup() has completed, // // and the empty draw() has set "finished" to true. // // TODO make sure this won't hang if the applet has an exception. -// while (applet.defaultSize && !applet.finished) { -// //System.out.println("default size"); -// try { -// Thread.sleep(5); -// -// } catch (InterruptedException e) { -// //System.out.println("interrupt"); -// } -// } + while (applet.defaultSize && !applet.finished) { + //System.out.println("default size"); + try { + Thread.sleep(5); + + } catch (InterruptedException e) { + //System.out.println("interrupt"); + } + } if (fullScreen) { //surface.placeFullScreen(hideStop); @@ -9565,10 +9579,16 @@ public class PApplet implements PConstants { // } catch (Exception e) { // throw new RuntimeException(e); // } - g = makePrimaryGraphics(); + g = createPrimaryGraphics(); surface = g.createSurface(); - frame = surface.initFrame(this, backgroundColor, displayIndex, present, spanDisplays); - surface.setTitle(getClass().getName()); + if (g.displayable()) { + frame = surface.initFrame(this, backgroundColor, displayIndex, present, spanDisplays); + //surface.setTitle(getClass().getName()); + frame.setTitle(getClass().getName()); +// } else { +// // TODO necessary? +// surface.initOffscreen(this); + } init(); @@ -9578,6 +9598,11 @@ public class PApplet implements PConstants { // moving it to init() 141114 //applet.start(); + // Removing this for 3.0a6. sketchWidth/Height() methods should give us + // good values for most cases, and removes the hackery seen here. + // TODO May need to keep since setup() may take a while, so why not have + // it first render offscreen before showing. + /* // Wait until the applet has figured out its width. // In a static mode app, this will be after setup() has completed, // and the empty draw() has set "finished" to true. @@ -9591,6 +9616,8 @@ public class PApplet implements PConstants { //System.out.println("interrupt"); } } + */ + // System.out.println("out of default size loop, " + width + " " + height); // convenience to avoid another 'get' from the static main() method return surface; @@ -9618,7 +9645,7 @@ public class PApplet implements PConstants { * sketch.init() // start the animation thread */ public Canvas getCanvas() { - g = makePrimaryGraphics(); + g = createPrimaryGraphics(); surface = g.createSurface(); return surface.initCanvas(this); } diff --git a/core/src/processing/core/PGraphics.java b/core/src/processing/core/PGraphics.java index 9e4f4da77..4ba0b99a6 100644 --- a/core/src/processing/core/PGraphics.java +++ b/core/src/processing/core/PGraphics.java @@ -168,7 +168,7 @@ public class PGraphics extends PImage implements PConstants { /// true if defaults() has been called a first time protected boolean settingsInited; - /// true if defaults() has been called a first time + /// true if settings should be re-applied on next beginDraw() protected boolean reapplySettings; /// set to a PGraphics object being used inside a beginRaw/endRaw() block @@ -516,6 +516,9 @@ public class PGraphics extends PImage implements PConstants { */ public Image image; + /** Surface object that we're talking to */ + protected PSurface surface; + // ........................................................ // internal color for setting/calculating @@ -653,7 +656,7 @@ public class PGraphics extends PImage implements PConstants { * vertex() calls will be based on coordinates that are * based on the IMAGE or NORMALIZED. */ - public int textureMode = IMAGE; + public int textureMode = IMAGE; /** * Current horizontal coordinate for texture, will always @@ -683,6 +686,11 @@ public class PGraphics extends PImage implements PConstants { // INTERNAL + // Most renderers will only override the default implementation of one or + // two of the setXxxx() methods, so they're broken out here since the + // default implementations for each are simple, obvious, and common. + // They're also separate to avoid a monolithic and fragile constructor. + public PGraphics() { // Allows subclasses to override @@ -691,6 +699,8 @@ public class PGraphics extends PImage implements PConstants { public void setParent(PApplet parent) { // ignore this.parent = parent; + // Some renderers (OpenGL) need to know what smoothing level will be used + // before the rendering surface is even created. quality = parent.sketchQuality(); } @@ -737,17 +747,20 @@ public class PGraphics extends PImage implements PConstants { width = w; height = h; + /** {@link PImage.pixelFactor} set in {@link PImage#PImage()} */ pixelWidth = width * pixelFactor; pixelHeight = height * pixelFactor; -// allocate(); - reapplySettings(); +// if (surface != null) { +// allocate(); +// } +// reapplySettings(); + reapplySettings = true; } // /** -// * Allocate memory for this renderer. Generally will need to be implemented -// * for all renderers. +// * Allocate memory or an image buffer for this renderer. // */ // protected void allocate() { } @@ -764,7 +777,7 @@ public class PGraphics extends PImage implements PConstants { public PSurface createSurface() { // ignore - return new PSurfaceAWT(this); + return surface = new PSurfaceAWT(this); } @@ -950,7 +963,7 @@ public class PGraphics extends PImage implements PConstants { settingsInited = true; // defaultSettings() overlaps reapplySettings(), don't do both - //reapplySettings = false; + reapplySettings = false; } diff --git a/core/src/processing/core/PGraphicsJava2D.java b/core/src/processing/core/PGraphicsJava2D.java index a5aa79448..13bd8bc7b 100644 --- a/core/src/processing/core/PGraphicsJava2D.java +++ b/core/src/processing/core/PGraphicsJava2D.java @@ -137,6 +137,13 @@ public class PGraphicsJava2D extends PGraphics { // } +// @Override +// protected void allocate() { +// //surface.initImage(this, width, height); +// surface.initImage(this); +// } + + /* @Override protected void allocate() { @@ -239,8 +246,8 @@ public class PGraphicsJava2D extends PGraphics { @Override public PSurface createSurface() { - //return (surface = new PSurfaceAWT()); - return new PSurfaceAWT(this); + return surface = new PSurfaceAWT(this); +// return new PSurfaceAWT(this); } @@ -267,15 +274,43 @@ public class PGraphicsJava2D extends PGraphics { // Graphics2D g2old; + public Graphics2D checkImage() { + if (image == null || + ((BufferedImage) image).getWidth() != width || + ((BufferedImage) image).getHeight() != height) { +// image = new BufferedImage(width * pixelFactor, height * pixelFactor +// format == RGB ? BufferedImage.TYPE_INT_ARGB); + GraphicsConfiguration gc = null; + if (surface != null) { + Component comp = surface.getComponent(); + if (comp == null) { + comp = parent.frame; + } + if (comp != null) { + gc = comp.getGraphicsConfiguration(); + } + } + // If not realized (off-screen, i.e the Color Selector Tool), gc will be null. + if (gc == null) { + //System.err.println("GraphicsConfiguration null in initImage()"); + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + gc = ge.getDefaultScreenDevice().getDefaultConfiguration(); + } + + // Formerly this was broken into separate versions based on offscreen or + // not, but we may as well create a compatible image; it won't hurt, right? + int wide = width * pixelFactor; + int high = height * pixelFactor; + image = gc.createCompatibleImage(wide, high); + } + return (Graphics2D) image.getGraphics(); + } + + @Override public void beginDraw() { - // TODO this will happen when it's offscreen.. need a better option here - if (image == null || - ((BufferedImage) image).getWidth() != width || - ((BufferedImage) image).getHeight() != height) { - image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - } - g2 = (Graphics2D) image.getGraphics(); + g2 = checkImage(); + //g2 = (Graphics2D) image.getGraphics(); // Calling getGraphics() seems to nuke the smoothing settings smooth(quality); diff --git a/core/src/processing/core/PGraphicsJava2D2X.java b/core/src/processing/core/PGraphicsJava2D2X.java index e4d1ffcfd..f17620211 100644 --- a/core/src/processing/core/PGraphicsJava2D2X.java +++ b/core/src/processing/core/PGraphicsJava2D2X.java @@ -1,7 +1,5 @@ package processing.core; -import java.awt.*; - public class PGraphicsJava2D2X extends PGraphicsJava2D { // PImage retina; @@ -97,22 +95,22 @@ public class PGraphicsJava2D2X extends PGraphicsJava2D { @Override public void beginDraw() { -// GraphicsConfiguration gc = parent.getGraphicsConfiguration(); + super.beginDraw(); +//// GraphicsConfiguration gc = parent.getGraphicsConfiguration(); +//// +//// if (image == null) { +//// retina.width = width * 2; +//// retina.height = height * 2; +//// image = gc.createCompatibleImage(retina.width, retina.height); +//// } +// g2 = (Graphics2D) image.getGraphics(); // -// if (image == null) { -// retina.width = width * 2; -// retina.height = height * 2; -// image = gc.createCompatibleImage(retina.width, retina.height); -// } - g2 = (Graphics2D) image.getGraphics(); - - checkSettings(); - resetMatrix(); // reset model matrix +// vertexCount = 0; +// checkSettings(); +// resetMatrix(); // reset model matrix // inserted here for retina g2.scale(2, 2); - - vertexCount = 0; } diff --git a/core/src/processing/core/PSurface.java b/core/src/processing/core/PSurface.java index e52e0b085..d6575016d 100644 --- a/core/src/processing/core/PSurface.java +++ b/core/src/processing/core/PSurface.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2014 The Processing Foundation + Copyright (c) 2014-15 The Processing Foundation This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -24,6 +24,7 @@ package processing.core; import java.awt.Canvas; import java.awt.Color; +import java.awt.Component; import java.awt.Frame; @@ -44,7 +45,7 @@ public interface PSurface { static final Color WINDOW_BGCOLOR = new Color(0xDD, 0xDD, 0xDD); // renderer that doesn't draw to the screen - public void initOffscreen(); + public void initOffscreen(PApplet sketch); public Canvas initCanvas(PApplet sketch); @@ -53,14 +54,18 @@ public interface PSurface { // - /** Set the window (and dock, or whatever necessary) title. */ - public void setTitle(String title); + // Just call these on an AWT Frame object stored in PApplet. + // Silly, but prevents a lot of rewrite and extra methods for little benefit. + // However, maybe prevents us from having to document the 'frame' variable? - /** Show or hide the window. */ - public void setVisible(boolean visible); - - /** Set true if we want to resize things (default is not resizable) */ - public void setResizable(boolean resizable); +// /** Set the window (and dock, or whatever necessary) title. */ +// public void setTitle(String title); +// +// /** Show or hide the window. */ +// public void setVisible(boolean visible); +// +// /** Set true if we want to resize things (default is not resizable) */ +// public void setResizable(boolean resizable); // @@ -76,35 +81,13 @@ public interface PSurface { // - /** Start the animation thread */ - public void startThread(); - - /** - * On the next trip through the animation thread, things should go sleepy-bye. - * Does not pause the thread immediately because that needs to happen on the - * animation thread itself, so fires on the next trip through draw(). - */ - public void pauseThread(); - - public void resumeThread(); - - /** - * Stop the animation thread (set it null) - * @return false if already stopped - */ - public boolean stopThread(); - - public boolean isStopped(); - - // - // sets displayWidth/Height inside PApplet //public void checkDisplaySize(); public void setSize(int width, int height); /** - * Called by {@link PApplet#createGraphics(int, int)} to nitialize the + * Called by {@link PApplet#createGraphics} to initialize the * {@link PGraphics#image} object with an image that's compatible with this * drawing surface/display/hardware. * @param gr PGraphics object whose image will be set @@ -112,7 +95,10 @@ public interface PSurface { * @param high */ // create pixel buffer (pulled out for offscreen graphics) - public void initImage(PGraphics gr, int wide, int high); + //public void initImage(PGraphics gr, int wide, int high); + // create pixel buffer, called from allocate() to produce a compatible image for rendering efficiently +// public void initImage(PGraphics gr); + public Component getComponent(); /** * Sometimes smoothing must be set at the drawing surface level @@ -141,4 +127,23 @@ public interface PSurface { // + /** Start the animation thread */ + public void startThread(); + + /** + * On the next trip through the animation thread, things should go sleepy-bye. + * Does not pause the thread immediately because that needs to happen on the + * animation thread itself, so fires on the next trip through draw(). + */ + public void pauseThread(); + + public void resumeThread(); + + /** + * Stop the animation thread (set it null) + * @return false if already stopped + */ + public boolean stopThread(); + + public boolean isStopped(); } \ No newline at end of file diff --git a/core/src/processing/core/PSurfaceAWT.java b/core/src/processing/core/PSurfaceAWT.java index 2bc893e64..0c76c3545 100644 --- a/core/src/processing/core/PSurfaceAWT.java +++ b/core/src/processing/core/PSurfaceAWT.java @@ -36,11 +36,11 @@ import processing.event.KeyEvent; import processing.event.MouseEvent; -public class PSurfaceAWT implements PSurface { +public class PSurfaceAWT extends PSurfaceBasic { GraphicsDevice displayDevice; // used for canvas to determine whether resizable or not - boolean resizable; // default is false +// boolean resizable; // default is false // Internally, we know it's always a JFrame (not just a Frame) JFrame frame; @@ -55,20 +55,11 @@ public class PSurfaceAWT implements PSurface { boolean useStrategy = false; Canvas canvas; - PApplet sketch; PGraphics graphics; int sketchWidth; int sketchHeight; - Thread thread; - boolean paused; - Object pauseObject = new Object(); - - /** As of release 0116, frameRate(60) is called as a default */ - protected float frameRateTarget = 60; - protected long frameRatePeriod = 1000000000L / 60L; - public PSurfaceAWT(PGraphics graphics) { this.graphics = graphics; @@ -109,6 +100,7 @@ public class PSurfaceAWT implements PSurface { * later on the EDT. Other implementations may not require that, so the * invokeLater() happens in here rather than requiring the caller to wrap it. */ + @Override public void requestFocus() { // for 2.0a6, moving this request to the EDT EventQueue.invokeLater(new Runnable() { @@ -156,7 +148,8 @@ public class PSurfaceAWT implements PSurface { @Override public Dimension getMaximumSize() { - return resizable ? super.getMaximumSize() : getPreferredSize(); + //return resizable ? super.getMaximumSize() : getPreferredSize(); + return frame.isResizable() ? super.getMaximumSize() : getPreferredSize(); } @@ -270,6 +263,7 @@ public class PSurfaceAWT implements PSurface { } + @Override public void blit() { // Other folks taht call render() (i.e. paint()) are already on the EDT. // We need to be using the EDT since we're messing with the Canvas @@ -283,8 +277,9 @@ public class PSurfaceAWT implements PSurface { // what needs to happen here? - public void initOffscreen() { - + @Override + public void initOffscreen(PApplet sketch) { + this.sketch = sketch; } /* @@ -296,6 +291,7 @@ public class PSurfaceAWT implements PSurface { } */ + @Override public Canvas initCanvas(PApplet sketch) { this.sketch = sketch; @@ -307,6 +303,7 @@ public class PSurfaceAWT implements PSurface { } + @Override public Frame initFrame(PApplet sketch, Color backgroundColor, int deviceIndex, boolean fullScreen, boolean spanDisplays) { this.sketch = sketch; @@ -438,45 +435,46 @@ public class PSurfaceAWT implements PSurface { } - /** Set the window (and dock, or whatever necessary) title. */ - public void setTitle(String title) { - frame.setTitle(title); - } - - - /** Set true if we want to resize things (default is not resizable) */ - public void setResizable(boolean resizable) { - this.resizable = resizable; // really only used for canvas - - if (frame != null) { - frame.setResizable(resizable); - } - } - - - public void setVisible(boolean visible) { - frame.setVisible(visible); - - // removing per https://github.com/processing/processing/pull/3162 - // can remove the code below once 3.0a6 is tested and behaving -/* - if (visible && PApplet.platform == PConstants.LINUX) { - // Linux doesn't deal with insets the same way. We get fake insets - // earlier, and then the window manager will slap its own insets - // onto things once the frame is realized on the screen. Awzm. - if (PApplet.platform == PConstants.LINUX) { - Insets insets = frame.getInsets(); - frame.setSize(Math.max(sketchWidth, MIN_WINDOW_WIDTH) + - insets.left + insets.right, - Math.max(sketchHeight, MIN_WINDOW_HEIGHT) + - insets.top + insets.bottom); - } - } -*/ - } +// /** Set the window (and dock, or whatever necessary) title. */ +// public void setTitle(String title) { +// frame.setTitle(title); +// } +// +// +// /** Set true if we want to resize things (default is not resizable) */ +// public void setResizable(boolean resizable) { +// this.resizable = resizable; // really only used for canvas +// +// if (frame != null) { +// frame.setResizable(resizable); +// } +// } +// +// +// public void setVisible(boolean visible) { +// frame.setVisible(visible); +// +// // removing per https://github.com/processing/processing/pull/3162 +// // can remove the code below once 3.0a6 is tested and behaving +///* +// if (visible && PApplet.platform == PConstants.LINUX) { +// // Linux doesn't deal with insets the same way. We get fake insets +// // earlier, and then the window manager will slap its own insets +// // onto things once the frame is realized on the screen. Awzm. +// if (PApplet.platform == PConstants.LINUX) { +// Insets insets = frame.getInsets(); +// frame.setSize(Math.max(sketchWidth, MIN_WINDOW_WIDTH) + +// insets.left + insets.right, +// Math.max(sketchHeight, MIN_WINDOW_HEIGHT) + +// insets.top + insets.bottom); +// } +// } +//*/ +// } //public void placeFullScreen(boolean hideStop) { + @Override public void placePresent(Color stopColor) { // After the pack(), the screen bounds are gonna be 0s frame.setBounds(screenRect); @@ -510,6 +508,7 @@ public class PSurfaceAWT implements PSurface { } + @Override public void placeWindow(int[] location) { setFrameSize(); //sketchWidth, sketchHeight); @@ -549,7 +548,7 @@ public class PSurfaceAWT implements PSurface { // all set for rockin if (sketch.getGraphics().displayable()) { - setVisible(true); + frame.setVisible(true); } } @@ -591,6 +590,7 @@ public class PSurfaceAWT implements PSurface { } + @Override public void placeWindow(int[] location, int[] editorLocation) { //Dimension window = setFrameSize(sketchWidth, sketchHeight); Dimension window = setFrameSize(); //sketchWidth, sketchHeight); @@ -653,74 +653,21 @@ public class PSurfaceAWT implements PSurface { // TODO this is much too late... why even create the enormous frame for PDF? if (sketch.getGraphics().displayable()) { - setVisible(true); - } - } - - - public void startThread() { - if (thread == null) { - thread = new AnimationThread(); - thread.start(); - } else { - throw new IllegalStateException("Thread already started in PSurfaceAWT"); - } - } - - - public boolean stopThread() { - if (thread == null) { - return false; - } - thread = null; - return true; - } - - - public boolean isStopped() { - return thread == null; - } - - - // sets a flag to pause the thread when ready - public void pauseThread() { - PApplet.debug("PApplet.run() paused, calling object wait..."); - paused = true; - } - - - // halts the animation thread if the pause flag is set - protected void checkPause() { - if (paused) { - synchronized (pauseObject) { - try { - pauseObject.wait(); -// PApplet.debug("out of wait"); - } catch (InterruptedException e) { - // waiting for this interrupt on a start() (resume) call - } - } - } -// PApplet.debug("done with pause"); - } - - - public void resumeThread() { - paused = false; - synchronized (pauseObject) { - pauseObject.notifyAll(); // wake up the animation thread + frame.setVisible(true); } } // needs to resize the frame, which will resize the canvas, and so on... + @Override public void setSize(int wide, int high) { -// System.out.format("frame visible %b, setSize(%d, %d) %n", frame.isVisible(), wide, high); if (PApplet.DEBUG) { + //System.out.format("frame visible %b, setSize(%d, %d) %n", frame.isVisible(), wide, high); new Exception(String.format("setSize(%d, %d)", wide, high)).printStackTrace(System.out); } - if (wide == sketchWidth && high == sketchHeight) { + //if (wide == sketchWidth && high == sketchHeight) { // doesn't work on launch + if (wide == sketch.width && high == sketch.height) { if (PApplet.DEBUG) { new Exception("w/h unchanged " + wide + " " + high).printStackTrace(System.out); } @@ -732,7 +679,7 @@ public class PSurfaceAWT implements PSurface { // canvas.setSize(wide, high); // frame.setSize(wide, high); - if (frame != null) { // canvas only + if (frame != null) { // skip if just a canvas setFrameSize(); //wide, high); } setCanvasSize(); @@ -740,7 +687,7 @@ public class PSurfaceAWT implements PSurface { // frame.setLocationRelativeTo(null); // } - initImage(graphics, wide, high); + //initImage(graphics, wide, high); //throw new RuntimeException("implement me, see readme.md"); sketch.width = wide; @@ -748,25 +695,32 @@ public class PSurfaceAWT implements PSurface { // set PGraphics variables for width/height/pixelWidth/pixelHeight graphics.setSize(wide, high); +// System.out.println("out of setSize()"); } - public void initImage(PGraphics gr, int wide, int high) { + //public void initImage(PGraphics gr, int wide, int high) { + /* + @Override + public void initImage(PGraphics graphics) { GraphicsConfiguration gc = canvas.getGraphicsConfiguration(); // If not realized (off-screen, i.e the Color Selector Tool), gc will be null. if (gc == null) { - System.err.println("GraphicsConfiguration null in setSize()"); + System.err.println("GraphicsConfiguration null in initImage()"); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); gc = ge.getDefaultScreenDevice().getDefaultConfiguration(); } // Formerly this was broken into separate versions based on offscreen or // not, but we may as well create a compatible image; it won't hurt, right? - int factor = gr.pixelFactor; - gr.image = gc.createCompatibleImage(wide * factor, high * factor); + int wide = graphics.width * graphics.pixelFactor; + int high = graphics.height * graphics.pixelFactor; + graphics.image = gc.createCompatibleImage(wide, high); } + */ + @Override public void setSmooth(int level) { } @@ -850,6 +804,7 @@ public class PSurfaceAWT implements PSurface { * (so that it will be saved by the PDE for the next run) and * notify on quit. See more notes in the Worker class. */ + @Override public void setupExternalMessages() { frame.addComponentListener(new ComponentAdapter() { @@ -1291,128 +1246,6 @@ public class PSurfaceAWT implements PSurface { // addListeners(comp); // } - public void setFrameRate(float fps) { - frameRateTarget = fps; - frameRatePeriod = (long) (1000000000.0 / frameRateTarget); - //g.setFrameRate(fps); - } - - - class AnimationThread extends Thread { - - public AnimationThread() { - super("Animation Thread"); - } - - /** - * Main method for the primary animation thread. - * Painting in AWT and Swing - */ - @Override - public void run() { // not good to make this synchronized, locks things up - long beforeTime = System.nanoTime(); - long overSleepTime = 0L; - - int noDelays = 0; - // Number of frames with a delay of 0 ms before the - // animation thread yields to other running threads. - final int NO_DELAYS_PER_YIELD = 15; - - /* - // If size un-initialized, might be a Canvas. Call setSize() here since - // we now have a parent object that this Canvas can use as a peer. - if (graphics.image == null) { -// System.out.format("it's null, sketchW/H already set to %d %d%n", sketchWidth, sketchHeight); - try { - EventQueue.invokeAndWait(new Runnable() { - public void run() { - setSize(sketchWidth, sketchHeight); - } - }); - } catch (InterruptedException ie) { - ie.printStackTrace(); - } catch (InvocationTargetException ite) { - ite.printStackTrace(); - } -// System.out.format(" but now, sketchW/H changed to %d %d%n", sketchWidth, sketchHeight); - } - */ - - // un-pause the sketch and get rolling - sketch.start(); - - while ((Thread.currentThread() == thread) && !sketch.finished) { - checkPause(); - - // Don't resize the renderer from the EDT (i.e. from a ComponentEvent), - // otherwise it may attempt a resize mid-render. -// Dimension currentSize = canvas.getSize(); -// if (currentSize.width != sketchWidth || currentSize.height != sketchHeight) { -// System.err.format("need to resize from %s to %d, %d%n", currentSize, sketchWidth, sketchHeight); -// } - - // render a single frame -// try { -// EventQueue.invokeAndWait(new Runnable() { -// public void run() { - sketch.handleDraw(); - -// EventQueue.invokeLater(new Runnable() { -// public void run() { - if (sketch.frameCount == 1) { - requestFocus(); - } -// } -// }); - -// } -// }); -// } catch (InterruptedException ie) { -// ie.printStackTrace(); -// } catch (InvocationTargetException ite) { -// ite.getTargetException().printStackTrace(); -// } - - // wait for update & paint to happen before drawing next frame - // this is necessary since the drawing is sometimes in a - // separate thread, meaning that the next frame will start - // before the update/paint is completed - - long afterTime = System.nanoTime(); - long timeDiff = afterTime - beforeTime; - //System.out.println("time diff is " + timeDiff); - long sleepTime = (frameRatePeriod - timeDiff) - overSleepTime; - - if (sleepTime > 0) { // some time left in this cycle - try { - Thread.sleep(sleepTime / 1000000L, (int) (sleepTime % 1000000L)); - noDelays = 0; // Got some sleep, not delaying anymore - } catch (InterruptedException ex) { } - - overSleepTime = (System.nanoTime() - afterTime) - sleepTime; - - } else { // sleepTime <= 0; the frame took longer than the period - overSleepTime = 0L; - noDelays++; - - if (noDelays > NO_DELAYS_PER_YIELD) { - Thread.yield(); // give another thread a chance to run - noDelays = 0; - } - } - - beforeTime = System.nanoTime(); - } - - sketch.dispose(); // call to shutdown libs? - - // If the user called the exit() function, the window should close, - // rather than the sketch just halting. - if (sketch.exitCalled) { - sketch.exitActual(); - } - } - } // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @@ -1423,6 +1256,7 @@ public class PSurfaceAWT implements PSurface { Cursor invisibleCursor; + @Override public void setCursor(int kind) { // Swap the HAND cursor because MOVE doesn't seem to be available on OS X // https://github.com/processing/processing/issues/2358 @@ -1435,6 +1269,7 @@ public class PSurfaceAWT implements PSurface { } + @Override public void setCursor(PImage img, int x, int y) { // Don't set cursorType, instead use cursorType to save the last // regular cursor type used for when cursor() is called. @@ -1448,6 +1283,7 @@ public class PSurfaceAWT implements PSurface { } + @Override public void showCursor() { // Maybe should always set here? Seems dangerous, since it's likely that // Java will set the cursor to something else on its own, and the sketch @@ -1459,6 +1295,7 @@ public class PSurfaceAWT implements PSurface { } + @Override public void hideCursor() { // Because the OS may have shown the cursor on its own, // don't return if 'cursorVisible' is set to true. [rev 0216] diff --git a/core/src/processing/core/PSurfaceBasic.java b/core/src/processing/core/PSurfaceBasic.java new file mode 100644 index 000000000..96678091b --- /dev/null +++ b/core/src/processing/core/PSurfaceBasic.java @@ -0,0 +1,290 @@ +/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2015 The Processing Foundation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation, version 2.1. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +package processing.core; + +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Component; +import java.awt.Frame; + + +public class PSurfaceBasic implements PSurface { + PApplet sketch; + + Thread thread; + boolean paused; + Object pauseObject = new Object(); + + protected float frameRateTarget = 60; + protected long frameRatePeriod = 1000000000L / 60L; + + + public PSurfaceBasic() { } + + + public void initOffscreen(PApplet sketch) { + // TODO Auto-generated method stub + } + + + public Canvas initCanvas(PApplet sketch) { + return null; + } + + + public Frame initFrame(PApplet sketch, Color backgroundColor, + int deviceIndex, boolean fullScreen, + boolean spanDisplays) { + return null; + } + + + public void placeWindow(int[] location) { } + + public void placeWindow(int[] location, int[] editorLocation) { } + + public void placePresent(Color stopColor) { } + + public void setupExternalMessages() { } + + + // + + + public void setSize(int width, int height) { + // TODO Auto-generated method stub + + } + +// public void initImage(PGraphics graphics) { +// // TODO Auto-generated method stub +// +// } + + public Component getComponent() { + return null; + } + + public void setSmooth(int level) { + // TODO Auto-generated method stub + + } + + public void requestFocus() { + // TODO Auto-generated method stub + + } + + public void blit() { + // TODO Auto-generated method stub + } + + public void setCursor(int kind) { } + + public void setCursor(PImage image, int hotspotX, int hotspotY) { } + + public void showCursor() { } + + public void hideCursor() { } + + + // + + + public void startThread() { + if (thread == null) { + thread = new AnimationThread(); + thread.start(); + } else { + throw new IllegalStateException("Thread already started in PSurfaceAWT"); + } + } + + + public boolean stopThread() { + if (thread == null) { + return false; + } + thread = null; + return true; + } + + + public boolean isStopped() { + return thread == null; + } + + + // sets a flag to pause the thread when ready + public void pauseThread() { + PApplet.debug("PApplet.run() paused, calling object wait..."); + paused = true; + } + + + // halts the animation thread if the pause flag is set + protected void checkPause() { + if (paused) { + synchronized (pauseObject) { + try { + pauseObject.wait(); +// PApplet.debug("out of wait"); + } catch (InterruptedException e) { + // waiting for this interrupt on a start() (resume) call + } + } + } +// PApplet.debug("done with pause"); + } + + + public void resumeThread() { + paused = false; + synchronized (pauseObject) { + pauseObject.notifyAll(); // wake up the animation thread + } + } + + + public void setFrameRate(float fps) { + frameRateTarget = fps; + frameRatePeriod = (long) (1000000000.0 / frameRateTarget); + //g.setFrameRate(fps); + } + + class AnimationThread extends Thread { + + public AnimationThread() { + super("Animation Thread"); + } + + /** + * Main method for the primary animation thread. + * Painting in AWT and Swing + */ + @Override + public void run() { // not good to make this synchronized, locks things up + long beforeTime = System.nanoTime(); + long overSleepTime = 0L; + + int noDelays = 0; + // Number of frames with a delay of 0 ms before the + // animation thread yields to other running threads. + final int NO_DELAYS_PER_YIELD = 15; + + /* + // If size un-initialized, might be a Canvas. Call setSize() here since + // we now have a parent object that this Canvas can use as a peer. + if (graphics.image == null) { +// System.out.format("it's null, sketchW/H already set to %d %d%n", sketchWidth, sketchHeight); + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + setSize(sketchWidth, sketchHeight); + } + }); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } catch (InvocationTargetException ite) { + ite.printStackTrace(); + } +// System.out.format(" but now, sketchW/H changed to %d %d%n", sketchWidth, sketchHeight); + } + */ + + // un-pause the sketch and get rolling + sketch.start(); + + while ((Thread.currentThread() == thread) && !sketch.finished) { + checkPause(); + + // Don't resize the renderer from the EDT (i.e. from a ComponentEvent), + // otherwise it may attempt a resize mid-render. +// Dimension currentSize = canvas.getSize(); +// if (currentSize.width != sketchWidth || currentSize.height != sketchHeight) { +// System.err.format("need to resize from %s to %d, %d%n", currentSize, sketchWidth, sketchHeight); +// } + + // render a single frame +// try { +// EventQueue.invokeAndWait(new Runnable() { +// public void run() { + sketch.handleDraw(); + +// EventQueue.invokeLater(new Runnable() { +// public void run() { + if (sketch.frameCount == 1) { + requestFocus(); + } +// } +// }); + +// } +// }); +// } catch (InterruptedException ie) { +// ie.printStackTrace(); +// } catch (InvocationTargetException ite) { +// ite.getTargetException().printStackTrace(); +// } + + // wait for update & paint to happen before drawing next frame + // this is necessary since the drawing is sometimes in a + // separate thread, meaning that the next frame will start + // before the update/paint is completed + + long afterTime = System.nanoTime(); + long timeDiff = afterTime - beforeTime; + //System.out.println("time diff is " + timeDiff); + long sleepTime = (frameRatePeriod - timeDiff) - overSleepTime; + + if (sleepTime > 0) { // some time left in this cycle + try { + Thread.sleep(sleepTime / 1000000L, (int) (sleepTime % 1000000L)); + noDelays = 0; // Got some sleep, not delaying anymore + } catch (InterruptedException ex) { } + + overSleepTime = (System.nanoTime() - afterTime) - sleepTime; + + } else { // sleepTime <= 0; the frame took longer than the period + overSleepTime = 0L; + noDelays++; + + if (noDelays > NO_DELAYS_PER_YIELD) { + Thread.yield(); // give another thread a chance to run + noDelays = 0; + } + } + + beforeTime = System.nanoTime(); + } + + sketch.dispose(); // call to shutdown libs? + + // If the user called the exit() function, the window should close, + // rather than the sketch just halting. + if (sketch.exitCalled) { + sketch.exitActual(); + } + } + } +} \ No newline at end of file diff --git a/core/src/processing/opengl/PSurfaceLWJGL.java b/core/src/processing/opengl/PSurfaceLWJGL.java index 80d276638..37cba4f7d 100644 --- a/core/src/processing/opengl/PSurfaceLWJGL.java +++ b/core/src/processing/opengl/PSurfaceLWJGL.java @@ -2,6 +2,7 @@ package processing.opengl; import java.awt.Canvas; import java.awt.Color; +import java.awt.Component; import java.awt.Dimension; import java.awt.Frame; import java.awt.GraphicsConfiguration; @@ -77,7 +78,7 @@ public class PSurfaceLWJGL implements PSurface { @Override - public void initOffscreen() { + public void initOffscreen(PApplet sketch) { } @@ -232,24 +233,24 @@ public class PSurfaceLWJGL implements PSurface { } - @Override - public void setTitle(String title) { - Display.setTitle(title); - } - - - @Override - public void setVisible(boolean visible) { - // Apparently not possible: - // http://forum.lwjgl.org/index.php?topic=5388.0 - System.err.println("Cannot set visibility of window in OpenGL"); - } - - - @Override - public void setResizable(boolean resizable) { - Display.setResizable(resizable); - } +// @Override +// public void setTitle(String title) { +// Display.setTitle(title); +// } +// +// +// @Override +// public void setVisible(boolean visible) { +// // Apparently not possible: +// // http://forum.lwjgl.org/index.php?topic=5388.0 +// System.err.println("Cannot set visibility of window in OpenGL"); +// } +// +// +// @Override +// public void setResizable(boolean resizable) { +// Display.setResizable(resizable); +// } @Override @@ -415,8 +416,12 @@ public class PSurfaceLWJGL implements PSurface { } - public void initImage(PGraphics gr, int wide, int high) { - // TODO not sure yet how to implement [fry] +// @Override +// public void initImage(PGraphics graphics) { +// // TODO not sure yet how to implement [fry] +// } + public Component getComponent() { + return frame; } @@ -624,6 +629,8 @@ public class PSurfaceLWJGL implements PSurface { } } + + /////////////////////////////////////////////////////////// // LWJGL event handling diff --git a/java/libraries/pdf/src/processing/pdf/PGraphicsPDF.java b/java/libraries/pdf/src/processing/pdf/PGraphicsPDF.java index 7198c0d4f..e9dac07f0 100644 --- a/java/libraries/pdf/src/processing/pdf/PGraphicsPDF.java +++ b/java/libraries/pdf/src/processing/pdf/PGraphicsPDF.java @@ -100,6 +100,13 @@ public class PGraphicsPDF extends PGraphicsJava2D { } + @Override + public PSurface createSurface() { + return surface = new PSurfaceBasic(); + } + + + @Override protected void defaultSettings() { // ignore super.defaultSettings(); textMode = SHAPE; @@ -141,7 +148,7 @@ public class PGraphicsPDF extends PGraphicsJava2D { // g2 = template.createGraphics(width, height, mapper); } // System.out.println("beginDraw " + (System.currentTimeMillis() - t0)); - + // super in Java2D now creates an image buffer, don't do that // super.beginDraw(); checkSettings();