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