propane 3.1.0.pre-java → 3.2.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.mvn/wrapper/maven-wrapper.properties +1 -0
- data/CHANGELOG.md +1 -5
- data/README.md +23 -12
- data/Rakefile +23 -12
- data/lib/propane/helpers/version_error.rb +6 -0
- data/lib/propane/runner.rb +12 -0
- data/lib/propane/version.rb +1 -1
- data/library/slider/slider.rb +1 -1
- data/mvnw +234 -0
- data/mvnw.cmd +145 -0
- data/pom.xml +28 -27
- data/propane.gemspec +2 -2
- data/src/main/java/japplemenubar/JAppleMenuBar.java +41 -47
- data/src/main/java/monkstone/ColorUtil.java +1 -1
- data/src/main/java/monkstone/MathToolModule.java +12 -11
- data/src/main/java/monkstone/PropaneLibrary.java +9 -10
- data/src/main/java/monkstone/core/LibraryProxy.java +124 -113
- data/src/main/java/monkstone/fastmath/Deglut.java +86 -89
- data/src/main/java/monkstone/filechooser/Chooser.java +7 -13
- data/src/main/java/monkstone/noise/SimplexNoise.java +0 -1
- data/src/main/java/monkstone/slider/CustomHorizontalSlider.java +4 -4
- data/src/main/java/monkstone/slider/CustomVerticalSlider.java +1 -1
- data/src/main/java/monkstone/slider/SimpleHorizontalSlider.java +9 -9
- data/src/main/java/monkstone/slider/SimpleSlider.java +0 -9
- data/src/main/java/monkstone/slider/SimpleVerticalSlider.java +11 -13
- data/src/main/java/monkstone/slider/Slider.java +1 -1
- data/src/main/java/monkstone/slider/SliderBar.java +1 -1
- data/src/main/java/monkstone/slider/SliderGroup.java +1 -1
- data/src/main/java/monkstone/slider/WheelHandler.java +8 -9
- data/src/main/java/monkstone/vecmath/AppRender.java +2 -2
- data/src/main/java/monkstone/vecmath/ShapeRender.java +2 -2
- data/src/main/java/monkstone/vecmath/package-info.java +2 -2
- data/src/main/java/monkstone/vecmath/vec2/Vec2.java +2 -2
- data/src/main/java/monkstone/vecmath/vec3/Vec3.java +1 -1
- data/src/main/java/monkstone/videoevent/VideoInterface.java +11 -5
- data/src/main/java/monkstone/videoevent/package-info.java +2 -2
- data/src/main/java/processing/awt/PGraphicsJava2D.java +1742 -2243
- data/src/main/java/processing/awt/PShapeJava2D.java +268 -270
- data/src/main/java/processing/awt/PSurfaceAWT.java +821 -920
- data/src/main/java/processing/core/DesktopHandler.java +94 -0
- data/src/main/java/processing/core/PApplet.java +14170 -14082
- data/src/main/java/processing/core/PConstants.java +447 -473
- data/src/main/java/processing/core/PFont.java +867 -873
- data/src/main/java/processing/core/PGraphics.java +7193 -7428
- data/src/main/java/processing/core/PImage.java +3051 -3117
- data/src/main/java/processing/core/PMatrix.java +159 -172
- data/src/main/java/processing/core/PMatrix2D.java +403 -444
- data/src/main/java/processing/core/PMatrix3D.java +735 -749
- data/src/main/java/processing/core/PShape.java +2651 -2793
- data/src/main/java/processing/core/PShapeOBJ.java +415 -422
- data/src/main/java/processing/core/PShapeSVG.java +1466 -1475
- data/src/main/java/processing/core/PStyle.java +37 -40
- data/src/main/java/processing/core/PSurface.java +98 -103
- data/src/main/java/processing/core/PSurfaceNone.java +208 -236
- data/src/main/java/processing/core/PVector.java +961 -990
- data/src/main/java/processing/data/DoubleDict.java +709 -753
- data/src/main/java/processing/data/DoubleList.java +695 -748
- data/src/main/java/processing/data/FloatDict.java +702 -746
- data/src/main/java/processing/data/FloatList.java +697 -751
- data/src/main/java/processing/data/IntDict.java +673 -718
- data/src/main/java/processing/data/IntList.java +633 -699
- data/src/main/java/processing/data/JSONArray.java +873 -931
- data/src/main/java/processing/data/JSONObject.java +1165 -1262
- data/src/main/java/processing/data/JSONTokener.java +341 -351
- data/src/main/java/processing/data/LongDict.java +662 -707
- data/src/main/java/processing/data/LongList.java +634 -700
- data/src/main/java/processing/data/Sort.java +41 -37
- data/src/main/java/processing/data/StringDict.java +486 -522
- data/src/main/java/processing/data/StringList.java +580 -624
- data/src/main/java/processing/data/Table.java +3508 -3686
- data/src/main/java/processing/data/TableRow.java +183 -182
- data/src/main/java/processing/data/XML.java +883 -957
- data/src/main/java/processing/event/Event.java +66 -87
- data/src/main/java/processing/event/KeyEvent.java +41 -48
- data/src/main/java/processing/event/MouseEvent.java +93 -103
- data/src/main/java/processing/event/TouchEvent.java +6 -10
- data/src/main/java/processing/javafx/PGraphicsFX2D.java +5 -69
- data/src/main/java/processing/javafx/PSurfaceFX.java +2 -7
- data/src/main/java/processing/opengl/FontTexture.java +270 -290
- data/src/main/java/processing/opengl/FrameBuffer.java +363 -375
- data/src/main/java/processing/opengl/LinePath.java +500 -543
- data/src/main/java/processing/opengl/LineStroker.java +582 -593
- data/src/main/java/processing/opengl/PGL.java +2881 -2904
- data/src/main/java/processing/opengl/PGraphics2D.java +315 -408
- data/src/main/java/processing/opengl/PGraphics3D.java +72 -107
- data/src/main/java/processing/opengl/PGraphicsOpenGL.java +12043 -12230
- data/src/main/java/processing/opengl/PJOGL.java +1681 -1745
- data/src/main/java/processing/opengl/PShader.java +1257 -1260
- data/src/main/java/processing/opengl/PShapeOpenGL.java +4599 -4662
- data/src/main/java/processing/opengl/PSurfaceJOGL.java +1030 -1047
- data/src/main/java/processing/opengl/Texture.java +1397 -1462
- data/src/main/java/processing/opengl/VertexBuffer.java +55 -57
- data/src/main/resources/icon/icon-1024.png +0 -0
- data/src/main/resources/icon/icon-128.png +0 -0
- data/src/main/resources/icon/icon-16.png +0 -0
- data/src/main/resources/icon/icon-256.png +0 -0
- data/src/main/resources/icon/icon-32.png +0 -0
- data/src/main/resources/icon/icon-48.png +0 -0
- data/src/main/resources/icon/icon-512.png +0 -0
- data/src/main/resources/icon/icon-64.png +0 -0
- data/vendors/Rakefile +1 -1
- metadata +12 -8
- data/src/main/java/processing/core/ThinkDifferent.java +0 -70
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
|
2
|
-
|
|
3
1
|
/*
|
|
4
2
|
Part of the Processing project - http://processing.org
|
|
5
3
|
|
|
@@ -20,8 +18,7 @@
|
|
|
20
18
|
Public License along with this library; if not, write to the
|
|
21
19
|
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
22
20
|
Boston, MA 02111-1307 USA
|
|
23
|
-
*/
|
|
24
|
-
|
|
21
|
+
*/
|
|
25
22
|
package processing.opengl;
|
|
26
23
|
|
|
27
24
|
import java.awt.Component;
|
|
@@ -65,7 +62,6 @@ import com.jogamp.newt.event.InputEvent;
|
|
|
65
62
|
import com.jogamp.newt.opengl.GLWindow;
|
|
66
63
|
import com.jogamp.opengl.util.FPSAnimator;
|
|
67
64
|
|
|
68
|
-
|
|
69
65
|
import processing.core.PApplet;
|
|
70
66
|
import processing.core.PConstants;
|
|
71
67
|
import processing.core.PGraphics;
|
|
@@ -74,181 +70,178 @@ import processing.core.PSurface;
|
|
|
74
70
|
import processing.event.KeyEvent;
|
|
75
71
|
import processing.event.MouseEvent;
|
|
76
72
|
|
|
77
|
-
|
|
78
73
|
public class PSurfaceJOGL implements PSurface {
|
|
79
|
-
/** Selected GL profile */
|
|
80
|
-
public static GLProfile profile;
|
|
81
|
-
|
|
82
|
-
public PJOGL pgl;
|
|
83
74
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
75
|
+
/**
|
|
76
|
+
* Selected GL profile
|
|
77
|
+
*/
|
|
78
|
+
public static GLProfile profile;
|
|
87
79
|
|
|
88
|
-
|
|
80
|
+
public PJOGL pgl;
|
|
89
81
|
|
|
90
|
-
|
|
91
|
-
|
|
82
|
+
protected GLWindow window;
|
|
83
|
+
protected FPSAnimator animator;
|
|
84
|
+
protected Rectangle screenRect;
|
|
92
85
|
|
|
93
|
-
|
|
94
|
-
protected int sketchHeight0;
|
|
95
|
-
protected int sketchWidth;
|
|
96
|
-
protected int sketchHeight;
|
|
86
|
+
private Thread drawExceptionHandler;
|
|
97
87
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
protected Rectangle displayRect;
|
|
101
|
-
protected Throwable drawException;
|
|
102
|
-
private final Object drawExceptionMutex = new Object();
|
|
88
|
+
protected PApplet sketch;
|
|
89
|
+
protected PGraphics graphics;
|
|
103
90
|
|
|
104
|
-
|
|
91
|
+
protected int sketchWidth0;
|
|
92
|
+
protected int sketchHeight0;
|
|
93
|
+
protected int sketchWidth;
|
|
94
|
+
protected int sketchHeight;
|
|
105
95
|
|
|
106
|
-
|
|
96
|
+
protected Display display;
|
|
97
|
+
protected Screen screen;
|
|
98
|
+
protected Rectangle displayRect;
|
|
99
|
+
protected Throwable drawException;
|
|
100
|
+
private final Object drawExceptionMutex = new Object();
|
|
107
101
|
|
|
108
|
-
|
|
102
|
+
protected NewtCanvasAWT canvas;
|
|
109
103
|
|
|
110
|
-
|
|
104
|
+
protected int windowScaleFactor;
|
|
111
105
|
|
|
112
|
-
|
|
113
|
-
this.graphics = graphics;
|
|
114
|
-
this.pgl = (PJOGL) ((PGraphicsOpenGL)graphics).pgl;
|
|
115
|
-
}
|
|
106
|
+
protected float[] currentPixelScale = {0, 0};
|
|
116
107
|
|
|
108
|
+
protected boolean external = false;
|
|
117
109
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
sketchWidth = sketch.sketchWidth();
|
|
122
|
-
sketchHeight = sketch.sketchHeight();
|
|
123
|
-
|
|
124
|
-
if (window != null) {
|
|
125
|
-
canvas = new NewtCanvasAWT(window);
|
|
126
|
-
canvas.setBounds(0, 0, window.getWidth(), window.getHeight());
|
|
127
|
-
canvas.setFocusable(true);
|
|
110
|
+
public PSurfaceJOGL(PGraphics graphics) {
|
|
111
|
+
this.graphics = graphics;
|
|
112
|
+
this.pgl = (PJOGL) ((PGraphicsOpenGL) graphics).pgl;
|
|
128
113
|
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
public void initFrame(PApplet sketch) {
|
|
133
|
-
this.sketch = sketch;
|
|
134
|
-
initIcons();
|
|
135
|
-
initDisplay();
|
|
136
|
-
initGL();
|
|
137
|
-
initWindow();
|
|
138
|
-
initListeners();
|
|
139
|
-
initAnimator();
|
|
140
|
-
}
|
|
141
114
|
|
|
115
|
+
public void initOffscreen(PApplet sketch) {
|
|
116
|
+
this.sketch = sketch;
|
|
142
117
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
118
|
+
sketchWidth = sketch.sketchWidth();
|
|
119
|
+
sketchHeight = sketch.sketchHeight();
|
|
146
120
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
screen = NewtFactory.createScreen(display, 0);
|
|
152
|
-
screen.addReference();
|
|
153
|
-
|
|
154
|
-
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
|
155
|
-
GraphicsDevice[] awtDevices = environment.getScreenDevices();
|
|
156
|
-
|
|
157
|
-
GraphicsDevice awtDisplayDevice = null;
|
|
158
|
-
int displayNum = sketch.sketchDisplay();
|
|
159
|
-
if (displayNum > 0) { // if -1, use the default device
|
|
160
|
-
if (displayNum <= awtDevices.length) {
|
|
161
|
-
awtDisplayDevice = awtDevices[displayNum-1];
|
|
162
|
-
} else {
|
|
163
|
-
System.err.format("Display %d does not exist, " +
|
|
164
|
-
"using the default display instead.%n", displayNum);
|
|
165
|
-
for (int i = 0; i < awtDevices.length; i++) {
|
|
166
|
-
System.err.format("Display %d is %s%n", i+1, awtDevices[i]);
|
|
121
|
+
if (window != null) {
|
|
122
|
+
canvas = new NewtCanvasAWT(window);
|
|
123
|
+
canvas.setBounds(0, 0, window.getWidth(), window.getHeight());
|
|
124
|
+
canvas.setFocusable(true);
|
|
167
125
|
}
|
|
168
|
-
}
|
|
169
|
-
} else if (0 < awtDevices.length) {
|
|
170
|
-
awtDisplayDevice = awtDevices[0];
|
|
171
126
|
}
|
|
172
127
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
128
|
+
public void initFrame(PApplet sketch) {
|
|
129
|
+
this.sketch = sketch;
|
|
130
|
+
initIcons();
|
|
131
|
+
initDisplay();
|
|
132
|
+
initGL();
|
|
133
|
+
initWindow();
|
|
134
|
+
initListeners();
|
|
135
|
+
initAnimator();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
public Object getNative() {
|
|
139
|
+
return window;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
protected void initDisplay() {
|
|
143
|
+
display = NewtFactory.createDisplay(null);
|
|
144
|
+
display.addReference();
|
|
145
|
+
screen = NewtFactory.createScreen(display, 0);
|
|
146
|
+
screen.addReference();
|
|
147
|
+
|
|
148
|
+
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
|
149
|
+
GraphicsDevice[] awtDevices = environment.getScreenDevices();
|
|
150
|
+
|
|
151
|
+
GraphicsDevice awtDisplayDevice = null;
|
|
152
|
+
int displayNum = sketch.sketchDisplay();
|
|
153
|
+
if (displayNum > 0) { // if -1, use the default device
|
|
154
|
+
if (displayNum <= awtDevices.length) {
|
|
155
|
+
awtDisplayDevice = awtDevices[displayNum - 1];
|
|
156
|
+
} else {
|
|
157
|
+
System.err.format("Display %d does not exist, "
|
|
158
|
+
+ "using the default display instead.%n", displayNum);
|
|
159
|
+
for (int i = 0; i < awtDevices.length; i++) {
|
|
160
|
+
System.err.format("Display %d is %s%n", i + 1, awtDevices[i]);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
} else if (0 < awtDevices.length) {
|
|
164
|
+
awtDisplayDevice = awtDevices[0];
|
|
165
|
+
}
|
|
176
166
|
|
|
177
|
-
|
|
178
|
-
|
|
167
|
+
if (awtDisplayDevice == null) {
|
|
168
|
+
awtDisplayDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
|
|
169
|
+
}
|
|
179
170
|
|
|
171
|
+
displayRect = awtDisplayDevice.getDefaultConfiguration().getBounds();
|
|
172
|
+
}
|
|
180
173
|
|
|
181
|
-
|
|
174
|
+
protected void initGL() {
|
|
182
175
|
// System.out.println("*******************************");
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
176
|
+
if (profile == null) {
|
|
177
|
+
if (PJOGL.profile == 1) {
|
|
178
|
+
try {
|
|
179
|
+
profile = GLProfile.getGL2ES1();
|
|
180
|
+
} catch (GLException ex) {
|
|
181
|
+
profile = GLProfile.getMaxFixedFunc(true);
|
|
182
|
+
}
|
|
183
|
+
} else if (PJOGL.profile == 2) {
|
|
184
|
+
try {
|
|
185
|
+
profile = GLProfile.getGL2ES2();
|
|
186
|
+
|
|
187
|
+
// workaround for https://jogamp.org/bugzilla/show_bug.cgi?id=1347
|
|
188
|
+
if (!profile.isHardwareRasterizer()) {
|
|
189
|
+
GLProfile hardware = GLProfile.getMaxProgrammable(true);
|
|
190
|
+
if (hardware.isGL2ES2()) {
|
|
191
|
+
profile = hardware;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
} catch (GLException ex) {
|
|
196
|
+
profile = GLProfile.getMaxProgrammable(true);
|
|
197
|
+
}
|
|
198
|
+
} else if (PJOGL.profile == 3) {
|
|
199
|
+
try {
|
|
200
|
+
profile = GLProfile.getGL2GL3();
|
|
201
|
+
} catch (GLException ex) {
|
|
202
|
+
profile = GLProfile.getMaxProgrammable(true);
|
|
203
|
+
}
|
|
204
|
+
if (!profile.isGL3()) {
|
|
205
|
+
PGraphics.showWarning("Requested profile GL3 but is not available, got: " + profile);
|
|
206
|
+
}
|
|
207
|
+
} else if (PJOGL.profile == 4) {
|
|
208
|
+
try {
|
|
209
|
+
profile = GLProfile.getGL4ES3();
|
|
210
|
+
} catch (GLException ex) {
|
|
211
|
+
profile = GLProfile.getMaxProgrammable(true);
|
|
212
|
+
}
|
|
213
|
+
if (!profile.isGL4()) {
|
|
214
|
+
PGraphics.showWarning("Requested profile GL4 but is not available, got: " + profile);
|
|
215
|
+
}
|
|
216
|
+
} else {
|
|
217
|
+
throw new RuntimeException(PGL.UNSUPPORTED_GLPROF_ERROR);
|
|
199
218
|
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
} catch (GLException ex) {
|
|
203
|
-
profile = GLProfile.getMaxProgrammable(true);
|
|
204
|
-
}
|
|
205
|
-
} else if (PJOGL.profile == 3) {
|
|
206
|
-
try {
|
|
207
|
-
profile = GLProfile.getGL2GL3();
|
|
208
|
-
} catch (GLException ex) {
|
|
209
|
-
profile = GLProfile.getMaxProgrammable(true);
|
|
210
|
-
}
|
|
211
|
-
if (!profile.isGL3()) {
|
|
212
|
-
PGraphics.showWarning("Requested profile GL3 but is not available, got: " + profile);
|
|
213
|
-
}
|
|
214
|
-
} else if (PJOGL.profile == 4) {
|
|
215
|
-
try {
|
|
216
|
-
profile = GLProfile.getGL4ES3();
|
|
217
|
-
} catch (GLException ex) {
|
|
218
|
-
profile = GLProfile.getMaxProgrammable(true);
|
|
219
|
-
}
|
|
220
|
-
if (!profile.isGL4()) {
|
|
221
|
-
PGraphics.showWarning("Requested profile GL4 but is not available, got: " + profile);
|
|
222
219
|
}
|
|
223
|
-
} else throw new RuntimeException(PGL.UNSUPPORTED_GLPROF_ERROR);
|
|
224
|
-
}
|
|
225
220
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
221
|
+
// Setting up the desired capabilities;
|
|
222
|
+
GLCapabilities caps = new GLCapabilities(profile);
|
|
223
|
+
caps.setAlphaBits(PGL.REQUESTED_ALPHA_BITS);
|
|
224
|
+
caps.setDepthBits(PGL.REQUESTED_DEPTH_BITS);
|
|
225
|
+
caps.setStencilBits(PGL.REQUESTED_STENCIL_BITS);
|
|
231
226
|
|
|
232
227
|
// caps.setPBuffer(false);
|
|
233
228
|
// caps.setFBO(false);
|
|
234
|
-
|
|
235
229
|
// pgl.reqNumSamples = PGL.smoothToSamples(graphics.smooth);
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
230
|
+
caps.setSampleBuffers(true);
|
|
231
|
+
caps.setNumSamples(PGL.smoothToSamples(graphics.smooth));
|
|
232
|
+
caps.setBackgroundOpaque(true);
|
|
233
|
+
caps.setOnscreen(true);
|
|
234
|
+
pgl.setCaps(caps);
|
|
235
|
+
}
|
|
243
236
|
|
|
244
|
-
|
|
245
|
-
|
|
237
|
+
protected void initWindow() {
|
|
238
|
+
window = GLWindow.create(screen, pgl.getCaps());
|
|
246
239
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
240
|
+
// Make sure that we pass the window close through to exit(), otherwise
|
|
241
|
+
// we're likely to have OpenGL try to shut down halfway through rendering
|
|
242
|
+
// a frame. Particularly problematic for complex/slow apps.
|
|
243
|
+
// https://github.com/processing/processing/issues/4690
|
|
244
|
+
window.setDefaultCloseOperation(WindowClosingProtocol.WindowClosingMode.DO_NOTHING_ON_CLOSE);
|
|
252
245
|
|
|
253
246
|
// if (displayDevice == null) {
|
|
254
247
|
//
|
|
@@ -256,26 +249,25 @@ public class PSurfaceJOGL implements PSurface {
|
|
|
256
249
|
// } else {
|
|
257
250
|
// window = GLWindow.create(displayDevice.getScreen(), pgl.getCaps());
|
|
258
251
|
// }
|
|
252
|
+
windowScaleFactor = PApplet.platform == PConstants.MACOSX
|
|
253
|
+
? 1 : sketch.pixelDensity;
|
|
259
254
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
new Rectangle((int) displayRect.getX(), (int) displayRect.getY(),
|
|
267
|
-
(int) displayRect.getWidth(),
|
|
268
|
-
(int) displayRect.getHeight());
|
|
255
|
+
boolean spanDisplays = sketch.sketchDisplay() == PConstants.SPAN;
|
|
256
|
+
screenRect = spanDisplays
|
|
257
|
+
? new Rectangle(screen.getX(), screen.getY(), screen.getWidth(), screen.getHeight())
|
|
258
|
+
: new Rectangle((int) displayRect.getX(), (int) displayRect.getY(),
|
|
259
|
+
(int) displayRect.getWidth(),
|
|
260
|
+
(int) displayRect.getHeight());
|
|
269
261
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
262
|
+
// Set the displayWidth/Height variables inside PApplet, so that they're
|
|
263
|
+
// usable and can even be returned by the sketchWidth()/Height() methods.
|
|
264
|
+
sketch.displayWidth = screenRect.width;
|
|
265
|
+
sketch.displayHeight = screenRect.height;
|
|
274
266
|
|
|
275
|
-
|
|
276
|
-
|
|
267
|
+
sketchWidth0 = sketch.sketchWidth();
|
|
268
|
+
sketchHeight0 = sketch.sketchHeight();
|
|
277
269
|
|
|
278
|
-
|
|
270
|
+
/*
|
|
279
271
|
// Trying to fix
|
|
280
272
|
// https://github.com/processing/processing/issues/3401
|
|
281
273
|
if (sketch.displayWidth < sketch.width ||
|
|
@@ -292,18 +284,17 @@ public class PSurfaceJOGL implements PSurface {
|
|
|
292
284
|
// graphics.setSize(w, h - 22 - 22);
|
|
293
285
|
System.err.println("setting width/height to " + w + " " + h);
|
|
294
286
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
sketchHeight = sketch.sketchHeight();
|
|
287
|
+
*/
|
|
288
|
+
sketchWidth = sketch.sketchWidth();
|
|
289
|
+
sketchHeight = sketch.sketchHeight();
|
|
299
290
|
// System.out.println("init: " + sketchWidth + " " + sketchHeight);
|
|
300
291
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
292
|
+
boolean fullScreen = sketch.sketchFullScreen();
|
|
293
|
+
// Removing the section below because sometimes people want to do the
|
|
294
|
+
// full screen size in a window, and it also breaks insideSettings().
|
|
295
|
+
// With 3.x, fullScreen() is so easy, that it's just better that way.
|
|
296
|
+
// https://github.com/processing/processing/issues/3545
|
|
297
|
+
/*
|
|
307
298
|
// Sketch has already requested to be the same as the screen's
|
|
308
299
|
// width and height, so let's roll with full screen mode.
|
|
309
300
|
if (screenRect.width == sketchWidth &&
|
|
@@ -311,337 +302,335 @@ public class PSurfaceJOGL implements PSurface {
|
|
|
311
302
|
fullScreen = true;
|
|
312
303
|
sketch.fullScreen();
|
|
313
304
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
if (fullScreen || spanDisplays) {
|
|
317
|
-
sketchWidth = screenRect.width / windowScaleFactor;
|
|
318
|
-
sketchHeight = screenRect.height / windowScaleFactor;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
sketch.setSize(sketchWidth, sketchHeight);
|
|
322
|
-
|
|
323
|
-
float[] reqSurfacePixelScale;
|
|
324
|
-
if (graphics.is2X() && PApplet.platform == PConstants.MACOSX) {
|
|
325
|
-
// Retina
|
|
326
|
-
reqSurfacePixelScale = new float[] { ScalableSurface.AUTOMAX_PIXELSCALE,
|
|
327
|
-
ScalableSurface.AUTOMAX_PIXELSCALE };
|
|
328
|
-
} else {
|
|
329
|
-
// Non-retina
|
|
330
|
-
reqSurfacePixelScale = new float[] { ScalableSurface.IDENTITY_PIXELSCALE,
|
|
331
|
-
ScalableSurface.IDENTITY_PIXELSCALE };
|
|
332
|
-
}
|
|
333
|
-
window.setSurfaceScale(reqSurfacePixelScale);
|
|
334
|
-
window.setSize(sketchWidth * windowScaleFactor, sketchHeight * windowScaleFactor);
|
|
335
|
-
window.setResizable(false);
|
|
336
|
-
setSize(sketchWidth, sketchHeight);
|
|
337
|
-
if (fullScreen) {
|
|
338
|
-
PApplet.hideMenuBar();
|
|
339
|
-
if (spanDisplays) {
|
|
340
|
-
window.setFullscreen(screen.getMonitorDevices());
|
|
341
|
-
} else {
|
|
342
|
-
window.setUndecorated(true);
|
|
343
|
-
window.setTopLevelPosition((int) displayRect.getX(), (int) displayRect.getY());
|
|
344
|
-
window.setTopLevelSize((int) displayRect.getWidth(), (int) displayRect.getHeight());
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
protected void initListeners() {
|
|
351
|
-
NEWTMouseListener mouseListener = new NEWTMouseListener();
|
|
352
|
-
window.addMouseListener(mouseListener);
|
|
353
|
-
NEWTKeyListener keyListener = new NEWTKeyListener();
|
|
354
|
-
window.addKeyListener(keyListener);
|
|
355
|
-
NEWTWindowListener winListener = new NEWTWindowListener();
|
|
356
|
-
window.addWindowListener(winListener);
|
|
357
|
-
|
|
358
|
-
DrawListener drawlistener = new DrawListener();
|
|
359
|
-
window.addGLEventListener(drawlistener);
|
|
360
|
-
}
|
|
361
|
-
|
|
305
|
+
*/
|
|
362
306
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
// See section "Clocks and Timers on Windows":
|
|
368
|
-
// https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks
|
|
369
|
-
Thread highResTimerThread = new Thread(() -> {
|
|
370
|
-
try {
|
|
371
|
-
Thread.sleep(Long.MAX_VALUE);
|
|
372
|
-
} catch (InterruptedException ignore) { }
|
|
373
|
-
}, "HighResTimerThread");
|
|
374
|
-
highResTimerThread.setDaemon(true);
|
|
375
|
-
highResTimerThread.start();
|
|
376
|
-
}
|
|
307
|
+
if (fullScreen || spanDisplays) {
|
|
308
|
+
sketchWidth = screenRect.width / windowScaleFactor;
|
|
309
|
+
sketchHeight = screenRect.height / windowScaleFactor;
|
|
310
|
+
}
|
|
377
311
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
312
|
+
sketch.setSize(sketchWidth, sketchHeight);
|
|
313
|
+
|
|
314
|
+
float[] reqSurfacePixelScale;
|
|
315
|
+
if (graphics.is2X() && PApplet.platform == PConstants.MACOSX) {
|
|
316
|
+
// Retina
|
|
317
|
+
reqSurfacePixelScale = new float[]{ScalableSurface.AUTOMAX_PIXELSCALE,
|
|
318
|
+
ScalableSurface.AUTOMAX_PIXELSCALE};
|
|
319
|
+
} else {
|
|
320
|
+
// Non-retina
|
|
321
|
+
reqSurfacePixelScale = new float[]{ScalableSurface.IDENTITY_PIXELSCALE,
|
|
322
|
+
ScalableSurface.IDENTITY_PIXELSCALE};
|
|
388
323
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
324
|
+
window.setSurfaceScale(reqSurfacePixelScale);
|
|
325
|
+
window.setSize(sketchWidth * windowScaleFactor, sketchHeight * windowScaleFactor);
|
|
326
|
+
window.setResizable(false);
|
|
327
|
+
setSize(sketchWidth, sketchHeight);
|
|
328
|
+
if (fullScreen) {
|
|
329
|
+
PApplet.hideMenuBar();
|
|
330
|
+
if (spanDisplays) {
|
|
331
|
+
window.setFullscreen(screen.getMonitorDevices());
|
|
332
|
+
} else {
|
|
333
|
+
window.setUndecorated(true);
|
|
334
|
+
window.setTopLevelPosition((int) displayRect.getX(), (int) displayRect.getY());
|
|
335
|
+
window.setTopLevelSize((int) displayRect.getWidth(), (int) displayRect.getHeight());
|
|
398
336
|
}
|
|
399
|
-
// System.err.println("Caught exception: " + drawException.getMessage());
|
|
400
|
-
if (drawException != null) {
|
|
401
|
-
Throwable cause = drawException.getCause();
|
|
402
|
-
if (cause instanceof ThreadDeath) {
|
|
403
|
-
// System.out.println("caught ThreadDeath");
|
|
404
|
-
// throw (ThreadDeath)cause;
|
|
405
|
-
} else if (cause instanceof RuntimeException) {
|
|
406
|
-
throw (RuntimeException) cause;
|
|
407
|
-
} else if (cause instanceof UnsatisfiedLinkError) {
|
|
408
|
-
throw new UnsatisfiedLinkError(cause.getMessage());
|
|
409
|
-
} else if (cause == null) {
|
|
410
|
-
throw new RuntimeException(drawException.getMessage());
|
|
411
|
-
} else {
|
|
412
|
-
throw new RuntimeException(cause);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
} catch (InterruptedException e) {
|
|
416
|
-
return;
|
|
417
|
-
}
|
|
418
337
|
}
|
|
419
|
-
|
|
420
|
-
});
|
|
421
|
-
drawExceptionHandler.start();
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
@Override
|
|
426
|
-
public void setTitle(final String title) {
|
|
427
|
-
display.getEDTUtil().invoke(false, new Runnable() {
|
|
428
|
-
@Override
|
|
429
|
-
public void run() {
|
|
430
|
-
window.setTitle(title);
|
|
431
|
-
}
|
|
432
|
-
});
|
|
433
|
-
}
|
|
338
|
+
}
|
|
434
339
|
|
|
340
|
+
protected void initListeners() {
|
|
341
|
+
NEWTMouseListener mouseListener = new NEWTMouseListener();
|
|
342
|
+
window.addMouseListener(mouseListener);
|
|
343
|
+
NEWTKeyListener keyListener = new NEWTKeyListener();
|
|
344
|
+
window.addKeyListener(keyListener);
|
|
345
|
+
NEWTWindowListener winListener = new NEWTWindowListener();
|
|
346
|
+
window.addWindowListener(winListener);
|
|
347
|
+
|
|
348
|
+
DrawListener drawlistener = new DrawListener();
|
|
349
|
+
window.addGLEventListener(drawlistener);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
protected void initAnimator() {
|
|
353
|
+
if (PApplet.platform == PConstants.WINDOWS) {
|
|
354
|
+
// Force Windows to keep timer resolution high by
|
|
355
|
+
// sleeping for time which is not a multiple of 10 ms.
|
|
356
|
+
// See section "Clocks and Timers on Windows":
|
|
357
|
+
// https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks
|
|
358
|
+
Thread highResTimerThread = new Thread(() -> {
|
|
359
|
+
try {
|
|
360
|
+
Thread.sleep(Long.MAX_VALUE);
|
|
361
|
+
} catch (InterruptedException ignore) {
|
|
362
|
+
}
|
|
363
|
+
}, "HighResTimerThread");
|
|
364
|
+
highResTimerThread.setDaemon(true);
|
|
365
|
+
highResTimerThread.start();
|
|
366
|
+
}
|
|
435
367
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
368
|
+
animator = new FPSAnimator(window, 60);
|
|
369
|
+
drawException = null;
|
|
370
|
+
animator.setUncaughtExceptionHandler(new GLAnimatorControl.UncaughtExceptionHandler() {
|
|
371
|
+
@Override
|
|
372
|
+
public void uncaughtException(final GLAnimatorControl animator,
|
|
373
|
+
final GLAutoDrawable drawable,
|
|
374
|
+
final Throwable cause) {
|
|
375
|
+
synchronized (drawExceptionMutex) {
|
|
376
|
+
drawException = cause;
|
|
377
|
+
drawExceptionMutex.notify();
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
drawExceptionHandler = new Thread(new Runnable() {
|
|
383
|
+
public void run() {
|
|
384
|
+
synchronized (drawExceptionMutex) {
|
|
385
|
+
try {
|
|
386
|
+
while (drawException == null) {
|
|
387
|
+
drawExceptionMutex.wait();
|
|
388
|
+
}
|
|
389
|
+
// System.err.println("Caught exception: " + drawException.getMessage());
|
|
390
|
+
if (drawException != null) {
|
|
391
|
+
Throwable cause = drawException.getCause();
|
|
392
|
+
if (cause instanceof ThreadDeath) {
|
|
393
|
+
// System.out.println("caught ThreadDeath");
|
|
394
|
+
// throw (ThreadDeath)cause;
|
|
395
|
+
} else if (cause instanceof RuntimeException) {
|
|
396
|
+
throw (RuntimeException) cause;
|
|
397
|
+
} else if (cause instanceof UnsatisfiedLinkError) {
|
|
398
|
+
throw new UnsatisfiedLinkError(cause.getMessage());
|
|
399
|
+
} else if (cause == null) {
|
|
400
|
+
throw new RuntimeException(drawException.getMessage());
|
|
401
|
+
} else {
|
|
402
|
+
throw new RuntimeException(cause);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
} catch (InterruptedException e) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
drawExceptionHandler.start();
|
|
412
|
+
}
|
|
445
413
|
|
|
414
|
+
@Override
|
|
415
|
+
public void setTitle(final String title) {
|
|
416
|
+
display.getEDTUtil().invoke(false, new Runnable() {
|
|
417
|
+
@Override
|
|
418
|
+
public void run() {
|
|
419
|
+
window.setTitle(title);
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
}
|
|
446
423
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
424
|
+
@Override
|
|
425
|
+
public void setVisible(final boolean visible) {
|
|
426
|
+
display.getEDTUtil().invoke(false, new Runnable() {
|
|
427
|
+
@Override
|
|
428
|
+
public void run() {
|
|
429
|
+
window.setVisible(visible);
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
}
|
|
456
433
|
|
|
434
|
+
@Override
|
|
435
|
+
public void setResizable(final boolean resizable) {
|
|
436
|
+
display.getEDTUtil().invoke(false, new Runnable() {
|
|
437
|
+
@Override
|
|
438
|
+
public void run() {
|
|
439
|
+
window.setResizable(resizable);
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
}
|
|
457
443
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
444
|
+
public void setIcon(PImage icon) {
|
|
445
|
+
PGraphics.showWarning("Window icons for OpenGL sketches can only be set in settings()\n"
|
|
446
|
+
+ "using PJOGL.setIcon(filename).");
|
|
447
|
+
}
|
|
462
448
|
|
|
449
|
+
@Override
|
|
450
|
+
public void setAlwaysOnTop(final boolean always) {
|
|
451
|
+
display.getEDTUtil().invoke(false, new Runnable() {
|
|
452
|
+
@Override
|
|
453
|
+
public void run() {
|
|
454
|
+
window.setAlwaysOnTop(always);
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
}
|
|
463
458
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
iconImages[i] = "/icon/icon-" + sizes[i] + ".png";
|
|
483
|
-
}
|
|
484
|
-
res = new ClassResources(iconImages,
|
|
485
|
-
PApplet.class.getClassLoader(),
|
|
486
|
-
PApplet.class);
|
|
487
|
-
} else {
|
|
488
|
-
// Loading custom icons from user-provided files.
|
|
489
|
-
String[] iconImages = new String[PJOGL.icons.length];
|
|
490
|
-
for (int i = 0; i < PJOGL.icons.length; i++) {
|
|
491
|
-
iconImages[i] = resourceFilename(PJOGL.icons[i]);
|
|
492
|
-
}
|
|
459
|
+
protected void initIcons() {
|
|
460
|
+
IOUtil.ClassResources res = null;
|
|
461
|
+
if (PJOGL.icons == null || PJOGL.icons.length == 0) {
|
|
462
|
+
// Default Processing icons
|
|
463
|
+
final int[] sizes = {16, 32, 48, 64, 128, 256, 512};
|
|
464
|
+
String[] iconImages = new String[sizes.length];
|
|
465
|
+
for (int i = 0; i < sizes.length; i++) {
|
|
466
|
+
iconImages[i] = "/icon/icon-" + sizes[i] + ".png";
|
|
467
|
+
}
|
|
468
|
+
res = new ClassResources(iconImages,
|
|
469
|
+
PApplet.class.getClassLoader(),
|
|
470
|
+
PApplet.class);
|
|
471
|
+
} else {
|
|
472
|
+
// Loading custom icons from user-provided files.
|
|
473
|
+
String[] iconImages = new String[PJOGL.icons.length];
|
|
474
|
+
for (int i = 0; i < PJOGL.icons.length; i++) {
|
|
475
|
+
iconImages[i] = resourceFilename(PJOGL.icons[i]);
|
|
476
|
+
}
|
|
493
477
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
478
|
+
res = new ClassResources(iconImages,
|
|
479
|
+
sketch.getClass().getClassLoader(),
|
|
480
|
+
sketch.getClass());
|
|
481
|
+
}
|
|
482
|
+
NewtFactory.setWindowIcons(res);
|
|
497
483
|
}
|
|
498
|
-
NewtFactory.setWindowIcons(res);
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
@SuppressWarnings("resource")
|
|
503
|
-
private String resourceFilename(String filename) {
|
|
504
|
-
// The code below comes from PApplet.createInputRaw() with a few adaptations
|
|
505
|
-
InputStream stream = null;
|
|
506
|
-
try {
|
|
507
|
-
// First see if it's in a data folder. This may fail by throwing
|
|
508
|
-
// a SecurityException. If so, this whole block will be skipped.
|
|
509
|
-
File file = new File(sketch.dataPath(filename));
|
|
510
|
-
if (!file.exists()) {
|
|
511
|
-
// next see if it's just in the sketch folder
|
|
512
|
-
file = sketch.sketchFile(filename);
|
|
513
|
-
}
|
|
514
484
|
|
|
515
|
-
|
|
485
|
+
@SuppressWarnings("resource")
|
|
486
|
+
private String resourceFilename(String filename) {
|
|
487
|
+
// The code below comes from PApplet.createInputRaw() with a few adaptations
|
|
488
|
+
InputStream stream = null;
|
|
516
489
|
try {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
//if (filenameActual.equalsIgnoreCase(filenameShort) &&
|
|
525
|
-
//!filenameActual.equals(filenameShort)) {
|
|
526
|
-
if (!filenameActual.equals(filenameShort)) {
|
|
527
|
-
throw new RuntimeException("This file is named " +
|
|
528
|
-
filenameActual + " not " +
|
|
529
|
-
filename + ". Rename the file " +
|
|
530
|
-
"or change your code.");
|
|
531
|
-
}
|
|
532
|
-
} catch (IOException e) { }
|
|
533
|
-
}
|
|
490
|
+
// First see if it's in a data folder. This may fail by throwing
|
|
491
|
+
// a SecurityException. If so, this whole block will be skipped.
|
|
492
|
+
File file = new File(sketch.dataPath(filename));
|
|
493
|
+
if (!file.exists()) {
|
|
494
|
+
// next see if it's just in the sketch folder
|
|
495
|
+
file = sketch.sketchFile(filename);
|
|
496
|
+
}
|
|
534
497
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
498
|
+
if (file.exists() && !file.isDirectory()) {
|
|
499
|
+
try {
|
|
500
|
+
// handle case sensitivity check
|
|
501
|
+
String filePath = file.getCanonicalPath();
|
|
502
|
+
String filenameActual = new File(filePath).getName();
|
|
503
|
+
// make sure there isn't a subfolder prepended to the name
|
|
504
|
+
String filenameShort = new File(filename).getName();
|
|
505
|
+
// if the actual filename is the same, but capitalized
|
|
506
|
+
// differently, warn the user.
|
|
507
|
+
//if (filenameActual.equalsIgnoreCase(filenameShort) &&
|
|
508
|
+
//!filenameActual.equals(filenameShort)) {
|
|
509
|
+
if (!filenameActual.equals(filenameShort)) {
|
|
510
|
+
throw new RuntimeException("This file is named "
|
|
511
|
+
+ filenameActual + " not "
|
|
512
|
+
+ filename + ". Rename the file "
|
|
513
|
+
+ "or change your code.");
|
|
514
|
+
}
|
|
515
|
+
} catch (IOException e) {
|
|
516
|
+
}
|
|
517
|
+
}
|
|
540
518
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
ClassLoader cl = sketch.getClass().getClassLoader();
|
|
547
|
-
|
|
548
|
-
try {
|
|
549
|
-
// by default, data files are exported to the root path of the jar.
|
|
550
|
-
// (not the data folder) so check there first.
|
|
551
|
-
stream = cl.getResourceAsStream("data/" + filename);
|
|
552
|
-
if (stream != null) {
|
|
553
|
-
String cn = stream.getClass().getName();
|
|
554
|
-
// this is an irritation of sun's java plug-in, which will return
|
|
555
|
-
// a non-null stream for an object that doesn't exist. like all good
|
|
556
|
-
// things, this is probably introduced in java 1.5. awesome!
|
|
557
|
-
// http://dev.processing.org/bugs/show_bug.cgi?id=359
|
|
558
|
-
if (!cn.equals("sun.plugin.cache.EmptyInputStream")) {
|
|
559
|
-
stream.close();
|
|
560
|
-
return "data/" + filename;
|
|
561
|
-
}
|
|
562
|
-
}
|
|
519
|
+
stream = new FileInputStream(file);
|
|
520
|
+
if (stream != null) {
|
|
521
|
+
stream.close();
|
|
522
|
+
return file.getCanonicalPath();
|
|
523
|
+
}
|
|
563
524
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
if (stream != null) {
|
|
569
|
-
String cn = stream.getClass().getName();
|
|
570
|
-
if (!cn.equals("sun.plugin.cache.EmptyInputStream")) {
|
|
571
|
-
stream.close();
|
|
572
|
-
return filename;
|
|
525
|
+
// have to break these out because a general Exception might
|
|
526
|
+
// catch the RuntimeException being thrown above
|
|
527
|
+
} catch (IOException ioe) {
|
|
528
|
+
} catch (SecurityException se) {
|
|
573
529
|
}
|
|
574
|
-
}
|
|
575
|
-
} catch (IOException e) { }
|
|
576
530
|
|
|
577
|
-
|
|
578
|
-
// attempt to load from a local file, used when running as
|
|
579
|
-
// an application, or as a signed applet
|
|
580
|
-
try { // first try to catch any security exceptions
|
|
581
|
-
try {
|
|
582
|
-
String path = sketch.dataPath(filename);
|
|
583
|
-
stream = new FileInputStream(path);
|
|
584
|
-
if (stream != null) {
|
|
585
|
-
stream.close();
|
|
586
|
-
return path;
|
|
587
|
-
}
|
|
588
|
-
} catch (IOException e2) { }
|
|
531
|
+
ClassLoader cl = sketch.getClass().getClassLoader();
|
|
589
532
|
|
|
590
533
|
try {
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
stream
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
534
|
+
// by default, data files are exported to the root path of the jar.
|
|
535
|
+
// (not the data folder) so check there first.
|
|
536
|
+
stream = cl.getResourceAsStream("data/" + filename);
|
|
537
|
+
if (stream != null) {
|
|
538
|
+
String cn = stream.getClass().getName();
|
|
539
|
+
// this is an irritation of sun's java plug-in, which will return
|
|
540
|
+
// a non-null stream for an object that doesn't exist. like all good
|
|
541
|
+
// things, this is probably introduced in java 1.5. awesome!
|
|
542
|
+
// http://dev.processing.org/bugs/show_bug.cgi?id=359
|
|
543
|
+
if (!cn.equals("sun.plugin.cache.EmptyInputStream")) {
|
|
544
|
+
stream.close();
|
|
545
|
+
return "data/" + filename;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
598
548
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
stream.
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
}
|
|
549
|
+
// When used with an online script, also need to check without the
|
|
550
|
+
// data folder, in case it's not in a subfolder called 'data'.
|
|
551
|
+
// http://dev.processing.org/bugs/show_bug.cgi?id=389
|
|
552
|
+
stream = cl.getResourceAsStream(filename);
|
|
553
|
+
if (stream != null) {
|
|
554
|
+
String cn = stream.getClass().getName();
|
|
555
|
+
if (!cn.equals("sun.plugin.cache.EmptyInputStream")) {
|
|
556
|
+
stream.close();
|
|
557
|
+
return filename;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
} catch (IOException e) {
|
|
561
|
+
}
|
|
613
562
|
|
|
614
|
-
|
|
615
|
-
|
|
563
|
+
try {
|
|
564
|
+
// attempt to load from a local file, used when running as
|
|
565
|
+
// an application, or as a signed applet
|
|
566
|
+
try { // first try to catch any security exceptions
|
|
567
|
+
try {
|
|
568
|
+
String path = sketch.dataPath(filename);
|
|
569
|
+
stream = new FileInputStream(path);
|
|
570
|
+
if (stream != null) {
|
|
571
|
+
stream.close();
|
|
572
|
+
return path;
|
|
573
|
+
}
|
|
574
|
+
} catch (IOException e2) {
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
try {
|
|
578
|
+
String path = sketch.sketchPath(filename);
|
|
579
|
+
stream = new FileInputStream(path);
|
|
580
|
+
if (stream != null) {
|
|
581
|
+
stream.close();
|
|
582
|
+
return path;
|
|
583
|
+
}
|
|
584
|
+
} catch (Exception e) {
|
|
585
|
+
} // ignored
|
|
586
|
+
|
|
587
|
+
try {
|
|
588
|
+
stream = new FileInputStream(filename);
|
|
589
|
+
if (stream != null) {
|
|
590
|
+
stream.close();
|
|
591
|
+
return filename;
|
|
592
|
+
}
|
|
593
|
+
} catch (IOException e1) {
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
} catch (SecurityException se) {
|
|
597
|
+
} // online, whups
|
|
598
|
+
|
|
599
|
+
} catch (Exception e) {
|
|
600
|
+
//die(e.getMessage(), e);
|
|
601
|
+
e.printStackTrace();
|
|
602
|
+
}
|
|
616
603
|
|
|
604
|
+
return "";
|
|
605
|
+
}
|
|
617
606
|
|
|
618
|
-
|
|
619
|
-
|
|
607
|
+
@Override
|
|
608
|
+
public void placeWindow(int[] location, int[] editorLocation) {
|
|
620
609
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
610
|
+
if (sketch.sketchFullScreen()) {
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
624
613
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
614
|
+
int x = window.getX() - window.getInsets().getLeftWidth();
|
|
615
|
+
int y = window.getY() - window.getInsets().getTopHeight();
|
|
616
|
+
int w = window.getWidth() + window.getInsets().getTotalWidth();
|
|
617
|
+
int h = window.getHeight() + window.getInsets().getTotalHeight();
|
|
629
618
|
|
|
630
|
-
|
|
619
|
+
if (location != null) {
|
|
631
620
|
// System.err.println("place window at " + location[0] + ", " + location[1]);
|
|
632
|
-
|
|
621
|
+
window.setTopLevelPosition(location[0], location[1]);
|
|
633
622
|
|
|
634
|
-
|
|
623
|
+
} else if (editorLocation != null) {
|
|
635
624
|
// System.err.println("place window at editor location " + editorLocation[0] + ", " + editorLocation[1]);
|
|
636
|
-
|
|
637
|
-
|
|
625
|
+
int locationX = editorLocation[0] - 20;
|
|
626
|
+
int locationY = editorLocation[1];
|
|
638
627
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
628
|
+
if (locationX - w > 10) {
|
|
629
|
+
// if it fits to the left of the window
|
|
630
|
+
window.setTopLevelPosition(locationX - w, locationY);
|
|
642
631
|
|
|
643
|
-
|
|
644
|
-
|
|
632
|
+
} else { // doesn't fit
|
|
633
|
+
/*
|
|
645
634
|
// if it fits inside the editor window,
|
|
646
635
|
// offset slightly from upper lefthand corner
|
|
647
636
|
// so that it's plunked inside the text area
|
|
@@ -651,665 +640,659 @@ public class PSurfaceJOGL implements PSurface {
|
|
|
651
640
|
if ((locationX + w > sketch.displayWidth - 33) ||
|
|
652
641
|
(locationY + h > sketch.displayHeight - 33)) {
|
|
653
642
|
// otherwise center on screen
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
643
|
+
*/
|
|
644
|
+
locationX = (sketch.displayWidth - w) / 2;
|
|
645
|
+
locationY = (sketch.displayHeight - h) / 2;
|
|
646
|
+
/*
|
|
647
|
+
}
|
|
648
|
+
*/
|
|
649
|
+
window.setTopLevelPosition(locationX, locationY);
|
|
650
|
+
}
|
|
651
|
+
} else { // just center on screen
|
|
652
|
+
// Can't use frame.setLocationRelativeTo(null) because it sends the
|
|
653
|
+
// frame to the main display, which undermines the --display setting.
|
|
654
|
+
window.setTopLevelPosition(screenRect.x + (screenRect.width - sketchWidth) / 2,
|
|
655
|
+
screenRect.y + (screenRect.height - sketchHeight) / 2);
|
|
658
656
|
}
|
|
659
|
-
*/
|
|
660
|
-
window.setTopLevelPosition(locationX, locationY);
|
|
661
|
-
}
|
|
662
|
-
} else { // just center on screen
|
|
663
|
-
// Can't use frame.setLocationRelativeTo(null) because it sends the
|
|
664
|
-
// frame to the main display, which undermines the --display setting.
|
|
665
|
-
window.setTopLevelPosition(screenRect.x + (screenRect.width - sketchWidth) / 2,
|
|
666
|
-
screenRect.y + (screenRect.height - sketchHeight) / 2);
|
|
667
|
-
}
|
|
668
657
|
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
658
|
+
Point frameLoc = new Point(x, y);
|
|
659
|
+
if (frameLoc.y < 0) {
|
|
660
|
+
// Windows actually allows you to place frames where they can't be
|
|
661
|
+
// closed. Awesome. http://dev.processing.org/bugs/show_bug.cgi?id=1508
|
|
662
|
+
window.setTopLevelPosition(frameLoc.x, 30);
|
|
663
|
+
}
|
|
674
664
|
}
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
public void placePresent(int stopColor) {
|
|
679
|
-
float scale = getPixelScale();
|
|
680
|
-
pgl.initPresentMode(0.5f * (screenRect.width/scale - sketchWidth),
|
|
681
|
-
0.5f * (screenRect.height/scale - sketchHeight), stopColor);
|
|
682
|
-
PApplet.hideMenuBar();
|
|
683
665
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
666
|
+
public void placePresent(int stopColor) {
|
|
667
|
+
float scale = getPixelScale();
|
|
668
|
+
pgl.initPresentMode(0.5f * (screenRect.width / scale - sketchWidth),
|
|
669
|
+
0.5f * (screenRect.height / scale - sketchHeight), stopColor);
|
|
670
|
+
PApplet.hideMenuBar();
|
|
688
671
|
|
|
672
|
+
window.setUndecorated(true);
|
|
673
|
+
window.setTopLevelPosition((int) displayRect.getX(), (int) displayRect.getY());
|
|
674
|
+
window.setTopLevelSize((int) displayRect.getWidth(), (int) displayRect.getHeight());
|
|
675
|
+
}
|
|
689
676
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
677
|
+
public void setupExternalMessages() {
|
|
678
|
+
external = true;
|
|
679
|
+
}
|
|
693
680
|
|
|
681
|
+
public void startThread() {
|
|
682
|
+
if (animator != null) {
|
|
683
|
+
animator.start();
|
|
684
|
+
}
|
|
685
|
+
}
|
|
694
686
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
687
|
+
public void pauseThread() {
|
|
688
|
+
if (animator != null) {
|
|
689
|
+
animator.pause();
|
|
690
|
+
}
|
|
698
691
|
}
|
|
699
|
-
}
|
|
700
692
|
|
|
693
|
+
public void resumeThread() {
|
|
694
|
+
if (animator != null) {
|
|
695
|
+
animator.resume();
|
|
696
|
+
}
|
|
697
|
+
}
|
|
701
698
|
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
699
|
+
public boolean stopThread() {
|
|
700
|
+
if (drawExceptionHandler != null) {
|
|
701
|
+
drawExceptionHandler.interrupt();
|
|
702
|
+
drawExceptionHandler = null;
|
|
703
|
+
}
|
|
704
|
+
if (animator != null) {
|
|
705
|
+
return animator.stop();
|
|
706
|
+
} else {
|
|
707
|
+
return false;
|
|
708
|
+
}
|
|
705
709
|
}
|
|
706
|
-
}
|
|
707
710
|
|
|
711
|
+
public boolean isStopped() {
|
|
712
|
+
if (animator != null) {
|
|
713
|
+
return !animator.isAnimating();
|
|
714
|
+
} else {
|
|
715
|
+
return true;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
708
718
|
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
719
|
+
public void setLocation(final int x, final int y) {
|
|
720
|
+
display.getEDTUtil().invoke(false, new Runnable() {
|
|
721
|
+
@Override
|
|
722
|
+
public void run() {
|
|
723
|
+
window.setTopLevelPosition(x, y);
|
|
724
|
+
}
|
|
725
|
+
});
|
|
712
726
|
}
|
|
713
|
-
}
|
|
714
727
|
|
|
728
|
+
public void setSize(int wide, int high) {
|
|
729
|
+
if (pgl.presentMode()) {
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
715
732
|
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
}
|
|
726
|
-
}
|
|
733
|
+
// When the surface is set to resizable via surface.setResizable(true),
|
|
734
|
+
// a crash may occur if the user sets the window to size zero.
|
|
735
|
+
// https://github.com/processing/processing/issues/5052
|
|
736
|
+
if (high <= 0) {
|
|
737
|
+
high = 1;
|
|
738
|
+
}
|
|
739
|
+
if (wide <= 0) {
|
|
740
|
+
wide = 1;
|
|
741
|
+
}
|
|
727
742
|
|
|
743
|
+
boolean changed = sketch.width != wide || sketch.height != high;
|
|
728
744
|
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
return !animator.isAnimating();
|
|
732
|
-
} else {
|
|
733
|
-
return true;
|
|
734
|
-
}
|
|
735
|
-
}
|
|
745
|
+
sketchWidth = wide;
|
|
746
|
+
sketchHeight = high;
|
|
736
747
|
|
|
748
|
+
sketch.setSize(wide, high);
|
|
749
|
+
graphics.setSize(wide, high);
|
|
737
750
|
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
window.setTopLevelPosition(x, y);
|
|
743
|
-
}
|
|
744
|
-
});
|
|
745
|
-
}
|
|
751
|
+
if (changed) {
|
|
752
|
+
window.setSize(wide * windowScaleFactor, high * windowScaleFactor);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
746
755
|
|
|
756
|
+
public float getPixelScale() {
|
|
757
|
+
if (graphics.pixelDensity == 1) {
|
|
758
|
+
return 1;
|
|
759
|
+
}
|
|
747
760
|
|
|
748
|
-
|
|
749
|
-
|
|
761
|
+
if (PApplet.platform == PConstants.MACOSX) {
|
|
762
|
+
return getCurrentPixelScale();
|
|
763
|
+
}
|
|
750
764
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
765
|
+
return 2;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
private float getCurrentPixelScale() {
|
|
769
|
+
// Even if the graphics are retina, the user might have moved the window
|
|
770
|
+
// into a non-retina monitor, so we need to check
|
|
771
|
+
window.getCurrentSurfaceScale(currentPixelScale);
|
|
772
|
+
return currentPixelScale[0];
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
public Component getComponent() {
|
|
776
|
+
return canvas;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
public void setSmooth(int level) {
|
|
780
|
+
pgl.reqNumSamples = level;
|
|
781
|
+
GLCapabilities caps = new GLCapabilities(profile);
|
|
782
|
+
caps.setAlphaBits(PGL.REQUESTED_ALPHA_BITS);
|
|
783
|
+
caps.setDepthBits(PGL.REQUESTED_DEPTH_BITS);
|
|
784
|
+
caps.setStencilBits(PGL.REQUESTED_STENCIL_BITS);
|
|
785
|
+
caps.setSampleBuffers(true);
|
|
786
|
+
caps.setNumSamples(pgl.reqNumSamples);
|
|
787
|
+
caps.setBackgroundOpaque(true);
|
|
788
|
+
caps.setOnscreen(true);
|
|
789
|
+
NativeSurface target = window.getNativeSurface();
|
|
790
|
+
MutableGraphicsConfiguration config = (MutableGraphicsConfiguration) target.getGraphicsConfiguration();
|
|
791
|
+
config.setChosenCapabilities(caps);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
public void setFrameRate(float fps) {
|
|
795
|
+
if (fps < 1) {
|
|
796
|
+
PGraphics.showWarning(
|
|
797
|
+
"The OpenGL renderer cannot have a frame rate lower than 1.\n"
|
|
798
|
+
+ "Your sketch will run at 1 frame per second.");
|
|
799
|
+
fps = 1;
|
|
800
|
+
} else if (fps > 1000) {
|
|
801
|
+
PGraphics.showWarning(
|
|
802
|
+
"The OpenGL renderer cannot have a frame rate higher than 1000.\n"
|
|
803
|
+
+ "Your sketch will run at 1000 frames per second.");
|
|
804
|
+
fps = 1000;
|
|
805
|
+
}
|
|
806
|
+
if (animator != null) {
|
|
807
|
+
animator.stop();
|
|
808
|
+
animator.setFPS((int) fps);
|
|
809
|
+
pgl.setFps(fps);
|
|
810
|
+
animator.start();
|
|
811
|
+
}
|
|
756
812
|
}
|
|
757
|
-
|
|
758
|
-
|
|
813
|
+
|
|
814
|
+
public void requestFocus() {
|
|
815
|
+
display.getEDTUtil().invoke(false, new Runnable() {
|
|
816
|
+
@Override
|
|
817
|
+
public void run() {
|
|
818
|
+
window.requestFocus();
|
|
819
|
+
}
|
|
820
|
+
});
|
|
759
821
|
}
|
|
760
822
|
|
|
761
|
-
|
|
823
|
+
class DrawListener implements GLEventListener {
|
|
762
824
|
|
|
763
|
-
|
|
764
|
-
|
|
825
|
+
public void display(GLAutoDrawable drawable) {
|
|
826
|
+
if (display.getEDTUtil().isCurrentThreadEDT()) {
|
|
827
|
+
// For some reason, the first two frames of the animator are run on the
|
|
828
|
+
// EDT, skipping rendering Processing's frame in that case.
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
765
831
|
|
|
766
|
-
|
|
767
|
-
|
|
832
|
+
if (sketch.frameCount == 0) {
|
|
833
|
+
if (sketchWidth < sketchWidth0 || sketchHeight < sketchHeight0) {
|
|
834
|
+
PGraphics.showWarning("The sketch has been automatically resized to fit the screen resolution");
|
|
835
|
+
}
|
|
836
|
+
// System.out.println("display: " + window.getWidth() + " "+ window.getHeight() + " - " + sketchWidth + " " + sketchHeight);
|
|
837
|
+
requestFocus();
|
|
838
|
+
}
|
|
768
839
|
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
840
|
+
if (!sketch.finished) {
|
|
841
|
+
pgl.getGL(drawable);
|
|
842
|
+
int pframeCount = sketch.frameCount;
|
|
843
|
+
sketch.handleDraw();
|
|
844
|
+
if (pframeCount == sketch.frameCount || sketch.finished) {
|
|
845
|
+
// This hack allows the FBO layer to be swapped normally even if
|
|
846
|
+
// the sketch is no looping or finished because it does not call draw(),
|
|
847
|
+
// otherwise background artifacts may occur (depending on the hardware/drivers).
|
|
848
|
+
pgl.beginRender();
|
|
849
|
+
pgl.endRender(sketch.sketchWindowColor());
|
|
850
|
+
}
|
|
851
|
+
PGraphicsOpenGL.completeFinishedPixelTransfers();
|
|
852
|
+
}
|
|
773
853
|
|
|
854
|
+
if (sketch.exitCalled()) {
|
|
855
|
+
PGraphicsOpenGL.completeAllPixelTransfers();
|
|
774
856
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
857
|
+
sketch.dispose(); // calls stopThread(), which stops the animator.
|
|
858
|
+
sketch.exitActual();
|
|
859
|
+
}
|
|
860
|
+
}
|
|
779
861
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
862
|
+
public void dispose(GLAutoDrawable drawable) {
|
|
863
|
+
// sketch.dispose();
|
|
864
|
+
}
|
|
783
865
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
caps.setDepthBits(PGL.REQUESTED_DEPTH_BITS);
|
|
805
|
-
caps.setStencilBits(PGL.REQUESTED_STENCIL_BITS);
|
|
806
|
-
caps.setSampleBuffers(true);
|
|
807
|
-
caps.setNumSamples(pgl.reqNumSamples);
|
|
808
|
-
caps.setBackgroundOpaque(true);
|
|
809
|
-
caps.setOnscreen(true);
|
|
810
|
-
NativeSurface target = window.getNativeSurface();
|
|
811
|
-
MutableGraphicsConfiguration config = (MutableGraphicsConfiguration) target.getGraphicsConfiguration();
|
|
812
|
-
config.setChosenCapabilities(caps);
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
public void setFrameRate(float fps) {
|
|
817
|
-
if (fps < 1) {
|
|
818
|
-
PGraphics.showWarning(
|
|
819
|
-
"The OpenGL renderer cannot have a frame rate lower than 1.\n" +
|
|
820
|
-
"Your sketch will run at 1 frame per second.");
|
|
821
|
-
fps = 1;
|
|
822
|
-
} else if (fps > 1000) {
|
|
823
|
-
PGraphics.showWarning(
|
|
824
|
-
"The OpenGL renderer cannot have a frame rate higher than 1000.\n" +
|
|
825
|
-
"Your sketch will run at 1000 frames per second.");
|
|
826
|
-
fps = 1000;
|
|
827
|
-
}
|
|
828
|
-
if (animator != null) {
|
|
829
|
-
animator.stop();
|
|
830
|
-
animator.setFPS((int)fps);
|
|
831
|
-
pgl.setFps(fps);
|
|
832
|
-
animator.start();
|
|
866
|
+
public void init(GLAutoDrawable drawable) {
|
|
867
|
+
pgl.getGL(drawable);
|
|
868
|
+
pgl.init(drawable);
|
|
869
|
+
sketch.start();
|
|
870
|
+
|
|
871
|
+
int c = graphics.backgroundColor;
|
|
872
|
+
pgl.clearColor(((c >> 16) & 0xff) / 255f,
|
|
873
|
+
((c >> 8) & 0xff) / 255f,
|
|
874
|
+
((c >> 0) & 0xff) / 255f,
|
|
875
|
+
((c >> 24) & 0xff) / 255f);
|
|
876
|
+
pgl.clear(PGL.COLOR_BUFFER_BIT);
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
|
|
880
|
+
pgl.resetFBOLayer();
|
|
881
|
+
pgl.getGL(drawable);
|
|
882
|
+
float scale = PApplet.platform == PConstants.MACOSX
|
|
883
|
+
? getCurrentPixelScale() : getPixelScale();
|
|
884
|
+
setSize((int) (w / scale), (int) (h / scale));
|
|
885
|
+
}
|
|
833
886
|
}
|
|
834
|
-
}
|
|
835
887
|
|
|
888
|
+
protected class NEWTWindowListener implements com.jogamp.newt.event.WindowListener {
|
|
836
889
|
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
public void run() {
|
|
841
|
-
window.requestFocus();
|
|
842
|
-
}
|
|
843
|
-
});
|
|
844
|
-
}
|
|
890
|
+
public NEWTWindowListener() {
|
|
891
|
+
super();
|
|
892
|
+
}
|
|
845
893
|
|
|
894
|
+
@Override
|
|
895
|
+
public void windowGainedFocus(com.jogamp.newt.event.WindowEvent arg0) {
|
|
896
|
+
sketch.focused = true;
|
|
897
|
+
sketch.focusGained();
|
|
898
|
+
}
|
|
846
899
|
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
return;
|
|
853
|
-
}
|
|
900
|
+
@Override
|
|
901
|
+
public void windowLostFocus(com.jogamp.newt.event.WindowEvent arg0) {
|
|
902
|
+
sketch.focused = false;
|
|
903
|
+
sketch.focusLost();
|
|
904
|
+
}
|
|
854
905
|
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
906
|
+
@Override
|
|
907
|
+
public void windowDestroyNotify(com.jogamp.newt.event.WindowEvent arg0) {
|
|
908
|
+
sketch.exit();
|
|
858
909
|
}
|
|
859
|
-
// System.out.println("display: " + window.getWidth() + " "+ window.getHeight() + " - " + sketchWidth + " " + sketchHeight);
|
|
860
|
-
requestFocus();
|
|
861
|
-
}
|
|
862
910
|
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
if (pframeCount == sketch.frameCount || sketch.finished) {
|
|
868
|
-
// This hack allows the FBO layer to be swapped normally even if
|
|
869
|
-
// the sketch is no looping or finished because it does not call draw(),
|
|
870
|
-
// otherwise background artifacts may occur (depending on the hardware/drivers).
|
|
871
|
-
pgl.beginRender();
|
|
872
|
-
pgl.endRender(sketch.sketchWindowColor());
|
|
873
|
-
}
|
|
874
|
-
PGraphicsOpenGL.completeFinishedPixelTransfers();
|
|
875
|
-
}
|
|
911
|
+
@Override
|
|
912
|
+
public void windowDestroyed(com.jogamp.newt.event.WindowEvent arg0) {
|
|
913
|
+
sketch.exit();
|
|
914
|
+
}
|
|
876
915
|
|
|
877
|
-
|
|
878
|
-
|
|
916
|
+
@Override
|
|
917
|
+
public void windowMoved(com.jogamp.newt.event.WindowEvent arg0) {
|
|
918
|
+
if (external) {
|
|
919
|
+
sketch.frameMoved(window.getX(), window.getY());
|
|
920
|
+
}
|
|
921
|
+
}
|
|
879
922
|
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
}
|
|
884
|
-
public void dispose(GLAutoDrawable drawable) {
|
|
885
|
-
// sketch.dispose();
|
|
886
|
-
}
|
|
887
|
-
public void init(GLAutoDrawable drawable) {
|
|
888
|
-
pgl.getGL(drawable);
|
|
889
|
-
pgl.init(drawable);
|
|
890
|
-
sketch.start();
|
|
891
|
-
|
|
892
|
-
int c = graphics.backgroundColor;
|
|
893
|
-
pgl.clearColor(((c >> 16) & 0xff) / 255f,
|
|
894
|
-
((c >> 8) & 0xff) / 255f,
|
|
895
|
-
((c >> 0) & 0xff) / 255f,
|
|
896
|
-
((c >> 24) & 0xff) / 255f);
|
|
897
|
-
pgl.clear(PGL.COLOR_BUFFER_BIT);
|
|
898
|
-
}
|
|
923
|
+
@Override
|
|
924
|
+
public void windowRepaint(com.jogamp.newt.event.WindowUpdateEvent arg0) {
|
|
925
|
+
}
|
|
899
926
|
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
float scale = PApplet.platform == PConstants.MACOSX ?
|
|
904
|
-
getCurrentPixelScale() : getPixelScale();
|
|
905
|
-
setSize((int) (w / scale), (int) (h / scale));
|
|
927
|
+
@Override
|
|
928
|
+
public void windowResized(com.jogamp.newt.event.WindowEvent arg0) {
|
|
929
|
+
}
|
|
906
930
|
}
|
|
907
|
-
}
|
|
908
931
|
|
|
932
|
+
// NEWT mouse listener
|
|
933
|
+
protected class NEWTMouseListener extends com.jogamp.newt.event.MouseAdapter {
|
|
909
934
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
}
|
|
914
|
-
@Override
|
|
915
|
-
public void windowGainedFocus(com.jogamp.newt.event.WindowEvent arg0) {
|
|
916
|
-
sketch.focused = true;
|
|
917
|
-
sketch.focusGained();
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
@Override
|
|
921
|
-
public void windowLostFocus(com.jogamp.newt.event.WindowEvent arg0) {
|
|
922
|
-
sketch.focused = false;
|
|
923
|
-
sketch.focusLost();
|
|
924
|
-
}
|
|
935
|
+
public NEWTMouseListener() {
|
|
936
|
+
super();
|
|
937
|
+
}
|
|
925
938
|
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
939
|
+
@Override
|
|
940
|
+
public void mousePressed(com.jogamp.newt.event.MouseEvent e) {
|
|
941
|
+
nativeMouseEvent(e, MouseEvent.PRESS);
|
|
942
|
+
}
|
|
930
943
|
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
944
|
+
@Override
|
|
945
|
+
public void mouseReleased(com.jogamp.newt.event.MouseEvent e) {
|
|
946
|
+
nativeMouseEvent(e, MouseEvent.RELEASE);
|
|
947
|
+
}
|
|
935
948
|
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
}
|
|
941
|
-
}
|
|
949
|
+
@Override
|
|
950
|
+
public void mouseClicked(com.jogamp.newt.event.MouseEvent e) {
|
|
951
|
+
nativeMouseEvent(e, MouseEvent.CLICK);
|
|
952
|
+
}
|
|
942
953
|
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
954
|
+
@Override
|
|
955
|
+
public void mouseDragged(com.jogamp.newt.event.MouseEvent e) {
|
|
956
|
+
nativeMouseEvent(e, MouseEvent.DRAG);
|
|
957
|
+
}
|
|
946
958
|
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
959
|
+
@Override
|
|
960
|
+
public void mouseMoved(com.jogamp.newt.event.MouseEvent e) {
|
|
961
|
+
nativeMouseEvent(e, MouseEvent.MOVE);
|
|
962
|
+
}
|
|
951
963
|
|
|
964
|
+
@Override
|
|
965
|
+
public void mouseWheelMoved(com.jogamp.newt.event.MouseEvent e) {
|
|
966
|
+
nativeMouseEvent(e, MouseEvent.WHEEL);
|
|
967
|
+
}
|
|
952
968
|
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
public NEWTMouseListener() {
|
|
956
|
-
super();
|
|
957
|
-
}
|
|
958
|
-
@Override
|
|
959
|
-
public void mousePressed(com.jogamp.newt.event.MouseEvent e) {
|
|
960
|
-
nativeMouseEvent(e, MouseEvent.PRESS);
|
|
961
|
-
}
|
|
962
|
-
@Override
|
|
963
|
-
public void mouseReleased(com.jogamp.newt.event.MouseEvent e) {
|
|
964
|
-
nativeMouseEvent(e, MouseEvent.RELEASE);
|
|
965
|
-
}
|
|
966
|
-
@Override
|
|
967
|
-
public void mouseClicked(com.jogamp.newt.event.MouseEvent e) {
|
|
968
|
-
nativeMouseEvent(e, MouseEvent.CLICK);
|
|
969
|
-
}
|
|
970
|
-
@Override
|
|
971
|
-
public void mouseDragged(com.jogamp.newt.event.MouseEvent e) {
|
|
972
|
-
nativeMouseEvent(e, MouseEvent.DRAG);
|
|
973
|
-
}
|
|
974
|
-
@Override
|
|
975
|
-
public void mouseMoved(com.jogamp.newt.event.MouseEvent e) {
|
|
976
|
-
nativeMouseEvent(e, MouseEvent.MOVE);
|
|
977
|
-
}
|
|
978
|
-
@Override
|
|
979
|
-
public void mouseWheelMoved(com.jogamp.newt.event.MouseEvent e) {
|
|
980
|
-
nativeMouseEvent(e, MouseEvent.WHEEL);
|
|
981
|
-
}
|
|
982
|
-
@Override
|
|
983
|
-
public void mouseEntered(com.jogamp.newt.event.MouseEvent e) {
|
|
969
|
+
@Override
|
|
970
|
+
public void mouseEntered(com.jogamp.newt.event.MouseEvent e) {
|
|
984
971
|
// System.out.println("enter");
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
972
|
+
nativeMouseEvent(e, MouseEvent.ENTER);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
@Override
|
|
976
|
+
public void mouseExited(com.jogamp.newt.event.MouseEvent e) {
|
|
989
977
|
// System.out.println("exit");
|
|
990
|
-
|
|
978
|
+
nativeMouseEvent(e, MouseEvent.EXIT);
|
|
979
|
+
}
|
|
991
980
|
}
|
|
992
|
-
}
|
|
993
981
|
|
|
982
|
+
// NEWT key listener
|
|
983
|
+
protected class NEWTKeyListener extends com.jogamp.newt.event.KeyAdapter {
|
|
994
984
|
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
super();
|
|
999
|
-
}
|
|
1000
|
-
@Override
|
|
1001
|
-
public void keyPressed(com.jogamp.newt.event.KeyEvent e) {
|
|
1002
|
-
nativeKeyEvent(e, KeyEvent.PRESS);
|
|
1003
|
-
}
|
|
1004
|
-
@Override
|
|
1005
|
-
public void keyReleased(com.jogamp.newt.event.KeyEvent e) {
|
|
1006
|
-
nativeKeyEvent(e, KeyEvent.RELEASE);
|
|
1007
|
-
}
|
|
1008
|
-
public void keyTyped(com.jogamp.newt.event.KeyEvent e) {
|
|
1009
|
-
nativeKeyEvent(e, KeyEvent.TYPE);
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
protected void nativeMouseEvent(com.jogamp.newt.event.MouseEvent nativeEvent,
|
|
1015
|
-
int peAction) {
|
|
1016
|
-
int modifiers = nativeEvent.getModifiers();
|
|
1017
|
-
int peModifiers = modifiers &
|
|
1018
|
-
(InputEvent.SHIFT_MASK |
|
|
1019
|
-
InputEvent.CTRL_MASK |
|
|
1020
|
-
InputEvent.META_MASK |
|
|
1021
|
-
InputEvent.ALT_MASK);
|
|
1022
|
-
|
|
1023
|
-
int peButton = 0;
|
|
1024
|
-
switch (nativeEvent.getButton()) {
|
|
1025
|
-
case com.jogamp.newt.event.MouseEvent.BUTTON1:
|
|
1026
|
-
peButton = PConstants.LEFT;
|
|
1027
|
-
break;
|
|
1028
|
-
case com.jogamp.newt.event.MouseEvent.BUTTON2:
|
|
1029
|
-
peButton = PConstants.CENTER;
|
|
1030
|
-
break;
|
|
1031
|
-
case com.jogamp.newt.event.MouseEvent.BUTTON3:
|
|
1032
|
-
peButton = PConstants.RIGHT;
|
|
1033
|
-
break;
|
|
1034
|
-
}
|
|
985
|
+
public NEWTKeyListener() {
|
|
986
|
+
super();
|
|
987
|
+
}
|
|
1035
988
|
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
989
|
+
@Override
|
|
990
|
+
public void keyPressed(com.jogamp.newt.event.KeyEvent e) {
|
|
991
|
+
nativeKeyEvent(e, KeyEvent.PRESS);
|
|
992
|
+
}
|
|
1042
993
|
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
peCount = -(nativeEvent.isShiftDown() ? (int)nativeEvent.getRotation()[0]:
|
|
1048
|
-
(int)nativeEvent.getRotation()[1]);
|
|
1049
|
-
} else {
|
|
1050
|
-
peCount = nativeEvent.getClickCount();
|
|
1051
|
-
}
|
|
994
|
+
@Override
|
|
995
|
+
public void keyReleased(com.jogamp.newt.event.KeyEvent e) {
|
|
996
|
+
nativeKeyEvent(e, KeyEvent.RELEASE);
|
|
997
|
+
}
|
|
1052
998
|
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
} else {
|
|
1057
|
-
scale = (int) getPixelScale();
|
|
1058
|
-
}
|
|
1059
|
-
int sx = nativeEvent.getX() / scale;
|
|
1060
|
-
int sy = nativeEvent.getY() / scale;
|
|
1061
|
-
int mx = sx;
|
|
1062
|
-
int my = sy;
|
|
1063
|
-
|
|
1064
|
-
if (pgl.presentMode()) {
|
|
1065
|
-
mx -= (int)pgl.presentX;
|
|
1066
|
-
my -= (int)pgl.presentY;
|
|
1067
|
-
if (peAction == KeyEvent.RELEASE &&
|
|
1068
|
-
pgl.insideStopButton(sx, sy - screenRect.height / windowScaleFactor)) {
|
|
1069
|
-
sketch.exit();
|
|
1070
|
-
}
|
|
1071
|
-
if (mx < 0 || sketchWidth < mx || my < 0 || sketchHeight < my) {
|
|
1072
|
-
return;
|
|
1073
|
-
}
|
|
999
|
+
public void keyTyped(com.jogamp.newt.event.KeyEvent e) {
|
|
1000
|
+
nativeKeyEvent(e, KeyEvent.TYPE);
|
|
1001
|
+
}
|
|
1074
1002
|
}
|
|
1075
1003
|
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
if (isPCodedKey(code)) {
|
|
1098
|
-
keyCode = mapToPConst(code);
|
|
1099
|
-
keyChar = PConstants.CODED;
|
|
1100
|
-
} else if (isHackyKey(code)) {
|
|
1101
|
-
// we can return only one char for ENTER, let it be \n everywhere
|
|
1102
|
-
keyCode = code == com.jogamp.newt.event.KeyEvent.VK_ENTER ?
|
|
1103
|
-
PConstants.ENTER : code;
|
|
1104
|
-
keyChar = hackToChar(code, nativeEvent.getKeyChar());
|
|
1105
|
-
} else {
|
|
1106
|
-
keyCode = code;
|
|
1107
|
-
keyChar = nativeEvent.getKeyChar();
|
|
1108
|
-
}
|
|
1004
|
+
protected void nativeMouseEvent(com.jogamp.newt.event.MouseEvent nativeEvent,
|
|
1005
|
+
int peAction) {
|
|
1006
|
+
int modifiers = nativeEvent.getModifiers();
|
|
1007
|
+
int peModifiers = modifiers
|
|
1008
|
+
& (InputEvent.SHIFT_MASK
|
|
1009
|
+
| InputEvent.CTRL_MASK
|
|
1010
|
+
| InputEvent.META_MASK
|
|
1011
|
+
| InputEvent.ALT_MASK);
|
|
1012
|
+
|
|
1013
|
+
int peButton = 0;
|
|
1014
|
+
switch (nativeEvent.getButton()) {
|
|
1015
|
+
case com.jogamp.newt.event.MouseEvent.BUTTON1:
|
|
1016
|
+
peButton = PConstants.LEFT;
|
|
1017
|
+
break;
|
|
1018
|
+
case com.jogamp.newt.event.MouseEvent.BUTTON2:
|
|
1019
|
+
peButton = PConstants.CENTER;
|
|
1020
|
+
break;
|
|
1021
|
+
case com.jogamp.newt.event.MouseEvent.BUTTON3:
|
|
1022
|
+
peButton = PConstants.RIGHT;
|
|
1023
|
+
break;
|
|
1024
|
+
}
|
|
1109
1025
|
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
// E.g. virtual key code VK_Y denotes the same physical key regardless whether keyboard layout QWERTY or QWERTZ is active. The key symbol of the former is VK_Y, where the latter produces VK_Y.
|
|
1117
|
-
KeyEvent ke = new KeyEvent(nativeEvent, nativeEvent.getWhen(),
|
|
1118
|
-
peAction, peModifiers,
|
|
1119
|
-
keyChar,
|
|
1120
|
-
keyCode,
|
|
1121
|
-
nativeEvent.isAutoRepeat());
|
|
1122
|
-
|
|
1123
|
-
sketch.postEvent(ke);
|
|
1124
|
-
|
|
1125
|
-
if (!isPCodedKey(code) && !isHackyKey(code)) {
|
|
1126
|
-
if (peAction == KeyEvent.PRESS) {
|
|
1127
|
-
// Create key typed event
|
|
1128
|
-
// TODO: combine dead keys with the following key
|
|
1129
|
-
KeyEvent tke = new KeyEvent(nativeEvent, nativeEvent.getWhen(),
|
|
1130
|
-
KeyEvent.TYPE, peModifiers,
|
|
1131
|
-
keyChar,
|
|
1132
|
-
0,
|
|
1133
|
-
nativeEvent.isAutoRepeat());
|
|
1134
|
-
|
|
1135
|
-
sketch.postEvent(tke);
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
private static boolean isPCodedKey(short code) {
|
|
1142
|
-
return code == com.jogamp.newt.event.KeyEvent.VK_UP ||
|
|
1143
|
-
code == com.jogamp.newt.event.KeyEvent.VK_DOWN ||
|
|
1144
|
-
code == com.jogamp.newt.event.KeyEvent.VK_LEFT ||
|
|
1145
|
-
code == com.jogamp.newt.event.KeyEvent.VK_RIGHT ||
|
|
1146
|
-
code == com.jogamp.newt.event.KeyEvent.VK_ALT ||
|
|
1147
|
-
code == com.jogamp.newt.event.KeyEvent.VK_CONTROL ||
|
|
1148
|
-
code == com.jogamp.newt.event.KeyEvent.VK_SHIFT ||
|
|
1149
|
-
code == com.jogamp.newt.event.KeyEvent.VK_WINDOWS;
|
|
1150
|
-
}
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
// Why do we need this mapping?
|
|
1154
|
-
// Relevant discussion and links here:
|
|
1155
|
-
// http://forum.jogamp.org/Newt-wrong-keycode-for-key-td4033690.html#a4033697
|
|
1156
|
-
// (I don't think this is a complete solution).
|
|
1157
|
-
private static int mapToPConst(short code) {
|
|
1158
|
-
switch (code) {
|
|
1159
|
-
case com.jogamp.newt.event.KeyEvent.VK_UP:
|
|
1160
|
-
return PConstants.UP;
|
|
1161
|
-
case com.jogamp.newt.event.KeyEvent.VK_DOWN:
|
|
1162
|
-
return PConstants.DOWN;
|
|
1163
|
-
case com.jogamp.newt.event.KeyEvent.VK_LEFT:
|
|
1164
|
-
return PConstants.LEFT;
|
|
1165
|
-
case com.jogamp.newt.event.KeyEvent.VK_RIGHT:
|
|
1166
|
-
return PConstants.RIGHT;
|
|
1167
|
-
case com.jogamp.newt.event.KeyEvent.VK_ALT:
|
|
1168
|
-
return PConstants.ALT;
|
|
1169
|
-
case com.jogamp.newt.event.KeyEvent.VK_CONTROL:
|
|
1170
|
-
return PConstants.CONTROL;
|
|
1171
|
-
case com.jogamp.newt.event.KeyEvent.VK_SHIFT:
|
|
1172
|
-
return PConstants.SHIFT;
|
|
1173
|
-
case com.jogamp.newt.event.KeyEvent.VK_WINDOWS:
|
|
1174
|
-
return java.awt.event.KeyEvent.VK_META;
|
|
1175
|
-
default:
|
|
1176
|
-
return code;
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1026
|
+
if (PApplet.platform == PConstants.MACOSX) {
|
|
1027
|
+
//if (nativeEvent.isPopupTrigger()) {
|
|
1028
|
+
if ((modifiers & InputEvent.CTRL_MASK) != 0) {
|
|
1029
|
+
peButton = PConstants.RIGHT;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1179
1032
|
|
|
1033
|
+
int peCount = 0;
|
|
1034
|
+
if (peAction == MouseEvent.WHEEL) {
|
|
1035
|
+
// Invert wheel rotation count so it matches JAVA2D's
|
|
1036
|
+
// https://github.com/processing/processing/issues/3840
|
|
1037
|
+
peCount = -(nativeEvent.isShiftDown() ? (int) nativeEvent.getRotation()[0]
|
|
1038
|
+
: (int) nativeEvent.getRotation()[1]);
|
|
1039
|
+
} else {
|
|
1040
|
+
peCount = nativeEvent.getClickCount();
|
|
1041
|
+
}
|
|
1180
1042
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1043
|
+
int scale;
|
|
1044
|
+
if (PApplet.platform == PConstants.MACOSX) {
|
|
1045
|
+
scale = (int) getCurrentPixelScale();
|
|
1046
|
+
} else {
|
|
1047
|
+
scale = (int) getPixelScale();
|
|
1048
|
+
}
|
|
1049
|
+
int sx = nativeEvent.getX() / scale;
|
|
1050
|
+
int sy = nativeEvent.getY() / scale;
|
|
1051
|
+
int mx = sx;
|
|
1052
|
+
int my = sy;
|
|
1053
|
+
|
|
1054
|
+
if (pgl.presentMode()) {
|
|
1055
|
+
mx -= (int) pgl.presentX;
|
|
1056
|
+
my -= (int) pgl.presentY;
|
|
1057
|
+
if (peAction == KeyEvent.RELEASE
|
|
1058
|
+
&& pgl.insideStopButton(sx, sy - screenRect.height / windowScaleFactor)) {
|
|
1059
|
+
sketch.exit();
|
|
1060
|
+
}
|
|
1061
|
+
if (mx < 0 || sketchWidth < mx || my < 0 || sketchHeight < my) {
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
MouseEvent me = new MouseEvent(nativeEvent, nativeEvent.getWhen(),
|
|
1067
|
+
peAction, peModifiers,
|
|
1068
|
+
mx, my,
|
|
1069
|
+
peButton,
|
|
1070
|
+
peCount);
|
|
1071
|
+
|
|
1072
|
+
sketch.postEvent(me);
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
protected void nativeKeyEvent(com.jogamp.newt.event.KeyEvent nativeEvent,
|
|
1076
|
+
int peAction) {
|
|
1077
|
+
int peModifiers = nativeEvent.getModifiers()
|
|
1078
|
+
& (InputEvent.SHIFT_MASK
|
|
1079
|
+
| InputEvent.CTRL_MASK
|
|
1080
|
+
| InputEvent.META_MASK
|
|
1081
|
+
| InputEvent.ALT_MASK);
|
|
1082
|
+
|
|
1083
|
+
short code = nativeEvent.getKeyCode();
|
|
1084
|
+
char keyChar;
|
|
1085
|
+
int keyCode;
|
|
1086
|
+
if (isPCodedKey(code)) {
|
|
1087
|
+
keyCode = mapToPConst(code);
|
|
1088
|
+
keyChar = PConstants.CODED;
|
|
1089
|
+
} else if (isHackyKey(code)) {
|
|
1090
|
+
// we can return only one char for ENTER, let it be \n everywhere
|
|
1091
|
+
keyCode = code == com.jogamp.newt.event.KeyEvent.VK_ENTER
|
|
1092
|
+
? PConstants.ENTER : code;
|
|
1093
|
+
keyChar = hackToChar(code, nativeEvent.getKeyChar());
|
|
1094
|
+
} else {
|
|
1095
|
+
keyCode = code;
|
|
1096
|
+
keyChar = nativeEvent.getKeyChar();
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
// From http://jogamp.org/deployment/v2.1.0/javadoc/jogl/javadoc/com/jogamp/newt/event/KeyEvent.html
|
|
1100
|
+
// public final short getKeySymbol()
|
|
1101
|
+
// Returns the virtual key symbol reflecting the current keyboard layout.
|
|
1102
|
+
// public final short getKeyCode()
|
|
1103
|
+
// Returns the virtual key code using a fixed mapping to the US keyboard layout.
|
|
1104
|
+
// In contrast to key symbol, key code uses a fixed US keyboard layout and therefore is keyboard layout independent.
|
|
1105
|
+
// E.g. virtual key code VK_Y denotes the same physical key regardless whether keyboard layout QWERTY or QWERTZ is active. The key symbol of the former is VK_Y, where the latter produces VK_Y.
|
|
1106
|
+
KeyEvent ke = new KeyEvent(nativeEvent, nativeEvent.getWhen(),
|
|
1107
|
+
peAction, peModifiers,
|
|
1108
|
+
keyChar,
|
|
1109
|
+
keyCode,
|
|
1110
|
+
nativeEvent.isAutoRepeat());
|
|
1111
|
+
|
|
1112
|
+
sketch.postEvent(ke);
|
|
1113
|
+
|
|
1114
|
+
if (!isPCodedKey(code) && !isHackyKey(code)) {
|
|
1115
|
+
if (peAction == KeyEvent.PRESS) {
|
|
1116
|
+
// Create key typed event
|
|
1117
|
+
// TODO: combine dead keys with the following key
|
|
1118
|
+
KeyEvent tke = new KeyEvent(nativeEvent, nativeEvent.getWhen(),
|
|
1119
|
+
KeyEvent.TYPE, peModifiers,
|
|
1120
|
+
keyChar,
|
|
1121
|
+
0,
|
|
1122
|
+
nativeEvent.isAutoRepeat());
|
|
1123
|
+
|
|
1124
|
+
sketch.postEvent(tke);
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1189
1127
|
}
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1128
|
+
|
|
1129
|
+
private static boolean isPCodedKey(short code) {
|
|
1130
|
+
return code == com.jogamp.newt.event.KeyEvent.VK_UP
|
|
1131
|
+
|| code == com.jogamp.newt.event.KeyEvent.VK_DOWN
|
|
1132
|
+
|| code == com.jogamp.newt.event.KeyEvent.VK_LEFT
|
|
1133
|
+
|| code == com.jogamp.newt.event.KeyEvent.VK_RIGHT
|
|
1134
|
+
|| code == com.jogamp.newt.event.KeyEvent.VK_ALT
|
|
1135
|
+
|| code == com.jogamp.newt.event.KeyEvent.VK_CONTROL
|
|
1136
|
+
|| code == com.jogamp.newt.event.KeyEvent.VK_SHIFT
|
|
1137
|
+
|| code == com.jogamp.newt.event.KeyEvent.VK_WINDOWS;
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
// Why do we need this mapping?
|
|
1141
|
+
// Relevant discussion and links here:
|
|
1142
|
+
// http://forum.jogamp.org/Newt-wrong-keycode-for-key-td4033690.html#a4033697
|
|
1143
|
+
// (I don't think this is a complete solution).
|
|
1144
|
+
private static int mapToPConst(short code) {
|
|
1145
|
+
switch (code) {
|
|
1146
|
+
case com.jogamp.newt.event.KeyEvent.VK_UP:
|
|
1147
|
+
return PConstants.UP;
|
|
1148
|
+
case com.jogamp.newt.event.KeyEvent.VK_DOWN:
|
|
1149
|
+
return PConstants.DOWN;
|
|
1150
|
+
case com.jogamp.newt.event.KeyEvent.VK_LEFT:
|
|
1151
|
+
return PConstants.LEFT;
|
|
1152
|
+
case com.jogamp.newt.event.KeyEvent.VK_RIGHT:
|
|
1153
|
+
return PConstants.RIGHT;
|
|
1154
|
+
case com.jogamp.newt.event.KeyEvent.VK_ALT:
|
|
1155
|
+
return PConstants.ALT;
|
|
1156
|
+
case com.jogamp.newt.event.KeyEvent.VK_CONTROL:
|
|
1157
|
+
return PConstants.CONTROL;
|
|
1158
|
+
case com.jogamp.newt.event.KeyEvent.VK_SHIFT:
|
|
1159
|
+
return PConstants.SHIFT;
|
|
1160
|
+
case com.jogamp.newt.event.KeyEvent.VK_WINDOWS:
|
|
1161
|
+
return java.awt.event.KeyEvent.VK_META;
|
|
1162
|
+
default:
|
|
1163
|
+
return code;
|
|
1164
|
+
}
|
|
1206
1165
|
}
|
|
1207
|
-
return def;
|
|
1208
|
-
}
|
|
1209
1166
|
|
|
1167
|
+
private static boolean isHackyKey(short code) {
|
|
1168
|
+
switch (code) {
|
|
1169
|
+
case com.jogamp.newt.event.KeyEvent.VK_BACK_SPACE:
|
|
1170
|
+
case com.jogamp.newt.event.KeyEvent.VK_TAB:
|
|
1171
|
+
case com.jogamp.newt.event.KeyEvent.VK_ENTER:
|
|
1172
|
+
case com.jogamp.newt.event.KeyEvent.VK_ESCAPE:
|
|
1173
|
+
case com.jogamp.newt.event.KeyEvent.VK_DELETE:
|
|
1174
|
+
return true;
|
|
1175
|
+
}
|
|
1176
|
+
return false;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
private static char hackToChar(short code, char def) {
|
|
1180
|
+
switch (code) {
|
|
1181
|
+
case com.jogamp.newt.event.KeyEvent.VK_BACK_SPACE:
|
|
1182
|
+
return PConstants.BACKSPACE;
|
|
1183
|
+
case com.jogamp.newt.event.KeyEvent.VK_TAB:
|
|
1184
|
+
return PConstants.TAB;
|
|
1185
|
+
case com.jogamp.newt.event.KeyEvent.VK_ENTER:
|
|
1186
|
+
return PConstants.ENTER;
|
|
1187
|
+
case com.jogamp.newt.event.KeyEvent.VK_ESCAPE:
|
|
1188
|
+
return PConstants.ESC;
|
|
1189
|
+
case com.jogamp.newt.event.KeyEvent.VK_DELETE:
|
|
1190
|
+
return PConstants.DELETE;
|
|
1191
|
+
}
|
|
1192
|
+
return def;
|
|
1193
|
+
}
|
|
1210
1194
|
|
|
1211
|
-
|
|
1195
|
+
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
1196
|
+
class CursorInfo {
|
|
1212
1197
|
|
|
1198
|
+
PImage image;
|
|
1199
|
+
int x, y;
|
|
1213
1200
|
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1201
|
+
CursorInfo(PImage image, int x, int y) {
|
|
1202
|
+
this.image = image;
|
|
1203
|
+
this.x = x;
|
|
1204
|
+
this.y = y;
|
|
1205
|
+
}
|
|
1217
1206
|
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
this.y = y;
|
|
1207
|
+
void set() {
|
|
1208
|
+
setCursor(image, x, y);
|
|
1209
|
+
}
|
|
1222
1210
|
}
|
|
1223
1211
|
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
cursorNames.put(PConstants.WAIT, "wait");
|
|
1235
|
-
cursorNames.put(PConstants.MOVE, "move");
|
|
1236
|
-
cursorNames.put(PConstants.HAND, "hand");
|
|
1237
|
-
cursorNames.put(PConstants.TEXT, "text");
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
public void setCursor(int kind) {
|
|
1242
|
-
if (!cursorNames.containsKey(kind)) {
|
|
1243
|
-
PGraphics.showWarning("Unknown cursor type: " + kind);
|
|
1244
|
-
return;
|
|
1245
|
-
}
|
|
1246
|
-
CursorInfo cursor = cursors.get(kind);
|
|
1247
|
-
if (cursor == null) {
|
|
1248
|
-
String name = cursorNames.get(kind);
|
|
1249
|
-
if (name != null) {
|
|
1250
|
-
ImageIcon icon =
|
|
1251
|
-
new ImageIcon(getClass().getResource("cursors/" + name + ".png"));
|
|
1252
|
-
PImage img = new PImage(icon.getImage());
|
|
1253
|
-
// Most cursors just use the center as the hotspot...
|
|
1254
|
-
int x = img.width / 2;
|
|
1255
|
-
int y = img.height / 2;
|
|
1256
|
-
// ...others are more specific
|
|
1257
|
-
if (kind == PConstants.ARROW) {
|
|
1258
|
-
x = 10; y = 7;
|
|
1259
|
-
} else if (kind == PConstants.HAND) {
|
|
1260
|
-
x = 12; y = 8;
|
|
1261
|
-
} else if (kind == PConstants.TEXT) {
|
|
1262
|
-
x = 16; y = 22;
|
|
1263
|
-
}
|
|
1264
|
-
cursor = new CursorInfo(img, x, y);
|
|
1265
|
-
cursors.put(kind, cursor);
|
|
1266
|
-
}
|
|
1267
|
-
}
|
|
1268
|
-
if (cursor != null) {
|
|
1269
|
-
cursor.set();
|
|
1270
|
-
} else {
|
|
1271
|
-
PGraphics.showWarning("Cannot load cursor type: " + kind);
|
|
1212
|
+
static Map<Integer, CursorInfo> cursors = new HashMap<>();
|
|
1213
|
+
static Map<Integer, String> cursorNames = new HashMap<>();
|
|
1214
|
+
|
|
1215
|
+
static {
|
|
1216
|
+
cursorNames.put(PConstants.ARROW, "arrow");
|
|
1217
|
+
cursorNames.put(PConstants.CROSS, "cross");
|
|
1218
|
+
cursorNames.put(PConstants.WAIT, "wait");
|
|
1219
|
+
cursorNames.put(PConstants.MOVE, "move");
|
|
1220
|
+
cursorNames.put(PConstants.HAND, "hand");
|
|
1221
|
+
cursorNames.put(PConstants.TEXT, "text");
|
|
1272
1222
|
}
|
|
1273
|
-
}
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
public void setCursor(PImage image, int hotspotX, int hotspotY) {
|
|
1277
|
-
Display disp = window.getScreen().getDisplay();
|
|
1278
|
-
BufferedImage bimg = (BufferedImage)image.getNative();
|
|
1279
|
-
DataBufferInt dbuf = (DataBufferInt)bimg.getData().getDataBuffer();
|
|
1280
|
-
int[] ipix = dbuf.getData();
|
|
1281
|
-
ByteBuffer pixels = ByteBuffer.allocate(ipix.length * 4);
|
|
1282
|
-
pixels.asIntBuffer().put(ipix);
|
|
1283
|
-
PixelFormat format = PixelFormat.ARGB8888;
|
|
1284
|
-
final Dimension size = new Dimension(bimg.getWidth(), bimg.getHeight());
|
|
1285
|
-
PixelRectangle pixelrect = new PixelRectangle.GenericPixelRect(format, size, 0, false, pixels);
|
|
1286
|
-
final PointerIcon pi = disp.createPointerIcon(pixelrect, hotspotX, hotspotY);
|
|
1287
|
-
display.getEDTUtil().invoke(false, new Runnable() {
|
|
1288
|
-
@Override
|
|
1289
|
-
public void run() {
|
|
1290
|
-
window.setPointerVisible(true);
|
|
1291
|
-
window.setPointerIcon(pi);
|
|
1292
|
-
}
|
|
1293
|
-
});
|
|
1294
|
-
}
|
|
1295
1223
|
|
|
1224
|
+
public void setCursor(int kind) {
|
|
1225
|
+
if (!cursorNames.containsKey(kind)) {
|
|
1226
|
+
PGraphics.showWarning("Unknown cursor type: " + kind);
|
|
1227
|
+
return;
|
|
1228
|
+
}
|
|
1229
|
+
CursorInfo cursor = cursors.get(kind);
|
|
1230
|
+
if (cursor == null) {
|
|
1231
|
+
String name = cursorNames.get(kind);
|
|
1232
|
+
if (name != null) {
|
|
1233
|
+
ImageIcon icon
|
|
1234
|
+
= new ImageIcon(getClass().getResource("cursors/" + name + ".png"));
|
|
1235
|
+
PImage img = new PImage(icon.getImage());
|
|
1236
|
+
// Most cursors just use the center as the hotspot...
|
|
1237
|
+
int x = img.width / 2;
|
|
1238
|
+
int y = img.height / 2;
|
|
1239
|
+
// ...others are more specific
|
|
1240
|
+
if (kind == PConstants.ARROW) {
|
|
1241
|
+
x = 10;
|
|
1242
|
+
y = 7;
|
|
1243
|
+
} else if (kind == PConstants.HAND) {
|
|
1244
|
+
x = 12;
|
|
1245
|
+
y = 8;
|
|
1246
|
+
} else if (kind == PConstants.TEXT) {
|
|
1247
|
+
x = 16;
|
|
1248
|
+
y = 22;
|
|
1249
|
+
}
|
|
1250
|
+
cursor = new CursorInfo(img, x, y);
|
|
1251
|
+
cursors.put(kind, cursor);
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
if (cursor != null) {
|
|
1255
|
+
cursor.set();
|
|
1256
|
+
} else {
|
|
1257
|
+
PGraphics.showWarning("Cannot load cursor type: " + kind);
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1296
1260
|
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1261
|
+
public void setCursor(PImage image, int hotspotX, int hotspotY) {
|
|
1262
|
+
Display disp = window.getScreen().getDisplay();
|
|
1263
|
+
BufferedImage bimg = (BufferedImage) image.getNative();
|
|
1264
|
+
DataBufferInt dbuf = (DataBufferInt) bimg.getData().getDataBuffer();
|
|
1265
|
+
int[] ipix = dbuf.getData();
|
|
1266
|
+
ByteBuffer pixels = ByteBuffer.allocate(ipix.length * 4);
|
|
1267
|
+
pixels.asIntBuffer().put(ipix);
|
|
1268
|
+
PixelFormat format = PixelFormat.ARGB8888;
|
|
1269
|
+
final Dimension size = new Dimension(bimg.getWidth(), bimg.getHeight());
|
|
1270
|
+
PixelRectangle pixelrect = new PixelRectangle.GenericPixelRect(format, size, 0, false, pixels);
|
|
1271
|
+
final PointerIcon pi = disp.createPointerIcon(pixelrect, hotspotX, hotspotY);
|
|
1272
|
+
display.getEDTUtil().invoke(false, new Runnable() {
|
|
1273
|
+
@Override
|
|
1274
|
+
public void run() {
|
|
1275
|
+
window.setPointerVisible(true);
|
|
1276
|
+
window.setPointerIcon(pi);
|
|
1277
|
+
}
|
|
1278
|
+
});
|
|
1279
|
+
}
|
|
1305
1280
|
|
|
1281
|
+
public void showCursor() {
|
|
1282
|
+
display.getEDTUtil().invoke(false, new Runnable() {
|
|
1283
|
+
@Override
|
|
1284
|
+
public void run() {
|
|
1285
|
+
window.setPointerVisible(true);
|
|
1286
|
+
}
|
|
1287
|
+
});
|
|
1288
|
+
}
|
|
1306
1289
|
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1290
|
+
public void hideCursor() {
|
|
1291
|
+
display.getEDTUtil().invoke(false, new Runnable() {
|
|
1292
|
+
@Override
|
|
1293
|
+
public void run() {
|
|
1294
|
+
window.setPointerVisible(false);
|
|
1295
|
+
}
|
|
1296
|
+
});
|
|
1297
|
+
}
|
|
1315
1298
|
}
|