propane 3.4.0-java → 3.7.0.pre-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/extensions.xml +1 -2
  3. data/.mvn/wrapper/MavenWrapperDownloader.java +2 -2
  4. data/.mvn/wrapper/maven-wrapper.properties +2 -2
  5. data/.travis.yml +2 -2
  6. data/CHANGELOG.md +12 -0
  7. data/Gemfile +2 -0
  8. data/README.md +17 -8
  9. data/Rakefile +10 -11
  10. data/bin/propane +3 -1
  11. data/lib/propane.rb +6 -4
  12. data/lib/propane/app.rb +20 -10
  13. data/lib/propane/creators/sketch_class.rb +7 -1
  14. data/lib/propane/creators/sketch_factory.rb +4 -2
  15. data/lib/propane/creators/sketch_writer.rb +1 -0
  16. data/lib/propane/helper_methods.rb +23 -24
  17. data/lib/propane/helpers/numeric.rb +2 -0
  18. data/lib/propane/helpers/version_error.rb +1 -0
  19. data/lib/propane/library.rb +5 -1
  20. data/lib/propane/library_loader.rb +2 -0
  21. data/lib/propane/native_folder.rb +10 -9
  22. data/lib/propane/native_loader.rb +3 -0
  23. data/lib/propane/runner.rb +14 -6
  24. data/lib/propane/version.rb +2 -1
  25. data/library/boids/boids.rb +21 -11
  26. data/library/color_group/color_group.rb +28 -0
  27. data/library/control_panel/control_panel.rb +8 -5
  28. data/library/dxf/dxf.rb +6 -0
  29. data/library/file_chooser/chooser.rb +10 -9
  30. data/library/file_chooser/file_chooser.rb +10 -9
  31. data/library/library_proxy/library_proxy.rb +2 -0
  32. data/library/net/net.rb +7 -0
  33. data/library/simplex_noise/simplex_noise.rb +2 -0
  34. data/library/slider/slider.rb +23 -22
  35. data/library/vector_utils/vector_utils.rb +4 -0
  36. data/library/video_event/video_event.rb +4 -1
  37. data/pom.rb +37 -36
  38. data/pom.xml +7 -7
  39. data/propane.gemspec +16 -12
  40. data/src/main/java/monkstone/ColorUtil.java +13 -1
  41. data/src/main/java/monkstone/MathToolModule.java +253 -203
  42. data/src/main/java/monkstone/PropaneLibrary.java +2 -2
  43. data/src/main/java/monkstone/fastmath/Deglut.java +1 -1
  44. data/src/main/java/monkstone/filechooser/Chooser.java +2 -1
  45. data/src/main/java/monkstone/noise/SimplexNoise.java +2 -2
  46. data/src/main/java/monkstone/slider/CustomHorizontalSlider.java +1 -1
  47. data/src/main/java/monkstone/slider/CustomVerticalSlider.java +1 -1
  48. data/src/main/java/monkstone/slider/SimpleHorizontalSlider.java +1 -1
  49. data/src/main/java/monkstone/slider/SimpleVerticalSlider.java +1 -1
  50. data/src/main/java/monkstone/slider/SliderBar.java +1 -1
  51. data/src/main/java/monkstone/slider/SliderGroup.java +1 -1
  52. data/src/main/java/monkstone/slider/WheelHandler.java +7 -6
  53. data/src/main/java/monkstone/vecmath/package-info.java +1 -1
  54. data/src/main/java/monkstone/vecmath/vec2/Vec2.java +1 -1
  55. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +3 -3
  56. data/src/main/java/monkstone/videoevent/CaptureEvent.java +27 -0
  57. data/src/main/java/monkstone/videoevent/{VideoInterface.java → MovieEvent.java} +11 -27
  58. data/src/main/java/monkstone/videoevent/package-info.java +1 -1
  59. data/src/main/java/processing/awt/PGraphicsJava2D.java +781 -285
  60. data/src/main/java/processing/awt/PImageAWT.java +377 -0
  61. data/src/main/java/processing/awt/PShapeJava2D.java +56 -52
  62. data/src/main/java/processing/awt/PSurfaceAWT.java +309 -209
  63. data/src/main/java/processing/awt/ShimAWT.java +581 -0
  64. data/src/main/java/processing/core/PApplet.java +4510 -4503
  65. data/src/main/java/processing/core/PConstants.java +477 -447
  66. data/src/main/java/processing/core/PFont.java +914 -880
  67. data/src/main/java/processing/core/PGraphics.java +193 -177
  68. data/src/main/java/processing/core/PImage.java +611 -309
  69. data/src/main/java/processing/core/PMatrix.java +172 -159
  70. data/src/main/java/processing/core/PMatrix2D.java +478 -415
  71. data/src/main/java/processing/core/PMatrix3D.java +762 -735
  72. data/src/main/java/processing/core/PShape.java +2888 -2652
  73. data/src/main/java/processing/core/PShapeOBJ.java +97 -92
  74. data/src/main/java/processing/core/PShapeSVG.java +1705 -1490
  75. data/src/main/java/processing/core/PStyle.java +40 -37
  76. data/src/main/java/processing/core/PSurface.java +139 -97
  77. data/src/main/java/processing/core/PSurfaceNone.java +296 -218
  78. data/src/main/java/processing/core/PVector.java +997 -965
  79. data/src/main/java/processing/core/ThinkDifferent.java +15 -13
  80. data/src/main/java/processing/data/DoubleDict.java +756 -710
  81. data/src/main/java/processing/data/DoubleList.java +749 -696
  82. data/src/main/java/processing/data/FloatDict.java +748 -702
  83. data/src/main/java/processing/data/FloatList.java +751 -697
  84. data/src/main/java/processing/data/IntDict.java +720 -673
  85. data/src/main/java/processing/data/IntList.java +699 -633
  86. data/src/main/java/processing/data/JSONArray.java +931 -873
  87. data/src/main/java/processing/data/JSONObject.java +1262 -1165
  88. data/src/main/java/processing/data/JSONTokener.java +351 -341
  89. data/src/main/java/processing/data/LongDict.java +710 -663
  90. data/src/main/java/processing/data/LongList.java +701 -635
  91. data/src/main/java/processing/data/Sort.java +37 -41
  92. data/src/main/java/processing/data/StringDict.java +525 -486
  93. data/src/main/java/processing/data/StringList.java +626 -580
  94. data/src/main/java/processing/data/Table.java +3690 -3510
  95. data/src/main/java/processing/data/TableRow.java +182 -183
  96. data/src/main/java/processing/data/XML.java +957 -883
  97. data/src/main/java/processing/dxf/RawDXF.java +404 -0
  98. data/src/main/java/processing/event/Event.java +87 -67
  99. data/src/main/java/processing/event/KeyEvent.java +48 -41
  100. data/src/main/java/processing/event/MouseEvent.java +88 -113
  101. data/src/main/java/processing/event/TouchEvent.java +10 -6
  102. data/src/main/java/processing/javafx/PGraphicsFX2D.java +20 -345
  103. data/src/main/java/processing/javafx/PSurfaceFX.java +149 -121
  104. data/src/main/java/processing/net/Client.java +744 -0
  105. data/src/main/java/processing/net/Server.java +388 -0
  106. data/src/main/java/processing/opengl/FontTexture.java +289 -270
  107. data/src/main/java/processing/opengl/FrameBuffer.java +386 -364
  108. data/src/main/java/processing/opengl/LinePath.java +547 -500
  109. data/src/main/java/processing/opengl/LineStroker.java +588 -581
  110. data/src/main/java/processing/opengl/PGL.java +3047 -2914
  111. data/src/main/java/processing/opengl/PGraphics2D.java +408 -315
  112. data/src/main/java/processing/opengl/PGraphics3D.java +107 -72
  113. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +12378 -12075
  114. data/src/main/java/processing/opengl/PJOGL.java +1753 -1670
  115. data/src/main/java/processing/opengl/PShader.java +1266 -1257
  116. data/src/main/java/processing/opengl/PShapeOpenGL.java +4678 -4580
  117. data/src/main/java/processing/opengl/PSurfaceJOGL.java +1114 -1027
  118. data/src/main/java/processing/opengl/Texture.java +1492 -1401
  119. data/src/main/java/processing/opengl/VertexBuffer.java +57 -55
  120. data/test/create_test.rb +21 -20
  121. data/test/deglut_spec_test.rb +4 -2
  122. data/test/helper_methods_test.rb +49 -20
  123. data/test/math_tool_test.rb +39 -32
  124. data/test/native_folder.rb +47 -0
  125. data/test/respond_to_test.rb +3 -2
  126. data/test/sketches/key_event.rb +2 -2
  127. data/test/sketches/library/my_library/my_library.rb +3 -0
  128. data/test/test_helper.rb +2 -0
  129. data/test/vecmath_spec_test.rb +35 -22
  130. data/vendors/Rakefile +33 -62
  131. metadata +56 -48
  132. data/src/main/java/processing/core/util/image/ImageLoadFacade.java +0 -161
  133. data/src/main/java/processing/core/util/image/ImageSaveFacade.java +0 -169
  134. data/src/main/java/processing/core/util/image/constants/TifConstants.java +0 -45
  135. data/src/main/java/processing/core/util/image/load/AwtImageLoadStrategy.java +0 -80
  136. data/src/main/java/processing/core/util/image/load/Base64StringImageLoadStrategy.java +0 -73
  137. data/src/main/java/processing/core/util/image/load/FallbackImageLoadStrategy.java +0 -70
  138. data/src/main/java/processing/core/util/image/load/ImageIoImageLoadStrategy.java +0 -132
  139. data/src/main/java/processing/core/util/image/load/ImageLoadStrategy.java +0 -48
  140. data/src/main/java/processing/core/util/image/load/ImageLoadUtil.java +0 -45
  141. data/src/main/java/processing/core/util/image/load/TgaImageLoadStrategy.java +0 -255
  142. data/src/main/java/processing/core/util/image/load/TiffImageLoadStrategy.java +0 -98
  143. data/src/main/java/processing/core/util/image/save/ImageSaveStrategy.java +0 -49
  144. data/src/main/java/processing/core/util/image/save/ImageSaveUtil.java +0 -48
  145. data/src/main/java/processing/core/util/image/save/ImageWriterImageSaveStrategy.java +0 -179
  146. data/src/main/java/processing/core/util/image/save/SaveImageException.java +0 -41
  147. data/src/main/java/processing/core/util/image/save/TgaImageSaveStrategy.java +0 -198
  148. data/src/main/java/processing/core/util/image/save/TiffImageSaveStrategy.java +0 -91
  149. data/src/main/java/processing/core/util/image/save/TiffNakedFilenameImageSaveStrategy.java +0 -57
  150. data/src/main/java/processing/core/util/io/InputFactory.java +0 -285
  151. data/src/main/java/processing/core/util/io/PathUtil.java +0 -109
  152. data/src/main/java/processing/opengl/shaders/LightVert-brcm.glsl +0 -154
  153. data/src/main/java/processing/opengl/shaders/LightVert-vc4.glsl +0 -154
  154. data/src/main/java/processing/opengl/shaders/TexLightVert-brcm.glsl +0 -160
  155. 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
- public PJOGL pgl;
89
+ protected GLWindow window;
90
+ protected FPSAnimator animator;
91
+ protected Rectangle screenRect;
81
92
 
82
- protected GLWindow window;
83
- protected FPSAnimator animator;
84
- protected Rectangle screenRect;
93
+ private Thread drawExceptionHandler;
85
94
 
86
- private Thread drawExceptionHandler;
95
+ protected PApplet sketch;
96
+ protected PGraphics graphics;
87
97
 
88
- protected PApplet sketch;
89
- protected PGraphics graphics;
98
+ protected int sketchWidth0;
99
+ protected int sketchHeight0;
100
+ protected int sketchWidth;
101
+ protected int sketchHeight;
90
102
 
91
- protected int sketchWidth0;
92
- protected int sketchHeight0;
93
- protected int sketchWidth;
94
- protected int sketchHeight;
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
- protected Display display;
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
- protected NewtCanvasAWT canvas;
111
+ protected int windowScaleFactor;
103
112
 
104
- protected int windowScaleFactor;
113
+ protected float[] currentPixelScale = {0, 0};
105
114
 
106
- protected float[] currentPixelScale = {0, 0};
115
+ protected boolean external = false;
107
116
 
108
- protected boolean external = false;
109
117
 
110
- public PSurfaceJOGL(PGraphics graphics) {
111
- this.graphics = graphics;
112
- this.pgl = (PJOGL) ((PGraphicsOpenGL) graphics).pgl;
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
- sketchWidth = sketch.sketchWidth();
119
- sketchHeight = sketch.sketchHeight();
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
- public void initFrame(PApplet sketch) {
129
- this.sketch = sketch;
130
- initIcons();
131
- initDisplay();
132
- initGL();
133
- initWindow();
134
- initListeners();
135
- initAnimator();
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
- public Object getNative() {
139
- return window;
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
- GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
149
- GraphicsDevice[] awtDevices = environment.getScreenDevices();
210
+ @Override
211
+ public void initFrame(PApplet sketch) {
212
+ this.sketch = sketch;
150
213
 
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
- }
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
- if (awtDisplayDevice == null) {
168
- awtDisplayDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
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
- displayRect = awtDisplayDevice.getDefaultConfiguration().getBounds();
254
+ if (awtDisplayDevice == null) {
255
+ awtDisplayDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
172
256
  }
173
257
 
174
- protected void initGL() {
258
+ GraphicsConfiguration config = awtDisplayDevice.getDefaultConfiguration();
259
+ displayRect = config.getBounds();
260
+ }
261
+
262
+
263
+ protected void initGL() {
175
264
  // System.out.println("*******************************");
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);
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
- // 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);
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
- caps.setSampleBuffers(true);
231
- caps.setNumSamples(PGL.smoothToSamples(graphics.smooth));
232
- caps.setBackgroundOpaque(true);
233
- caps.setOnscreen(true);
234
- pgl.setCaps(caps);
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
- // 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);
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
- 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());
343
+ windowScaleFactor = PApplet.platform == PConstants.MACOS ?
344
+ 1 : sketch.pixelDensity;
261
345
 
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;
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
- sketchWidth0 = sketch.sketchWidth();
268
- sketchHeight0 = sketch.sketchHeight();
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
- sketchWidth = sketch.sketchWidth();
289
- sketchHeight = sketch.sketchHeight();
378
+ */
379
+
380
+ sketchWidth = sketch.sketchWidth();
381
+ sketchHeight = sketch.sketchHeight();
290
382
  // System.out.println("init: " + sketchWidth + " " + sketchHeight);
291
383
 
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
- /*
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
- 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};
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
- 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
- }
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
- @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
- });
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
- @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
- }
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
- 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
- }
441
+ DrawListener drawlistener = new DrawListener();
442
+ window.addGLEventListener(drawlistener);
443
+ }
448
444
 
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
- });
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
- 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
- }
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
- res = new ClassResources(iconImages,
479
- sketch.getClass().getClassLoader(),
480
- sketch.getClass());
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
- NewtFactory.setWindowIcons(res);
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
- @SuppressWarnings("resource")
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
- // 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
- }
497
-
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
- }
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
- stream = new FileInputStream(file);
520
- if (stream != null) {
521
- stream.close();
522
- return file.getCanonicalPath();
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
- // 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) {
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
- ClassLoader cl = sketch.getClass().getClassLoader();
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
- // 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
- }
643
+ String path = sketch.dataPath(filename);
644
+ stream = new FileInputStream(path);
645
+ stream.close();
646
+ return path;
647
+ } catch (IOException e2) { }
548
648
 
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
- }
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
- // 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
- }
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
- @Override
608
- public void placeWindow(int[] location, int[] editorLocation) {
670
+ return "";
671
+ }
609
672
 
610
- if (sketch.sketchFullScreen()) {
611
- return;
612
- }
613
673
 
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();
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
- if (location != null) {
686
+ if (location != null) {
620
687
  // System.err.println("place window at " + location[0] + ", " + location[1]);
621
- window.setTopLevelPosition(location[0], location[1]);
688
+ window.setTopLevelPosition(location[0], location[1]);
622
689
 
623
- } else if (editorLocation != null) {
690
+ } else if (editorLocation != null) {
624
691
  // System.err.println("place window at editor location " + editorLocation[0] + ", " + editorLocation[1]);
625
- int locationX = editorLocation[0] - 20;
626
- int locationY = editorLocation[1];
692
+ int locationX = editorLocation[0] - 20;
693
+ int locationY = editorLocation[1];
627
694
 
628
- if (locationX - w > 10) {
629
- // if it fits to the left of the window
630
- window.setTopLevelPosition(locationX - w, locationY);
695
+ if (locationX - w > 10) {
696
+ // if it fits to the left of the window
697
+ window.setTopLevelPosition(locationX - w, locationY);
631
698
 
632
- } else { // doesn't fit
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
- 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);
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
- 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
- }
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
- window.setUndecorated(true);
673
- window.setTopLevelPosition((int) displayRect.getX(), (int) displayRect.getY());
674
- window.setTopLevelSize((int) displayRect.getWidth(), (int) displayRect.getHeight());
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
- public void setupExternalMessages() {
678
- external = true;
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
- public void pauseThread() {
688
- if (animator != null) {
689
- animator.pause();
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
- 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
- }
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
- 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
- });
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
- // 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
- }
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
- sketchWidth = wide;
746
- sketchHeight = high;
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
- if (changed) {
752
- window.setSize(wide * windowScaleFactor, high * windowScaleFactor);
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
- if (PApplet.platform == PConstants.MACOSX) {
762
- return getCurrentPixelScale();
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
- public void requestFocus() {
815
- display.getEDTUtil().invoke(false, new Runnable() {
816
- @Override
817
- public void run() {
818
- window.requestFocus();
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
- class DrawListener implements GLEventListener {
823
+ boolean changed = sketch.width != wide || sketch.height != high;
824
824
 
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
- }
825
+ sketchWidth = wide;
826
+ sketchHeight = high;
831
827
 
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
- }
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
- if (sketch.exitCalled()) {
855
- PGraphicsOpenGL.completeAllPixelTransfers();
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
- public void dispose(GLAutoDrawable drawable) {
863
- // sketch.dispose();
864
- }
837
+ public float getPixelScale() {
838
+ if (graphics.pixelDensity == 1) {
839
+ return 1;
840
+ }
865
841
 
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
- }
842
+ if (PApplet.platform == PConstants.MACOS) {
843
+ return getCurrentPixelScale();
844
+ }
878
845
 
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
- }
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
- public NEWTWindowListener() {
891
- super();
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
- @Override
901
- public void windowLostFocus(com.jogamp.newt.event.WindowEvent arg0) {
902
- sketch.focused = false;
903
- sketch.focusLost();
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
- @Override
907
- public void windowDestroyNotify(com.jogamp.newt.event.WindowEvent arg0) {
908
- sketch.exit();
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
- @Override
912
- public void windowDestroyed(com.jogamp.newt.event.WindowEvent arg0) {
913
- sketch.exit();
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
- @Override
917
- public void windowMoved(com.jogamp.newt.event.WindowEvent arg0) {
918
- if (external) {
919
- sketch.frameMoved(window.getX(), window.getY());
920
- }
921
- }
938
+ if (sketch.exitCalled()) {
939
+ PGraphicsOpenGL.completeAllPixelTransfers();
922
940
 
923
- @Override
924
- public void windowRepaint(com.jogamp.newt.event.WindowUpdateEvent arg0) {
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
- @Override
928
- public void windowResized(com.jogamp.newt.event.WindowEvent arg0) {
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
- public NEWTMouseListener() {
936
- super();
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
- @Override
940
- public void mousePressed(com.jogamp.newt.event.MouseEvent e) {
941
- nativeMouseEvent(e, MouseEvent.PRESS);
942
- }
984
+ @Override
985
+ public void windowLostFocus(com.jogamp.newt.event.WindowEvent arg0) {
986
+ sketch.focused = false;
987
+ sketch.focusLost();
988
+ }
943
989
 
944
- @Override
945
- public void mouseReleased(com.jogamp.newt.event.MouseEvent e) {
946
- nativeMouseEvent(e, MouseEvent.RELEASE);
947
- }
990
+ @Override
991
+ public void windowDestroyNotify(com.jogamp.newt.event.WindowEvent arg0) {
992
+ sketch.exit();
993
+ }
948
994
 
949
- @Override
950
- public void mouseClicked(com.jogamp.newt.event.MouseEvent e) {
951
- nativeMouseEvent(e, MouseEvent.CLICK);
952
- }
995
+ @Override
996
+ public void windowDestroyed(com.jogamp.newt.event.WindowEvent arg0) {
997
+ sketch.exit();
998
+ }
953
999
 
954
- @Override
955
- public void mouseDragged(com.jogamp.newt.event.MouseEvent e) {
956
- nativeMouseEvent(e, MouseEvent.DRAG);
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
- @Override
960
- public void mouseMoved(com.jogamp.newt.event.MouseEvent e) {
961
- nativeMouseEvent(e, MouseEvent.MOVE);
962
- }
1007
+ @Override
1008
+ public void windowRepaint(com.jogamp.newt.event.WindowUpdateEvent arg0) {
1009
+ }
963
1010
 
964
- @Override
965
- public void mouseWheelMoved(com.jogamp.newt.event.MouseEvent e) {
966
- nativeMouseEvent(e, MouseEvent.WHEEL);
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
- @Override
976
- public void mouseExited(com.jogamp.newt.event.MouseEvent e) {
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
- nativeMouseEvent(e, MouseEvent.EXIT);
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
- @Override
995
- public void keyReleased(com.jogamp.newt.event.KeyEvent e) {
996
- nativeKeyEvent(e, KeyEvent.RELEASE);
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
- public void keyTyped(com.jogamp.newt.event.KeyEvent e) {
1000
- nativeKeyEvent(e, KeyEvent.TYPE);
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
- 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
- }
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
- if (PApplet.platform == PConstants.MACOSX) {
1027
- //if (nativeEvent.isPopupTrigger()) {
1028
- if ((modifiers & InputEvent.CTRL_MASK) != 0) {
1029
- peButton = PConstants.RIGHT;
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
- 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
- }
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
- 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
- }
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
- // 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
- }
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
- 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
- }
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
- CursorInfo(PImage image, int x, int y) {
1202
- this.image = image;
1203
- this.x = x;
1204
- this.y = y;
1205
- }
1274
+ class CursorInfo {
1275
+ PImage image;
1276
+ int x, y;
1206
1277
 
1207
- void set() {
1208
- setCursor(image, x, y);
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
- 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");
1284
+ void set() {
1285
+ setCursor(image, x, y);
1222
1286
  }
1287
+ }
1223
1288
 
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
- }
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
- public void hideCursor() {
1291
- display.getEDTUtil().invoke(false, new Runnable() {
1292
- @Override
1293
- public void run() {
1294
- window.setPointerVisible(false);
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
  }