Last active
March 26, 2019 17:57
-
-
Save GoToLoop/1d1eb18f468a7d5758469707276b6ea1 to your computer and use it in GitHub Desktop.
Canvas Resize Watcher
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Canvas Resize Watcher (v1.0) | |
* GoToLoop (2018/May/04) | |
* Developed on P3 (v3.3.5) | |
* | |
* https://Discourse.Processing.org/t/event-called-when-canvas-is-resized/6643/8 | |
* https://Gist.GitHub.com/GoToLoop/1d1eb18f468a7d5758469707276b6ea1 | |
*/ | |
import gotoloop.listener.CanvasResizeWatcher; | |
static final String RENDERER = FX2D; | |
static final color BG = 0x40 << 030, BG_RANGE = 1 << 030; | |
static final color FILL = -1, STROKE = 0; | |
static final float WEIGHT = 2.5, FPS = 60.0; | |
PGraphics pg; | |
color bg; | |
CanvasResizeWatcher watcher; | |
void setup() { | |
size(800, 600, RENDERER); | |
frameRate(FPS); | |
cursor(ARROW); | |
colorMode(RGB); | |
imageMode(CENTER); | |
createLayer(); | |
println( watcher = new CanvasResizeWatcher(this).start() ); | |
} | |
void draw() { | |
background(bg); | |
image(pg, width>>1, height>>1); | |
displayTitle(); | |
} | |
void mousePressed() { | |
final CanvasResizeWatcher w = watcher; | |
switch (mouseButton) { | |
case LEFT: | |
if (w.isPaused()) w.resume(); | |
else w.pause(); | |
return; | |
case RIGHT: | |
w.immediate ^= true; | |
return; | |
default: | |
w.resume(); | |
w.immediate = false; | |
} | |
} | |
void displayTitle() { | |
final CanvasResizeWatcher w = watcher; | |
getSurface().setTitle("Paused: " + w.isPaused() | |
+ " - Immediate: " + w.immediate); | |
} | |
void frameResized(final int w, final int h) { | |
createLayer(); | |
bg = (color) random(BG_RANGE); | |
print(w, h, TAB); | |
} | |
void createLayer() { | |
final int w = max(1, width>>1), h = max(1, height>>1); | |
( pg = createGraphics(w, h) ).beginDraw(); | |
pg.colorMode(RGB); | |
pg.background(BG); | |
pg.fill(FILL); | |
pg.stroke(STROKE); | |
pg.strokeWeight(WEIGHT); | |
pg.ellipseMode(CENTER); | |
pg.ellipse(pg.width>>1, pg.height>>1, pg.width, pg.height); | |
pg.endDraw(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Canvas Resize Watcher (v1.0) | |
* GoToLoop (2018/May/04) | |
* Developed on P3 (v3.3.5) | |
* | |
* https://Discourse.Processing.org/t/event-called-when-canvas-is-resized/6643/8 | |
* https://Gist.GitHub.com/GoToLoop/1d1eb18f468a7d5758469707276b6ea1 | |
*/ | |
package gotoloop.listener; | |
import processing.core.PApplet; | |
import processing.core.PGraphics; | |
import java.util.concurrent.atomic.AtomicBoolean; | |
// JAVA2D | |
import java.awt.Component; | |
import java.awt.event.ComponentAdapter; | |
import java.awt.event.ComponentEvent; | |
// FX2D | |
import javafx.scene.canvas.Canvas; | |
import javafx.beans.value.ChangeListener; | |
import javafx.beans.value.ObservableValue; | |
// P2D, P3D & OPENGL | |
import com.jogamp.newt.Window; | |
import com.jogamp.newt.event.WindowAdapter; | |
import com.jogamp.newt.event.WindowEvent; | |
public class CanvasResizeWatcher { | |
protected final AtomicBoolean resized = new AtomicBoolean(); | |
protected final PApplet p; | |
protected final Object window; | |
protected final PGraphics pg; | |
protected SizeListener listener; | |
protected boolean paused = true; | |
public boolean immediate, auto, synced; | |
public CanvasResizeWatcher(final PApplet pa) { | |
this(pa, false); | |
} | |
public CanvasResizeWatcher(final PApplet pa, boolean now) { | |
window = ( p = pa ).getSurface().getNative(); | |
pg = pa.getGraphics(); | |
immediate = now; | |
} | |
public CanvasResizeWatcher start() { | |
createRendererListener(); | |
resume().p.getSurface().setResizable(true); | |
return this; | |
} | |
public CanvasResizeWatcher stop() { | |
if (pause().listener != null) { | |
listener.removeListener(); | |
listener = null; | |
} | |
return this; | |
} | |
public CanvasResizeWatcher resume() { | |
if (paused) { | |
p.registerMethod("pre", this); | |
paused = false; | |
} | |
return this; | |
} | |
public CanvasResizeWatcher pause() { | |
if (!paused) { | |
p.unregisterMethod("pre", this); | |
paused = true; | |
} | |
return this; | |
} | |
public boolean isPaused() { | |
return paused; | |
} | |
public void pre() { | |
actIfResized(); | |
} | |
protected boolean actIfResized() { | |
return resized.weakCompareAndSet(true, false) && invokeCallback(); | |
} | |
protected boolean invokeCallback() { | |
if (!paused) { | |
p.frameResized(p.width, p.height); | |
return true; | |
} | |
return false; | |
} | |
public String discoverRenderer() { | |
if (window instanceof Canvas) return PApplet.FX2D; | |
else if (pg.isGL()) return pg.is3D()? PApplet.P3D : PApplet.P2D; | |
return PApplet.JAVA2D; | |
} | |
protected SizeListener createRendererListener() { | |
return createRendererListener(null); | |
} | |
protected SizeListener createRendererListener(String render) { | |
if (render == null || render.isEmpty()) render = discoverRenderer(); | |
switch (render) { | |
case PApplet.P2D: | |
case PApplet.P3D: | |
return new SizeListenerOPENGL(); | |
case PApplet.FX2D: | |
return new SizeListenerFX2D<Double>(); | |
default: | |
return new SizeListenerJAVA2D(); | |
} | |
} | |
@Override public String toString() { | |
return "Renderer: " + listener + "\t\tPaused: " | |
+ paused + "\tImmediate: " + immediate; | |
} | |
public interface SizeListener { | |
SizeListener addListener(); | |
SizeListener removeListener(); | |
} | |
public class SizeListenerJAVA2D extends ComponentAdapter | |
implements SizeListener { | |
public final Component win = (Component) window; | |
public SizeListenerJAVA2D() { | |
if (listener != null) listener.removeListener(); | |
listener = addListener(); | |
} | |
@Override public SizeListener addListener() { | |
win.addComponentListener(this); | |
return this; | |
} | |
@Override public SizeListener removeListener() { | |
win.removeComponentListener(this); | |
return this; | |
} | |
@Override public void componentResized(final ComponentEvent evt) { | |
if (!immediate) resized.set(true); | |
else invokeCallback(); | |
} | |
@Override public String toString() { | |
return discoverRenderer(); | |
} | |
} | |
public class SizeListenerFX2D<N extends Number> | |
implements SizeListener, ChangeListener<N> { | |
public final Canvas win = (Canvas) window; | |
protected final ChangeListener changeListener = this; | |
public SizeListenerFX2D() { | |
if (listener != null) listener.removeListener(); | |
listener = addListener(); | |
} | |
@Override public SizeListener addListener() { | |
win.widthProperty().addListener(changeListener); | |
win.heightProperty().addListener(changeListener); | |
return this; | |
} | |
@Override public SizeListener removeListener() { | |
win.widthProperty().removeListener(changeListener); | |
win.heightProperty().removeListener(changeListener); | |
return this; | |
} | |
@Override public void | |
changed(ObservableValue<? extends N> obs, N old, N cur) { | |
if (!immediate) resized.set(true); | |
else invokeCallback(); | |
} | |
@Override public String toString() { | |
return discoverRenderer(); | |
} | |
} | |
public class SizeListenerOPENGL extends WindowAdapter | |
implements SizeListener { | |
public final Window win = (Window) window; | |
public SizeListenerOPENGL() { | |
if (listener != null) listener.removeListener(); | |
listener = addListener(); | |
} | |
@Override public SizeListener addListener() { | |
win.addWindowListener(this); | |
return this; | |
} | |
@Override public SizeListener removeListener() { | |
win.removeWindowListener(this); | |
return this; | |
} | |
@Override public void windowResized(final WindowEvent evt) { | |
if (!immediate) resized.set(true); | |
else invokeCallback(); | |
} | |
@Override public String toString() { | |
return discoverRenderer(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment