propane 2.7.2-java → 2.8.0.pre-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +10 -0
  3. data/CHANGELOG.md +1 -1
  4. data/README.md +10 -8
  5. data/Rakefile +1 -1
  6. data/lib/propane/app.rb +3 -3
  7. data/lib/propane/version.rb +1 -1
  8. data/lib/{processing-core.jar → propane-2.8.0.jar} +0 -0
  9. data/library/control_panel/control_panel.rb +3 -2
  10. data/pom.rb +89 -88
  11. data/pom.xml +75 -46
  12. data/propane.gemspec +1 -2
  13. data/src/main/java/japplemenubar/JAppleMenuBar.java +88 -0
  14. data/src/main/java/japplemenubar/libjAppleMenuBar.jnilib +0 -0
  15. data/src/{monkstone → main/java/monkstone}/ColorUtil.java +0 -0
  16. data/src/{monkstone → main/java/monkstone}/MathToolModule.java +0 -0
  17. data/src/{monkstone → main/java/monkstone}/PropaneLibrary.java +0 -0
  18. data/src/{monkstone → main/java/monkstone}/core/LibraryProxy.java +0 -0
  19. data/src/{monkstone → main/java/monkstone}/fastmath/Deglut.java +0 -0
  20. data/src/{monkstone → main/java/monkstone}/fastmath/package-info.java +0 -0
  21. data/src/{monkstone → main/java/monkstone}/filechooser/Chooser.java +0 -0
  22. data/src/{monkstone → main/java/monkstone}/noise/SimplexNoise.java +0 -0
  23. data/src/{monkstone → main/java/monkstone}/slider/CustomHorizontalSlider.java +0 -0
  24. data/src/{monkstone → main/java/monkstone}/slider/CustomVerticalSlider.java +0 -0
  25. data/src/{monkstone → main/java/monkstone}/slider/SimpleHorizontalSlider.java +0 -0
  26. data/src/{monkstone → main/java/monkstone}/slider/SimpleSlider.java +0 -0
  27. data/src/{monkstone → main/java/monkstone}/slider/SimpleVerticalSlider.java +0 -0
  28. data/src/{monkstone → main/java/monkstone}/slider/Slider.java +0 -0
  29. data/src/{monkstone → main/java/monkstone}/slider/SliderBar.java +0 -0
  30. data/src/{monkstone → main/java/monkstone}/slider/SliderGroup.java +0 -0
  31. data/src/{monkstone → main/java/monkstone}/slider/WheelHandler.java +0 -0
  32. data/src/{monkstone → main/java/monkstone}/vecmath/AppRender.java +0 -0
  33. data/src/{monkstone → main/java/monkstone}/vecmath/JRender.java +0 -0
  34. data/src/{monkstone → main/java/monkstone}/vecmath/ShapeRender.java +0 -0
  35. data/src/{monkstone → main/java/monkstone}/vecmath/package-info.java +0 -0
  36. data/src/{monkstone → main/java/monkstone}/vecmath/vec2/Vec2.java +0 -0
  37. data/src/{monkstone → main/java/monkstone}/vecmath/vec2/package-info.java +0 -0
  38. data/src/{monkstone → main/java/monkstone}/vecmath/vec3/Vec3.java +0 -0
  39. data/src/{monkstone → main/java/monkstone}/vecmath/vec3/package-info.java +0 -0
  40. data/src/{monkstone → main/java/monkstone}/videoevent/VideoInterface.java +0 -0
  41. data/src/{monkstone → main/java/monkstone}/videoevent/package-info.java +0 -0
  42. data/src/main/java/processing/awt/PGraphicsJava2D.java +3029 -0
  43. data/src/main/java/processing/awt/PShapeJava2D.java +377 -0
  44. data/src/main/java/processing/awt/PSurfaceAWT.java +1567 -0
  45. data/src/main/java/processing/core/PApplet.java +15709 -0
  46. data/src/main/java/processing/core/PConstants.java +527 -0
  47. data/src/main/java/processing/core/PFont.java +1098 -0
  48. data/src/main/java/processing/core/PGraphics.java +8467 -0
  49. data/src/main/java/processing/core/PImage.java +3438 -0
  50. data/src/main/java/processing/core/PMatrix.java +208 -0
  51. data/src/main/java/processing/core/PMatrix2D.java +534 -0
  52. data/src/main/java/processing/core/PMatrix3D.java +877 -0
  53. data/src/main/java/processing/core/PShape.java +3445 -0
  54. data/src/main/java/processing/core/PShapeOBJ.java +469 -0
  55. data/src/main/java/processing/core/PShapeSVG.java +1787 -0
  56. data/src/main/java/processing/core/PStyle.java +63 -0
  57. data/src/main/java/processing/core/PSurface.java +161 -0
  58. data/src/main/java/processing/core/PSurfaceNone.java +374 -0
  59. data/src/main/java/processing/core/PVector.java +1063 -0
  60. data/src/main/java/processing/data/FloatDict.java +829 -0
  61. data/src/main/java/processing/data/FloatList.java +912 -0
  62. data/src/main/java/processing/data/IntDict.java +796 -0
  63. data/src/main/java/processing/data/IntList.java +913 -0
  64. data/src/main/java/processing/data/JSONArray.java +1260 -0
  65. data/src/main/java/processing/data/JSONObject.java +2282 -0
  66. data/src/main/java/processing/data/JSONTokener.java +435 -0
  67. data/src/main/java/processing/data/Sort.java +46 -0
  68. data/src/main/java/processing/data/StringDict.java +601 -0
  69. data/src/main/java/processing/data/StringList.java +775 -0
  70. data/src/main/java/processing/data/Table.java +4923 -0
  71. data/src/main/java/processing/data/TableRow.java +198 -0
  72. data/src/main/java/processing/data/XML.java +1149 -0
  73. data/src/main/java/processing/event/Event.java +125 -0
  74. data/src/main/java/processing/event/KeyEvent.java +70 -0
  75. data/src/main/java/processing/event/MouseEvent.java +149 -0
  76. data/src/main/java/processing/event/TouchEvent.java +57 -0
  77. data/src/main/java/processing/opengl/FontTexture.java +379 -0
  78. data/src/main/java/processing/opengl/FrameBuffer.java +503 -0
  79. data/src/main/java/processing/opengl/LinePath.java +623 -0
  80. data/src/main/java/processing/opengl/LineStroker.java +685 -0
  81. data/src/main/java/processing/opengl/PGL.java +3366 -0
  82. data/src/main/java/processing/opengl/PGraphics2D.java +615 -0
  83. data/src/main/java/processing/opengl/PGraphics3D.java +281 -0
  84. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +13634 -0
  85. data/src/main/java/processing/opengl/PJOGL.java +1966 -0
  86. data/src/main/java/processing/opengl/PShader.java +1478 -0
  87. data/src/main/java/processing/opengl/PShapeOpenGL.java +5234 -0
  88. data/src/main/java/processing/opengl/PSurfaceJOGL.java +1315 -0
  89. data/src/main/java/processing/opengl/Texture.java +1670 -0
  90. data/src/main/java/processing/opengl/VertexBuffer.java +88 -0
  91. data/src/main/java/processing/opengl/cursors/arrow.png +0 -0
  92. data/src/main/java/processing/opengl/cursors/cross.png +0 -0
  93. data/src/main/java/processing/opengl/cursors/hand.png +0 -0
  94. data/src/main/java/processing/opengl/cursors/license.txt +27 -0
  95. data/src/main/java/processing/opengl/cursors/move.png +0 -0
  96. data/src/main/java/processing/opengl/cursors/text.png +0 -0
  97. data/src/main/java/processing/opengl/cursors/wait.png +0 -0
  98. data/src/main/java/processing/opengl/shaders/ColorFrag.glsl +32 -0
  99. data/src/main/java/processing/opengl/shaders/ColorVert.glsl +34 -0
  100. data/src/main/java/processing/opengl/shaders/LightFrag.glsl +33 -0
  101. data/src/main/java/processing/opengl/shaders/LightVert-vc4.glsl +154 -0
  102. data/src/main/java/processing/opengl/shaders/LightVert.glsl +151 -0
  103. data/src/main/java/processing/opengl/shaders/LineFrag.glsl +32 -0
  104. data/src/main/java/processing/opengl/shaders/LineVert.glsl +100 -0
  105. data/src/main/java/processing/opengl/shaders/MaskFrag.glsl +40 -0
  106. data/src/main/java/processing/opengl/shaders/PointFrag.glsl +32 -0
  107. data/src/main/java/processing/opengl/shaders/PointVert.glsl +56 -0
  108. data/src/main/java/processing/opengl/shaders/TexFrag.glsl +37 -0
  109. data/src/main/java/processing/opengl/shaders/TexLightFrag.glsl +37 -0
  110. data/src/main/java/processing/opengl/shaders/TexLightVert-vc4.glsl +160 -0
  111. data/src/main/java/processing/opengl/shaders/TexLightVert.glsl +157 -0
  112. data/src/main/java/processing/opengl/shaders/TexVert.glsl +38 -0
  113. data/src/main/resources/icon/icon-1024.png +0 -0
  114. data/src/main/resources/icon/icon-128.png +0 -0
  115. data/src/main/resources/icon/icon-16.png +0 -0
  116. data/src/main/resources/icon/icon-256.png +0 -0
  117. data/src/main/resources/icon/icon-32.png +0 -0
  118. data/src/main/resources/icon/icon-48.png +0 -0
  119. data/src/main/resources/icon/icon-512.png +0 -0
  120. data/src/main/resources/icon/icon-64.png +0 -0
  121. data/src/main/resources/license.txt +508 -0
  122. data/vendors/Rakefile +5 -20
  123. metadata +115 -33
  124. data/lib/propane.jar +0 -0
@@ -0,0 +1,1567 @@
1
+ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
+
3
+ /*
4
+ Part of the Processing project - http://processing.org
5
+
6
+ Copyright (c) 2014-15 The Processing Foundation
7
+
8
+ This library is free software; you can redistribute it and/or
9
+ modify it under the terms of the GNU Lesser General Public
10
+ License as published by the Free Software Foundation, version 2.1.
11
+
12
+ This library is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ Lesser General Public License for more details.
16
+
17
+ You should have received a copy of the GNU Lesser General
18
+ Public License along with this library; if not, write to the
19
+ Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20
+ Boston, MA 02111-1307 USA
21
+ */
22
+
23
+ package processing.awt;
24
+
25
+ import java.awt.Canvas;
26
+ import java.awt.Color;
27
+ import java.awt.Cursor;
28
+ import java.awt.Dimension;
29
+ import java.awt.Frame;
30
+ import java.awt.Graphics;
31
+ import java.awt.Graphics2D;
32
+ import java.awt.GraphicsConfiguration;
33
+ import java.awt.GraphicsDevice;
34
+ import java.awt.GraphicsEnvironment;
35
+ import java.awt.Image;
36
+ import java.awt.Insets;
37
+ import java.awt.Label;
38
+ import java.awt.Point;
39
+ import java.awt.Rectangle;
40
+ import java.awt.Toolkit;
41
+ import java.awt.event.*;
42
+ import java.awt.geom.Rectangle2D;
43
+ import java.awt.image.*;
44
+ import java.lang.management.ManagementFactory;
45
+ import java.lang.reflect.Method;
46
+ import java.net.URL;
47
+ import java.util.ArrayList;
48
+ import java.util.List;
49
+
50
+ import javax.swing.JFrame;
51
+
52
+ import processing.core.PApplet;
53
+ import processing.core.PConstants;
54
+ import processing.core.PGraphics;
55
+ import processing.core.PImage;
56
+ import processing.core.PSurfaceNone;
57
+ import processing.event.KeyEvent;
58
+ import processing.event.MouseEvent;
59
+
60
+
61
+ public class PSurfaceAWT extends PSurfaceNone {
62
+ GraphicsDevice displayDevice;
63
+
64
+ // used for canvas to determine whether resizable or not
65
+ // boolean resizable; // default is false
66
+
67
+ // Internally, we know it's always a JFrame (not just a Frame)
68
+ // JFrame frame;
69
+ // Trying Frame again with a11 to see if this avoids some Swing nastiness.
70
+ // In the past, AWT Frames caused some problems on Windows and Linux,
71
+ // but those may not be a problem for our reworked PSurfaceAWT class.
72
+ Frame frame;
73
+
74
+ // Note that x and y may not be zero, depending on the display configuration
75
+ Rectangle screenRect;
76
+
77
+ // Used for resizing, at least on Windows insets size changes when
78
+ // frame.setResizable() is called, and in resize listener we need
79
+ // to know what size the window was before.
80
+ Insets currentInsets = new Insets(0, 0, 0, 0);
81
+
82
+ // 3.0a5 didn't use strategy, and active was shut off during init() w/ retina
83
+ // boolean useStrategy = true;
84
+
85
+ Canvas canvas;
86
+ // Component canvas;
87
+
88
+ // PGraphics graphics; // moved to PSurfaceNone
89
+
90
+ int sketchWidth;
91
+ int sketchHeight;
92
+
93
+ int windowScaleFactor;
94
+
95
+
96
+ public PSurfaceAWT(PGraphics graphics) {
97
+ //this.graphics = graphics;
98
+ super(graphics);
99
+
100
+ /*
101
+ if (checkRetina()) {
102
+ // System.out.println("retina in use");
103
+
104
+ // The active-mode rendering seems to be 2x slower, so disable it
105
+ // with retina. On a non-retina machine, however, useActive seems
106
+ // the only (or best) way to handle the rendering.
107
+ // useActive = false;
108
+ // canvas = new JPanel(true) {
109
+ // @Override
110
+ // public void paint(Graphics screen) {
111
+ //// if (!sketch.insideDraw) {
112
+ // screen.drawImage(PSurfaceAWT.this.graphics.image, 0, 0, sketchWidth, sketchHeight, null);
113
+ //// }
114
+ // }
115
+ // };
116
+ // Under 1.8 and the current 3.0a6 threading regime, active mode w/o
117
+ // strategy is far faster, but perhaps only because it's blitting with
118
+ // flicker--pushing pixels out before the screen has finished rendering.
119
+ // useStrategy = false;
120
+ }
121
+ */
122
+ canvas = new SmoothCanvas();
123
+ // if (useStrategy) {
124
+ //canvas.setIgnoreRepaint(true);
125
+ // }
126
+
127
+ // Pass tab key to the sketch, rather than moving between components
128
+ canvas.setFocusTraversalKeysEnabled(false);
129
+
130
+ canvas.addComponentListener(new ComponentAdapter() {
131
+ @Override
132
+ public void componentResized(ComponentEvent e) {
133
+ if (!sketch.isLooping()) {
134
+ // make sure this is a real resize event, not just initial setup
135
+ // https://github.com/processing/processing/issues/3310
136
+ Dimension canvasSize = canvas.getSize();
137
+ if (canvasSize.width != sketch.sketchWidth() ||
138
+ canvasSize.height != sketch.sketchHeight()) {
139
+ sketch.redraw();
140
+ }
141
+ }
142
+ }
143
+ });
144
+ addListeners();
145
+ }
146
+
147
+
148
+ // /**
149
+ // * Handle grabbing the focus on startup. Other renderers can override this
150
+ // * if handling needs to be different. For the AWT, the request is invoked
151
+ // * later on the EDT. Other implementations may not require that, so the
152
+ // * invokeLater() happens in here rather than requiring the caller to wrap it.
153
+ // */
154
+ // @Override
155
+ // void requestFocus() {
156
+ //// System.out.println("requesFocus() outer " + EventQueue.isDispatchThread());
157
+ // // for 2.0a6, moving this request to the EDT
158
+ // EventQueue.invokeLater(new Runnable() {
159
+ // public void run() {
160
+ // // Call the request focus event once the image is sure to be on
161
+ // // screen and the component is valid. The OpenGL renderer will
162
+ // // request focus for its canvas inside beginDraw().
163
+ // // http://java.sun.com/j2se/1.4.2/docs/api/java/awt/doc-files/FocusSpec.html
164
+ // // Disabling for 0185, because it causes an assertion failure on OS X
165
+ // // http://code.google.com/p/processing/issues/detail?id=258
166
+ // // requestFocus();
167
+ //
168
+ // // Changing to this version for 0187
169
+ // // http://code.google.com/p/processing/issues/detail?id=279
170
+ // //requestFocusInWindow();
171
+ //
172
+ // // For 3.0, just call this directly on the Canvas object
173
+ // if (canvas != null) {
174
+ // //System.out.println("requesting focus " + EventQueue.isDispatchThread());
175
+ // //System.out.println("requesting focus " + frame.isVisible());
176
+ // //canvas.requestFocusInWindow();
177
+ // canvas.requestFocus();
178
+ // }
179
+ // }
180
+ // });
181
+ // }
182
+
183
+
184
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
185
+
186
+
187
+ public class SmoothCanvas extends Canvas {
188
+ private Dimension oldSize = new Dimension(0, 0);
189
+ private Dimension newSize = new Dimension(0, 0);
190
+
191
+
192
+ // Turns out getParent() returns a JPanel on a JFrame. Yech.
193
+ public Frame getFrame() {
194
+ return frame;
195
+ }
196
+
197
+
198
+ @Override
199
+ public Dimension getPreferredSize() {
200
+ return new Dimension(sketchWidth, sketchHeight);
201
+ }
202
+
203
+
204
+ @Override
205
+ public Dimension getMinimumSize() {
206
+ return getPreferredSize();
207
+ }
208
+
209
+
210
+ @Override
211
+ public Dimension getMaximumSize() {
212
+ //return resizable ? super.getMaximumSize() : getPreferredSize();
213
+ return frame.isResizable() ? super.getMaximumSize() : getPreferredSize();
214
+ }
215
+
216
+
217
+ @Override
218
+ public void validate() {
219
+ super.validate();
220
+ newSize.width = getWidth();
221
+ newSize.height = getHeight();
222
+ // if (oldSize.equals(newSize)) {
223
+ //// System.out.println("validate() return " + oldSize);
224
+ // return;
225
+ // } else {
226
+ if (!oldSize.equals(newSize)) {
227
+ // System.out.println("validate() render old=" + oldSize + " -> new=" + newSize);
228
+ oldSize = newSize;
229
+ sketch.setSize(newSize.width / windowScaleFactor, newSize.height / windowScaleFactor);
230
+ // try {
231
+ render();
232
+ // } catch (IllegalStateException ise) {
233
+ // System.out.println(ise.getMessage());
234
+ // }
235
+ }
236
+ }
237
+
238
+
239
+ @Override
240
+ public void update(Graphics g) {
241
+ // System.out.println("updating");
242
+ paint(g);
243
+ }
244
+
245
+
246
+ @Override
247
+ public void paint(Graphics screen) {
248
+ // System.out.println("painting");
249
+ // if (useStrategy) {
250
+ render();
251
+ /*
252
+ if (graphics != null) {
253
+ System.out.println("drawing to screen " + canvas);
254
+ screen.drawImage(graphics.image, 0, 0, sketchWidth, sketchHeight, null);
255
+ }
256
+ */
257
+
258
+ // } else {
259
+ //// new Exception("painting").printStackTrace(System.out);
260
+ //// if (graphics.image != null) { // && !sketch.insideDraw) {
261
+ // if (onscreen != null) {
262
+ //// synchronized (graphics.image) {
263
+ // // Needs the width/height to be set so that retina images are properly scaled down
264
+ //// screen.drawImage(graphics.image, 0, 0, sketchWidth, sketchHeight, null);
265
+ // synchronized (offscreenLock) {
266
+ // screen.drawImage(onscreen, 0, 0, sketchWidth, sketchHeight, null);
267
+ // }
268
+ // }
269
+ // }
270
+ }
271
+ }
272
+
273
+ /*
274
+ @Override
275
+ public void addNotify() {
276
+ // System.out.println("adding notify");
277
+ super.addNotify();
278
+ // prior to Java 7 on OS X, this no longer works [121222]
279
+ // createBufferStrategy(2);
280
+ }
281
+ */
282
+
283
+
284
+ synchronized protected void render() {
285
+ if (canvas.isDisplayable() &&
286
+ graphics.image != null) {
287
+ if (canvas.getBufferStrategy() == null) {
288
+ canvas.createBufferStrategy(2);
289
+ }
290
+ BufferStrategy strategy = canvas.getBufferStrategy();
291
+ if (strategy != null) {
292
+ // Render single frame
293
+ // try {
294
+ do {
295
+ // The following loop ensures that the contents of the drawing buffer
296
+ // are consistent in case the underlying surface was recreated
297
+ do {
298
+ Graphics2D draw = (Graphics2D) strategy.getDrawGraphics();
299
+ // draw to width/height, since this may be a 2x image
300
+ draw.drawImage(graphics.image, 0, 0, sketchWidth, sketchHeight, null);
301
+ draw.dispose();
302
+ } while (strategy.contentsRestored());
303
+
304
+ // Display the buffer
305
+ strategy.show();
306
+
307
+ // Repeat the rendering if the drawing buffer was lost
308
+ } while (strategy.contentsLost());
309
+ }
310
+ }
311
+ }
312
+
313
+
314
+ /*
315
+ protected void blit() {
316
+ // Other folks that call render() (i.e. paint()) are already on the EDT.
317
+ // We need to be using the EDT since we're messing with the Canvas
318
+ // object and BufferStrategy and friends.
319
+ //EventQueue.invokeLater(new Runnable() {
320
+ //public void run() {
321
+ //((SmoothCanvas) canvas).render();
322
+ //}
323
+ //});
324
+
325
+ if (useStrategy) {
326
+ // Not necessary to be on the EDT to update BufferStrategy
327
+ //((SmoothCanvas) canvas).render();
328
+ render();
329
+ } else {
330
+ if (graphics.image != null) {
331
+ BufferedImage graphicsImage = (BufferedImage) graphics.image;
332
+ if (offscreen == null ||
333
+ offscreen.getWidth() != graphicsImage.getWidth() ||
334
+ offscreen.getHeight() != graphicsImage.getHeight()) {
335
+ System.out.println("creating new image");
336
+ offscreen = (BufferedImage)
337
+ canvas.createImage(graphicsImage.getWidth(),
338
+ graphicsImage.getHeight());
339
+ // off = offscreen.getGraphics();
340
+ }
341
+ // synchronized (offscreen) {
342
+ Graphics2D off = (Graphics2D) offscreen.getGraphics();
343
+ // off.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1));
344
+ off.drawImage(graphicsImage, 0, 0, null);
345
+ // }
346
+ off.dispose();
347
+ synchronized (offscreenLock) {
348
+ BufferedImage temp = onscreen;
349
+ onscreen = offscreen;
350
+ offscreen = temp;
351
+ }
352
+ canvas.repaint();
353
+ }
354
+ }
355
+ }
356
+ */
357
+
358
+
359
+ // what needs to happen here?
360
+ @Override
361
+ public void initOffscreen(PApplet sketch) {
362
+ this.sketch = sketch;
363
+ }
364
+
365
+ /*
366
+ public Frame initOffscreen() {
367
+ Frame dummy = new Frame();
368
+ dummy.pack(); // get legit AWT graphics
369
+ // but don't show it
370
+ return dummy;
371
+ }
372
+ */
373
+
374
+ /*
375
+ @Override
376
+ public Component initComponent(PApplet sketch) {
377
+ this.sketch = sketch;
378
+
379
+ // needed for getPreferredSize() et al
380
+ sketchWidth = sketch.sketchWidth();
381
+ sketchHeight = sketch.sketchHeight();
382
+
383
+ return canvas;
384
+ }
385
+ */
386
+
387
+
388
+ @Override
389
+ public void initFrame(final PApplet sketch) {/*, int backgroundColor,
390
+ int deviceIndex, boolean fullScreen, boolean spanDisplays) {*/
391
+ this.sketch = sketch;
392
+
393
+ GraphicsEnvironment environment =
394
+ GraphicsEnvironment.getLocalGraphicsEnvironment();
395
+
396
+ int displayNum = sketch.sketchDisplay();
397
+ // System.out.println("display from sketch is " + displayNum);
398
+ if (displayNum > 0) { // if -1, use the default device
399
+ GraphicsDevice[] devices = environment.getScreenDevices();
400
+ if (displayNum <= devices.length) {
401
+ displayDevice = devices[displayNum - 1];
402
+ } else {
403
+ System.err.format("Display %d does not exist, " +
404
+ "using the default display instead.%n", displayNum);
405
+ for (int i = 0; i < devices.length; i++) {
406
+ System.err.format("Display %d is %s%n", (i+1), devices[i]);
407
+ }
408
+ }
409
+ }
410
+ if (displayDevice == null) {
411
+ displayDevice = environment.getDefaultScreenDevice();
412
+ }
413
+
414
+ // Need to save the window bounds at full screen,
415
+ // because pack() will cause the bounds to go to zero.
416
+ // http://dev.processing.org/bugs/show_bug.cgi?id=923
417
+ boolean spanDisplays = sketch.sketchDisplay() == PConstants.SPAN;
418
+ screenRect = spanDisplays ? getDisplaySpan() :
419
+ displayDevice.getDefaultConfiguration().getBounds();
420
+ // DisplayMode doesn't work here, because we can't get the upper-left
421
+ // corner of the display, which is important for multi-display setups.
422
+
423
+ // Set the displayWidth/Height variables inside PApplet, so that they're
424
+ // usable and can even be returned by the sketchWidth()/Height() methods.
425
+ sketch.displayWidth = screenRect.width;
426
+ sketch.displayHeight = screenRect.height;
427
+
428
+ windowScaleFactor = PApplet.platform == PConstants.MACOSX ?
429
+ 1 : sketch.pixelDensity;
430
+
431
+ sketchWidth = sketch.sketchWidth() * windowScaleFactor;
432
+ sketchHeight = sketch.sketchHeight() * windowScaleFactor;
433
+
434
+ boolean fullScreen = sketch.sketchFullScreen();
435
+ // Removing the section below because sometimes people want to do the
436
+ // full screen size in a window, and it also breaks insideSettings().
437
+ // With 3.x, fullScreen() is so easy, that it's just better that way.
438
+ // https://github.com/processing/processing/issues/3545
439
+ /*
440
+ // Sketch has already requested to be the same as the screen's
441
+ // width and height, so let's roll with full screen mode.
442
+ if (screenRect.width == sketchWidth &&
443
+ screenRect.height == sketchHeight) {
444
+ fullScreen = true;
445
+ sketch.fullScreen(); // won't change the renderer
446
+ }
447
+ */
448
+
449
+ if (fullScreen || spanDisplays) {
450
+ sketchWidth = screenRect.width;
451
+ sketchHeight = screenRect.height;
452
+ }
453
+
454
+ // Using a JFrame fixes a Windows problem with Present mode. This might
455
+ // be our error, but usually this is the sort of crap we usually get from
456
+ // OS X. It's time for a turnaround: Redmond is thinking different too!
457
+ // https://github.com/processing/processing/issues/1955
458
+ frame = new JFrame(displayDevice.getDefaultConfiguration());
459
+ // frame = new Frame(displayDevice.getDefaultConfiguration());
460
+ // // Default Processing gray, which will be replaced below if another
461
+ // // color is specified on the command line (i.e. in the prefs).
462
+ // ((JFrame) frame).getContentPane().setBackground(WINDOW_BGCOLOR);
463
+ // // Cannot call setResizable(false) until later due to OS X (issue #467)
464
+
465
+ // // Removed code above, also removed from what's now in the placeXxxx()
466
+ // // methods. Not sure why it was being double-set; hopefully anachronistic.
467
+ // if (backgroundColor == 0) {
468
+ // backgroundColor = WINDOW_BGCOLOR;
469
+ // }
470
+ final Color windowColor = new Color(sketch.sketchWindowColor(), false);
471
+ if (frame instanceof JFrame) {
472
+ ((JFrame) frame).getContentPane().setBackground(windowColor);
473
+ } else {
474
+ frame.setBackground(windowColor);
475
+ }
476
+
477
+ // Put the p5 logo in the Frame's corner to override the Java coffee cup.
478
+ setProcessingIcon(frame);
479
+
480
+ // For 0149, moving this code (up to the pack() method) before init().
481
+ // For OpenGL (and perhaps other renderers in the future), a peer is
482
+ // needed before a GLDrawable can be created. So pack() needs to be
483
+ // called on the Frame before applet.init(), which itself calls size(),
484
+ // and launches the Thread that will kick off setup().
485
+ // http://dev.processing.org/bugs/show_bug.cgi?id=891
486
+ // http://dev.processing.org/bugs/show_bug.cgi?id=908
487
+
488
+ frame.add(canvas);
489
+ setSize(sketchWidth / windowScaleFactor, sketchHeight / windowScaleFactor);
490
+
491
+ /*
492
+ if (fullScreen) {
493
+ // Called here because the graphics device is needed before we can
494
+ // determine whether the sketch wants size(displayWidth, displayHeight),
495
+ // and getting the graphics device will be PSurface-specific.
496
+ PApplet.hideMenuBar();
497
+
498
+ // Tried to use this to fix the 'present' mode issue.
499
+ // Did not help, and the screenRect setup seems to work fine.
500
+ //frame.setExtendedState(Frame.MAXIMIZED_BOTH);
501
+
502
+ // https://github.com/processing/processing/pull/3162
503
+ frame.dispose(); // release native resources, allows setUndecorated()
504
+ frame.setUndecorated(true);
505
+ // another duplicate?
506
+ // if (backgroundColor != null) {
507
+ // frame.getContentPane().setBackground(backgroundColor);
508
+ // }
509
+ // this may be the bounds of all screens
510
+ frame.setBounds(screenRect);
511
+ // will be set visible in placeWindow() [3.0a10]
512
+ //frame.setVisible(true); // re-add native resources
513
+ }
514
+ */
515
+ frame.setLayout(null);
516
+ //frame.add(applet);
517
+
518
+ // Need to pass back our new sketchWidth/Height here, because it may have
519
+ // been overridden by numbers we calculated above if fullScreen and/or
520
+ // spanScreens was in use.
521
+ // pg = sketch.makePrimaryGraphics(sketchWidth, sketchHeight);
522
+ // pg = sketch.makePrimaryGraphics();
523
+
524
+ // resize sketch to sketchWidth/sketchHeight here
525
+
526
+ if (fullScreen) {
527
+ frame.invalidate();
528
+ } else {
529
+ // frame.pack();
530
+ }
531
+
532
+ // insufficient, places the 100x100 sketches offset strangely
533
+ //frame.validate();
534
+
535
+ // disabling resize has to happen after pack() to avoid apparent Apple bug
536
+ // http://code.google.com/p/processing/issues/detail?id=467
537
+ frame.setResizable(false);
538
+
539
+ frame.addWindowListener(new WindowAdapter() {
540
+ @Override
541
+ public void windowClosing(WindowEvent e) {
542
+ sketch.exit(); // don't quit, need to just shut everything down (0133)
543
+ }
544
+ });
545
+
546
+ // sketch.setFrame(frame);
547
+ }
548
+
549
+
550
+ @Override
551
+ public Object getNative() {
552
+ return canvas;
553
+ }
554
+
555
+
556
+ // public Toolkit getToolkit() {
557
+ // return canvas.getToolkit();
558
+ // }
559
+
560
+
561
+ /** Set the window (and dock, or whatever necessary) title. */
562
+ @Override
563
+ public void setTitle(String title) {
564
+ frame.setTitle(title);
565
+ // Workaround for apparent Java bug on OS X?
566
+ // https://github.com/processing/processing/issues/3472
567
+ if (cursorVisible &&
568
+ (PApplet.platform == PConstants.MACOSX) &&
569
+ (cursorType != PConstants.ARROW)) {
570
+ hideCursor();
571
+ showCursor();
572
+ }
573
+ }
574
+
575
+
576
+ /** Set true if we want to resize things (default is not resizable) */
577
+ @Override
578
+ public void setResizable(boolean resizable) {
579
+ //this.resizable = resizable; // really only used for canvas
580
+
581
+ if (frame != null) {
582
+ frame.setResizable(resizable);
583
+ }
584
+ }
585
+
586
+
587
+ @Override
588
+ public void setIcon(PImage image) {
589
+ Image awtImage = (Image) image.getNative();
590
+ frame.setIconImage(awtImage);
591
+ // if (PApplet.platform != PConstants.MACOSX) {
592
+ // frame.setIconImage(awtImage);
593
+ //
594
+ // } else {
595
+ // try {
596
+ // final String td = "processing.core.ThinkDifferent";
597
+ // Class<?> thinkDifferent =
598
+ // Thread.currentThread().getContextClassLoader().loadClass(td);
599
+ // Method method =
600
+ // thinkDifferent.getMethod("setIconImage", new Class[] { java.awt.Image.class });
601
+ // method.invoke(null, new Object[] { awtImage });
602
+ // } catch (Exception e) {
603
+ // e.printStackTrace(); // That's unfortunate
604
+ // }
605
+ // }
606
+ }
607
+
608
+
609
+ @Override
610
+ public void setAlwaysOnTop(boolean always) {
611
+ frame.setAlwaysOnTop(always);
612
+ }
613
+
614
+
615
+ @Override
616
+ public void setLocation(int x, int y) {
617
+ frame.setLocation(x, y);
618
+ }
619
+
620
+
621
+ List<Image> iconImages;
622
+
623
+ protected void setProcessingIcon(Frame frame) {
624
+ // On OS X, this only affects what shows up in the dock when minimized.
625
+ // So replacing it is actually a step backwards. Brilliant.
626
+ // if (PApplet.platform != PConstants.MACOSX) {
627
+ //Image image = Toolkit.getDefaultToolkit().createImage(ICON_IMAGE);
628
+ //frame.setIconImage(image);
629
+ try {
630
+ if (iconImages == null) {
631
+ iconImages = new ArrayList<Image>();
632
+ final int[] sizes = { 16, 32, 48, 64, 128, 256, 512 };
633
+
634
+ for (int sz : sizes) {
635
+ //URL url = getClass().getResource("/icon/icon-" + sz + ".png");
636
+ URL url = PApplet.class.getResource("/icon/icon-" + sz + ".png");
637
+ Image image = Toolkit.getDefaultToolkit().getImage(url);
638
+ iconImages.add(image);
639
+ //iconImages.add(Toolkit.getLibImage("icons/pde-" + sz + ".png", frame));
640
+ }
641
+ }
642
+ frame.setIconImages(iconImages);
643
+
644
+ } catch (Exception e) { } // harmless; keep this to ourselves
645
+
646
+ // } else { // handle OS X differently
647
+ // if (!dockIconSpecified()) { // don't override existing -Xdock param
648
+ // // On OS X, set this for AWT surfaces, which handles the dock image
649
+ // // as well as the cmd-tab image that's shown. Just one size, I guess.
650
+ // URL url = PApplet.class.getResource("/icon/icon-512.png");
651
+ // // Seems dangerous to have this in code instead of using reflection, no?
652
+ // //ThinkDifferent.setIconImage(Toolkit.getDefaultToolkit().getImage(url));
653
+ // try {
654
+ // final String td = "processing.core.ThinkDifferent";
655
+ // Class<?> thinkDifferent =
656
+ // Thread.currentThread().getContextClassLoader().loadClass(td);
657
+ // Method method =
658
+ // thinkDifferent.getMethod("setIconImage", new Class[] { java.awt.Image.class });
659
+ // method.invoke(null, new Object[] { Toolkit.getDefaultToolkit().getImage(url) });
660
+ // } catch (Exception e) {
661
+ // e.printStackTrace(); // That's unfortunate
662
+ // }
663
+ // }
664
+ // }
665
+ }
666
+
667
+
668
+ /**
669
+ * @return true if -Xdock:icon was specified on the command line
670
+ */
671
+ private boolean dockIconSpecified() {
672
+ // TODO This is incomplete... Haven't yet found a way to figure out if
673
+ // the app has an icns file specified already. Help?
674
+ List<String> jvmArgs =
675
+ ManagementFactory.getRuntimeMXBean().getInputArguments();
676
+ for (String arg : jvmArgs) {
677
+ if (arg.startsWith("-Xdock:icon")) {
678
+ return true; // dock image already set
679
+ }
680
+ }
681
+ return false;
682
+ }
683
+
684
+
685
+ @Override
686
+ public void setVisible(boolean visible) {
687
+ frame.setVisible(visible);
688
+
689
+ // Generally useful whenever setting the frame visible
690
+ if (canvas != null) {
691
+ //canvas.requestFocusInWindow();
692
+ canvas.requestFocus();
693
+ }
694
+
695
+ // removing per https://github.com/processing/processing/pull/3162
696
+ // can remove the code below once 3.0a6 is tested and behaving
697
+ /*
698
+ if (visible && PApplet.platform == PConstants.LINUX) {
699
+ // Linux doesn't deal with insets the same way. We get fake insets
700
+ // earlier, and then the window manager will slap its own insets
701
+ // onto things once the frame is realized on the screen. Awzm.
702
+ if (PApplet.platform == PConstants.LINUX) {
703
+ Insets insets = frame.getInsets();
704
+ frame.setSize(Math.max(sketchWidth, MIN_WINDOW_WIDTH) +
705
+ insets.left + insets.right,
706
+ Math.max(sketchHeight, MIN_WINDOW_HEIGHT) +
707
+ insets.top + insets.bottom);
708
+ }
709
+ }
710
+ */
711
+ }
712
+
713
+
714
+ //public void placeFullScreen(boolean hideStop) {
715
+ @Override
716
+ public void placePresent(int stopColor) {
717
+ setFullFrame();
718
+
719
+ // After the pack(), the screen bounds are gonna be 0s
720
+ // frame.setBounds(screenRect); // already called in setFullFrame()
721
+ canvas.setBounds((screenRect.width - sketchWidth) / 2,
722
+ (screenRect.height - sketchHeight) / 2,
723
+ sketchWidth, sketchHeight);
724
+
725
+ // if (PApplet.platform == PConstants.MACOSX) {
726
+ // macosxFullScreenEnable(frame);
727
+ // macosxFullScreenToggle(frame);
728
+ // }
729
+
730
+ if (stopColor != 0) {
731
+ Label label = new Label("stop");
732
+ label.setForeground(new Color(stopColor, false));
733
+ label.addMouseListener(new MouseAdapter() {
734
+ @Override
735
+ public void mousePressed(java.awt.event.MouseEvent e) {
736
+ sketch.exit();
737
+ }
738
+ });
739
+ frame.add(label);
740
+
741
+ Dimension labelSize = label.getPreferredSize();
742
+ // sometimes shows up truncated on mac
743
+ //System.out.println("label width is " + labelSize.width);
744
+ labelSize = new Dimension(100, labelSize.height);
745
+ label.setSize(labelSize);
746
+ label.setLocation(20, screenRect.height - labelSize.height - 20);
747
+ }
748
+
749
+ // if (sketch.getGraphics().displayable()) {
750
+ // setVisible(true);
751
+ // }
752
+ }
753
+
754
+
755
+ /*
756
+ @Override
757
+ public void placeWindow(int[] location) {
758
+ setFrameSize(); //sketchWidth, sketchHeight);
759
+
760
+ if (location != null) {
761
+ // a specific location was received from the Runner
762
+ // (applet has been run more than once, user placed window)
763
+ frame.setLocation(location[0], location[1]);
764
+
765
+ } else { // just center on screen
766
+ // Can't use frame.setLocationRelativeTo(null) because it sends the
767
+ // frame to the main display, which undermines the --display setting.
768
+ frame.setLocation(screenRect.x + (screenRect.width - sketchWidth) / 2,
769
+ screenRect.y + (screenRect.height - sketchHeight) / 2);
770
+ }
771
+ Point frameLoc = frame.getLocation();
772
+ if (frameLoc.y < 0) {
773
+ // Windows actually allows you to place frames where they can't be
774
+ // closed. Awesome. http://dev.processing.org/bugs/show_bug.cgi?id=1508
775
+ frame.setLocation(frameLoc.x, 30);
776
+ }
777
+
778
+ // if (backgroundColor != null) {
779
+ // ((JFrame) frame).getContentPane().setBackground(backgroundColor);
780
+ // }
781
+
782
+ setCanvasSize(); //sketchWidth, sketchHeight);
783
+
784
+ frame.addWindowListener(new WindowAdapter() {
785
+ @Override
786
+ public void windowClosing(WindowEvent e) {
787
+ System.exit(0);
788
+ }
789
+ });
790
+
791
+ // handle frame resizing events
792
+ setupFrameResizeListener();
793
+
794
+ // all set for rockin
795
+ if (sketch.getGraphics().displayable()) {
796
+ frame.setVisible(true);
797
+ }
798
+ }
799
+ */
800
+
801
+
802
+ private void setCanvasSize() {
803
+ // System.out.format("setting canvas size %d %d%n", sketchWidth, sketchHeight);
804
+ // new Exception().printStackTrace(System.out);
805
+ int contentW = Math.max(sketchWidth, MIN_WINDOW_WIDTH);
806
+ int contentH = Math.max(sketchHeight, MIN_WINDOW_HEIGHT);
807
+
808
+ canvas.setBounds((contentW - sketchWidth)/2,
809
+ (contentH - sketchHeight)/2,
810
+ sketchWidth, sketchHeight);
811
+ }
812
+
813
+
814
+ /** Resize frame for these sketch (canvas) dimensions. */
815
+ private Dimension setFrameSize() { //int sketchWidth, int sketchHeight) {
816
+ // https://github.com/processing/processing/pull/3162
817
+ frame.addNotify(); // using instead of show() to add the peer [fry]
818
+
819
+ // System.out.format("setting frame size %d %d %n", sketchWidth, sketchHeight);
820
+ // new Exception().printStackTrace(System.out);
821
+ currentInsets = frame.getInsets();
822
+ int windowW = Math.max(sketchWidth, MIN_WINDOW_WIDTH) +
823
+ currentInsets.left + currentInsets.right;
824
+ int windowH = Math.max(sketchHeight, MIN_WINDOW_HEIGHT) +
825
+ currentInsets.top + currentInsets.bottom;
826
+ frame.setSize(windowW, windowH);
827
+ return new Dimension(windowW, windowH);
828
+ }
829
+
830
+
831
+ private void setFrameCentered() {
832
+ // Can't use frame.setLocationRelativeTo(null) because it sends the
833
+ // frame to the main display, which undermines the --display setting.
834
+ frame.setLocation(screenRect.x + (screenRect.width - sketchWidth) / 2,
835
+ screenRect.y + (screenRect.height - sketchHeight) / 2);
836
+ }
837
+
838
+
839
+ /** Hide the menu bar, make the Frame undecorated, set it to screenRect. */
840
+ private void setFullFrame() {
841
+ // Called here because the graphics device is needed before we can
842
+ // determine whether the sketch wants size(displayWidth, displayHeight),
843
+ // and getting the graphics device will be PSurface-specific.
844
+ PApplet.hideMenuBar();
845
+
846
+ // Tried to use this to fix the 'present' mode issue.
847
+ // Did not help, and the screenRect setup seems to work fine.
848
+ //frame.setExtendedState(Frame.MAXIMIZED_BOTH);
849
+
850
+ // https://github.com/processing/processing/pull/3162
851
+ //frame.dispose(); // release native resources, allows setUndecorated()
852
+ frame.removeNotify();
853
+ frame.setUndecorated(true);
854
+ frame.addNotify();
855
+
856
+ // this may be the bounds of all screens
857
+ frame.setBounds(screenRect);
858
+ // will be set visible in placeWindow() [3.0a10]
859
+ //frame.setVisible(true); // re-add native resources
860
+ }
861
+
862
+
863
+ @Override
864
+ public void placeWindow(int[] location, int[] editorLocation) {
865
+ //Dimension window = setFrameSize(sketchWidth, sketchHeight);
866
+ Dimension window = setFrameSize(); //sketchWidth, sketchHeight);
867
+
868
+ int contentW = Math.max(sketchWidth, MIN_WINDOW_WIDTH);
869
+ int contentH = Math.max(sketchHeight, MIN_WINDOW_HEIGHT);
870
+
871
+ if (sketch.sketchFullScreen()) {
872
+ setFullFrame();
873
+ }
874
+
875
+ // Ignore placement of previous window and editor when full screen
876
+ if (!sketch.sketchFullScreen()) {
877
+ if (location != null) {
878
+ // a specific location was received from the Runner
879
+ // (applet has been run more than once, user placed window)
880
+ frame.setLocation(location[0], location[1]);
881
+
882
+ } else if (editorLocation != null) {
883
+ int locationX = editorLocation[0] - 20;
884
+ int locationY = editorLocation[1];
885
+
886
+ if (locationX - window.width > 10) {
887
+ // if it fits to the left of the window
888
+ frame.setLocation(locationX - window.width, locationY);
889
+
890
+ } else { // doesn't fit
891
+ // if it fits inside the editor window,
892
+ // offset slightly from upper lefthand corner
893
+ // so that it's plunked inside the text area
894
+ //locationX = editorLocation[0] + 66;
895
+ //locationY = editorLocation[1] + 66;
896
+ locationX = (sketch.displayWidth - window.width) / 2;
897
+ locationY = (sketch.displayHeight - window.height) / 2;
898
+
899
+ /*
900
+ if ((locationX + window.width > sketch.displayWidth - 33) ||
901
+ (locationY + window.height > sketch.displayHeight - 33)) {
902
+ // otherwise center on screen
903
+ locationX = (sketch.displayWidth - window.width) / 2;
904
+ locationY = (sketch.displayHeight - window.height) / 2;
905
+ }
906
+ */
907
+ frame.setLocation(locationX, locationY);
908
+ }
909
+ } else { // just center on screen
910
+ setFrameCentered();
911
+ }
912
+ Point frameLoc = frame.getLocation();
913
+ if (frameLoc.y < 0) {
914
+ // Windows actually allows you to place frames where they can't be
915
+ // closed. Awesome. http://dev.processing.org/bugs/show_bug.cgi?id=1508
916
+ frame.setLocation(frameLoc.x, 30);
917
+ }
918
+ }
919
+
920
+ canvas.setBounds((contentW - sketchWidth)/2,
921
+ (contentH - sketchHeight)/2,
922
+ sketchWidth, sketchHeight);
923
+
924
+ // handle frame resizing events
925
+ setupFrameResizeListener();
926
+
927
+ /*
928
+ // If displayable() is false, then PSurfaceNone should be used, but...
929
+ if (sketch.getGraphics().displayable()) {
930
+ frame.setVisible(true);
931
+ // System.out.println("setting visible on EDT? " + EventQueue.isDispatchThread());
932
+ //requestFocus();
933
+ // if (canvas != null) {
934
+ // //canvas.requestFocusInWindow();
935
+ // canvas.requestFocus();
936
+ // }
937
+ }
938
+ */
939
+ // if (sketch.getGraphics().displayable()) {
940
+ // setVisible(true);
941
+ // }
942
+ }
943
+
944
+
945
+ // needs to resize the frame, which will resize the canvas, and so on...
946
+ @Override
947
+ public void setSize(int wide, int high) {
948
+ // When the surface is set to resizable via surface.setResizable(true),
949
+ // a crash may occur if the user sets the window to size zero.
950
+ // https://github.com/processing/processing/issues/5052
951
+ if (high <= 0) {
952
+ high = 1;
953
+ }
954
+ if (wide <= 0) {
955
+ wide = 1;
956
+ }
957
+
958
+ // if (PApplet.DEBUG) {
959
+ // //System.out.format("frame visible %b, setSize(%d, %d) %n", frame.isVisible(), wide, high);
960
+ // new Exception(String.format("setSize(%d, %d)", wide, high)).printStackTrace(System.out);
961
+ // }
962
+
963
+ //if (wide == sketchWidth && high == sketchHeight) { // doesn't work on launch
964
+ if (wide == sketch.width && high == sketch.height &&
965
+ (frame == null || currentInsets.equals(frame.getInsets()))) {
966
+ // if (PApplet.DEBUG) {
967
+ // new Exception("w/h unchanged " + wide + " " + high).printStackTrace(System.out);
968
+ // }
969
+ return; // unchanged, don't rebuild everything
970
+ }
971
+
972
+ sketchWidth = wide * windowScaleFactor;
973
+ sketchHeight = high * windowScaleFactor;
974
+
975
+ // canvas.setSize(wide, high);
976
+ // frame.setSize(wide, high);
977
+ if (frame != null) { // skip if just a canvas
978
+ setFrameSize(); //wide, high);
979
+ }
980
+ setCanvasSize();
981
+ // if (frame != null) {
982
+ // frame.setLocationRelativeTo(null);
983
+ // }
984
+
985
+ //initImage(graphics, wide, high);
986
+
987
+ //throw new RuntimeException("implement me, see readme.md");
988
+ sketch.setSize(wide, high);
989
+ // sketch.width = wide;
990
+ // sketch.height = high;
991
+
992
+ // set PGraphics variables for width/height/pixelWidth/pixelHeight
993
+ graphics.setSize(wide, high);
994
+ // System.out.println("out of setSize()");
995
+ }
996
+
997
+
998
+ //public void initImage(PGraphics gr, int wide, int high) {
999
+ /*
1000
+ @Override
1001
+ public void initImage(PGraphics graphics) {
1002
+ GraphicsConfiguration gc = canvas.getGraphicsConfiguration();
1003
+ // If not realized (off-screen, i.e the Color Selector Tool), gc will be null.
1004
+ if (gc == null) {
1005
+ System.err.println("GraphicsConfiguration null in initImage()");
1006
+ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
1007
+ gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
1008
+ }
1009
+
1010
+ // Formerly this was broken into separate versions based on offscreen or
1011
+ // not, but we may as well create a compatible image; it won't hurt, right?
1012
+ int wide = graphics.width * graphics.pixelFactor;
1013
+ int high = graphics.height * graphics.pixelFactor;
1014
+ graphics.image = gc.createCompatibleImage(wide, high);
1015
+ }
1016
+ */
1017
+
1018
+
1019
+ // @Override
1020
+ // public Component getComponent() {
1021
+ // return canvas;
1022
+ // }
1023
+
1024
+
1025
+ // @Override
1026
+ // public void setSmooth(int level) {
1027
+ // }
1028
+
1029
+
1030
+ /*
1031
+ private boolean checkRetina() {
1032
+ if (PApplet.platform == PConstants.MACOSX) {
1033
+ // This should probably be reset each time there's a display change.
1034
+ // A 5-minute search didn't turn up any such event in the Java 7 API.
1035
+ // Also, should we use the Toolkit associated with the editor window?
1036
+ final String javaVendor = System.getProperty("java.vendor");
1037
+ if (javaVendor.contains("Oracle")) {
1038
+ GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
1039
+ GraphicsDevice device = env.getDefaultScreenDevice();
1040
+
1041
+ try {
1042
+ Field field = device.getClass().getDeclaredField("scale");
1043
+ if (field != null) {
1044
+ field.setAccessible(true);
1045
+ Object scale = field.get(device);
1046
+
1047
+ if (scale instanceof Integer && ((Integer)scale).intValue() == 2) {
1048
+ return true;
1049
+ }
1050
+ }
1051
+ } catch (Exception ignore) { }
1052
+ }
1053
+ }
1054
+ return false;
1055
+ }
1056
+ */
1057
+
1058
+
1059
+ /** Get the bounds rectangle for all displays. */
1060
+ static Rectangle getDisplaySpan() {
1061
+ Rectangle bounds = new Rectangle();
1062
+ GraphicsEnvironment environment =
1063
+ GraphicsEnvironment.getLocalGraphicsEnvironment();
1064
+ for (GraphicsDevice device : environment.getScreenDevices()) {
1065
+ for (GraphicsConfiguration config : device.getConfigurations()) {
1066
+ Rectangle2D.union(bounds, config.getBounds(), bounds);
1067
+ }
1068
+ }
1069
+ return bounds;
1070
+ }
1071
+
1072
+
1073
+ /*
1074
+ private void checkDisplaySize() {
1075
+ if (canvas.getGraphicsConfiguration() != null) {
1076
+ GraphicsDevice displayDevice = getGraphicsConfiguration().getDevice();
1077
+
1078
+ if (displayDevice != null) {
1079
+ Rectangle screenRect =
1080
+ displayDevice.getDefaultConfiguration().getBounds();
1081
+
1082
+ displayWidth = screenRect.width;
1083
+ displayHeight = screenRect.height;
1084
+ }
1085
+ }
1086
+ }
1087
+ */
1088
+
1089
+
1090
+ /**
1091
+ * Set this sketch to communicate its state back to the PDE.
1092
+ * <p/>
1093
+ * This uses the stderr stream to write positions of the window
1094
+ * (so that it will be saved by the PDE for the next run) and
1095
+ * notify on quit. See more notes in the Worker class.
1096
+ */
1097
+ @Override
1098
+ public void setupExternalMessages() {
1099
+ frame.addComponentListener(new ComponentAdapter() {
1100
+ @Override
1101
+ public void componentMoved(ComponentEvent e) {
1102
+ Point where = ((Frame) e.getSource()).getLocation();
1103
+ sketch.frameMoved(where.x, where.y);
1104
+ }
1105
+ });
1106
+ }
1107
+
1108
+
1109
+ /**
1110
+ * Set up a listener that will fire proper component resize events
1111
+ * in cases where frame.setResizable(true) is called.
1112
+ */
1113
+ private void setupFrameResizeListener() {
1114
+ frame.addWindowStateListener(new WindowStateListener() {
1115
+ @Override
1116
+ // Detecting when the frame is resized in order to handle the frame
1117
+ // maximization bug in OSX:
1118
+ // http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8036935
1119
+ public void windowStateChanged(WindowEvent e) {
1120
+ // This seems to be firing when dragging the window on OS X
1121
+ // https://github.com/processing/processing/issues/3092
1122
+ if (Frame.MAXIMIZED_BOTH == e.getNewState()) {
1123
+ // Supposedly, sending the frame to back and then front is a
1124
+ // workaround for this bug:
1125
+ // http://stackoverflow.com/a/23897602
1126
+ // but is not working for me...
1127
+ //frame.toBack();
1128
+ //frame.toFront();
1129
+ // Packing the frame works, but that causes the window to collapse
1130
+ // on OS X when the window is dragged. Changing to addNotify() for
1131
+ // https://github.com/processing/processing/issues/3092
1132
+ //frame.pack();
1133
+ frame.addNotify();
1134
+ }
1135
+ }
1136
+ });
1137
+
1138
+ frame.addComponentListener(new ComponentAdapter() {
1139
+ @Override
1140
+ public void componentResized(ComponentEvent e) {
1141
+ // Ignore bad resize events fired during setup to fix
1142
+ // http://dev.processing.org/bugs/show_bug.cgi?id=341
1143
+ // This should also fix the blank screen on Linux bug
1144
+ // http://dev.processing.org/bugs/show_bug.cgi?id=282
1145
+ if (frame.isResizable()) {
1146
+ // might be multiple resize calls before visible (i.e. first
1147
+ // when pack() is called, then when it's resized for use).
1148
+ // ignore them because it's not the user resizing things.
1149
+ Frame farm = (Frame) e.getComponent();
1150
+ if (farm.isVisible()) {
1151
+ Dimension windowSize = farm.getSize();
1152
+ int x = farm.getX() + currentInsets.left;
1153
+ int y = farm.getY() + currentInsets.top;
1154
+
1155
+ // JFrame (unlike java.awt.Frame) doesn't include the left/top
1156
+ // insets for placement (though it does seem to need them for
1157
+ // overall size of the window. Perhaps JFrame sets its coord
1158
+ // system so that (0, 0) is always the upper-left of the content
1159
+ // area. Which seems nice, but breaks any f*ing AWT-based code.
1160
+ int w = windowSize.width - currentInsets.left - currentInsets.right;
1161
+ int h = windowSize.height - currentInsets.top - currentInsets.bottom;
1162
+ setSize(w / windowScaleFactor, h / windowScaleFactor);
1163
+
1164
+ // correct the location when inset size changes
1165
+ setLocation(x - currentInsets.left, y - currentInsets.top);
1166
+ }
1167
+ }
1168
+ }
1169
+ });
1170
+ }
1171
+
1172
+
1173
+ // /**
1174
+ // * (No longer in use) Use reflection to call
1175
+ // * <code>com.apple.eawt.FullScreenUtilities.setWindowCanFullScreen(window, true);</code>
1176
+ // */
1177
+ // static void macosxFullScreenEnable(Window window) {
1178
+ // try {
1179
+ // Class<?> util = Class.forName("com.apple.eawt.FullScreenUtilities");
1180
+ // Class params[] = new Class[] { Window.class, Boolean.TYPE };
1181
+ // Method method = util.getMethod("setWindowCanFullScreen", params);
1182
+ // method.invoke(util, window, true);
1183
+ //
1184
+ // } catch (ClassNotFoundException cnfe) {
1185
+ // // ignored
1186
+ // } catch (Exception e) {
1187
+ // e.printStackTrace();
1188
+ // }
1189
+ // }
1190
+ //
1191
+ //
1192
+ // /**
1193
+ // * (No longer in use) Use reflection to call
1194
+ // * <code>com.apple.eawt.Application.getApplication().requestToggleFullScreen(window);</code>
1195
+ // */
1196
+ // static void macosxFullScreenToggle(Window window) {
1197
+ // try {
1198
+ // Class<?> appClass = Class.forName("com.apple.eawt.Application");
1199
+ //
1200
+ // Method getAppMethod = appClass.getMethod("getApplication");
1201
+ // Object app = getAppMethod.invoke(null, new Object[0]);
1202
+ //
1203
+ // Method requestMethod =
1204
+ // appClass.getMethod("requestToggleFullScreen", Window.class);
1205
+ // requestMethod.invoke(app, window);
1206
+ //
1207
+ // } catch (ClassNotFoundException cnfe) {
1208
+ // // ignored
1209
+ // } catch (Exception e) {
1210
+ // e.printStackTrace();
1211
+ // }
1212
+ // }
1213
+
1214
+
1215
+ //////////////////////////////////////////////////////////////
1216
+
1217
+
1218
+ /*
1219
+ // disabling for now; requires Java 1.7 and "precise" semantics are odd...
1220
+ // returns 0.1 for tick-by-tick scrolling on OS X, but it's not a matter of
1221
+ // calling ceil() on the value: 1.5 goes to 1, but 2.3 goes to 2.
1222
+ // "precise" is a whole different animal, so add later API to shore that up.
1223
+ static protected Method preciseWheelMethod;
1224
+ static {
1225
+ try {
1226
+ preciseWheelMethod = MouseWheelEvent.class.getMethod("getPreciseWheelRotation", new Class[] { });
1227
+ } catch (Exception e) {
1228
+ // ignored, the method will just be set to null
1229
+ }
1230
+ }
1231
+ */
1232
+
1233
+
1234
+ /**
1235
+ * Figure out how to process a mouse event. When loop() has been
1236
+ * called, the events will be queued up until drawing is complete.
1237
+ * If noLoop() has been called, then events will happen immediately.
1238
+ */
1239
+ protected void nativeMouseEvent(java.awt.event.MouseEvent nativeEvent) {
1240
+ // the 'amount' is the number of button clicks for a click event,
1241
+ // or the number of steps/clicks on the wheel for a mouse wheel event.
1242
+ int peCount = nativeEvent.getClickCount();
1243
+
1244
+ int peAction = 0;
1245
+ switch (nativeEvent.getID()) {
1246
+ case java.awt.event.MouseEvent.MOUSE_PRESSED:
1247
+ peAction = MouseEvent.PRESS;
1248
+ break;
1249
+ case java.awt.event.MouseEvent.MOUSE_RELEASED:
1250
+ peAction = MouseEvent.RELEASE;
1251
+ break;
1252
+ case java.awt.event.MouseEvent.MOUSE_CLICKED:
1253
+ peAction = MouseEvent.CLICK;
1254
+ break;
1255
+ case java.awt.event.MouseEvent.MOUSE_DRAGGED:
1256
+ peAction = MouseEvent.DRAG;
1257
+ break;
1258
+ case java.awt.event.MouseEvent.MOUSE_MOVED:
1259
+ peAction = MouseEvent.MOVE;
1260
+ break;
1261
+ case java.awt.event.MouseEvent.MOUSE_ENTERED:
1262
+ peAction = MouseEvent.ENTER;
1263
+ break;
1264
+ case java.awt.event.MouseEvent.MOUSE_EXITED:
1265
+ peAction = MouseEvent.EXIT;
1266
+ break;
1267
+ //case java.awt.event.MouseWheelEvent.WHEEL_UNIT_SCROLL:
1268
+ case java.awt.event.MouseEvent.MOUSE_WHEEL:
1269
+ peAction = MouseEvent.WHEEL;
1270
+ /*
1271
+ if (preciseWheelMethod != null) {
1272
+ try {
1273
+ peAmount = ((Double) preciseWheelMethod.invoke(nativeEvent, (Object[]) null)).floatValue();
1274
+ } catch (Exception e) {
1275
+ preciseWheelMethod = null;
1276
+ }
1277
+ }
1278
+ */
1279
+ peCount = ((MouseWheelEvent) nativeEvent).getWheelRotation();
1280
+ break;
1281
+ }
1282
+
1283
+ //System.out.println(nativeEvent);
1284
+ //int modifiers = nativeEvent.getModifiersEx();
1285
+ // If using getModifiersEx(), the regular modifiers don't set properly.
1286
+ int modifiers = nativeEvent.getModifiers();
1287
+
1288
+ int peModifiers = modifiers &
1289
+ (InputEvent.SHIFT_MASK |
1290
+ InputEvent.CTRL_MASK |
1291
+ InputEvent.META_MASK |
1292
+ InputEvent.ALT_MASK);
1293
+
1294
+ // Windows and OS X seem to disagree on how to handle this. Windows only
1295
+ // sets BUTTON1_DOWN_MASK, while OS X seems to set BUTTON1_MASK.
1296
+ // This is an issue in particular with mouse release events:
1297
+ // http://code.google.com/p/processing/issues/detail?id=1294
1298
+ // The fix for which led to a regression (fixed here by checking both):
1299
+ // http://code.google.com/p/processing/issues/detail?id=1332
1300
+ int peButton = 0;
1301
+ // if ((modifiers & InputEvent.BUTTON1_MASK) != 0 ||
1302
+ // (modifiers & InputEvent.BUTTON1_DOWN_MASK) != 0) {
1303
+ // peButton = LEFT;
1304
+ // } else if ((modifiers & InputEvent.BUTTON2_MASK) != 0 ||
1305
+ // (modifiers & InputEvent.BUTTON2_DOWN_MASK) != 0) {
1306
+ // peButton = CENTER;
1307
+ // } else if ((modifiers & InputEvent.BUTTON3_MASK) != 0 ||
1308
+ // (modifiers & InputEvent.BUTTON3_DOWN_MASK) != 0) {
1309
+ // peButton = RIGHT;
1310
+ // }
1311
+ if ((modifiers & InputEvent.BUTTON1_MASK) != 0) {
1312
+ peButton = PConstants.LEFT;
1313
+ } else if ((modifiers & InputEvent.BUTTON2_MASK) != 0) {
1314
+ peButton = PConstants.CENTER;
1315
+ } else if ((modifiers & InputEvent.BUTTON3_MASK) != 0) {
1316
+ peButton = PConstants.RIGHT;
1317
+ }
1318
+
1319
+ // If running on Mac OS, allow ctrl-click as right mouse. Prior to 0215,
1320
+ // this used isPopupTrigger() on the native event, but that doesn't work
1321
+ // for mouseClicked and mouseReleased (or others).
1322
+ if (PApplet.platform == PConstants.MACOSX) {
1323
+ //if (nativeEvent.isPopupTrigger()) {
1324
+ if ((modifiers & InputEvent.CTRL_MASK) != 0) {
1325
+ peButton = PConstants.RIGHT;
1326
+ }
1327
+ }
1328
+
1329
+ sketch.postEvent(new MouseEvent(nativeEvent, nativeEvent.getWhen(),
1330
+ peAction, peModifiers,
1331
+ nativeEvent.getX() / windowScaleFactor,
1332
+ nativeEvent.getY() / windowScaleFactor,
1333
+ peButton,
1334
+ peCount));
1335
+ }
1336
+
1337
+
1338
+ protected void nativeKeyEvent(java.awt.event.KeyEvent event) {
1339
+ int peAction = 0;
1340
+ switch (event.getID()) {
1341
+ case java.awt.event.KeyEvent.KEY_PRESSED:
1342
+ peAction = KeyEvent.PRESS;
1343
+ break;
1344
+ case java.awt.event.KeyEvent.KEY_RELEASED:
1345
+ peAction = KeyEvent.RELEASE;
1346
+ break;
1347
+ case java.awt.event.KeyEvent.KEY_TYPED:
1348
+ peAction = KeyEvent.TYPE;
1349
+ break;
1350
+ }
1351
+
1352
+ // int peModifiers = event.getModifiersEx() &
1353
+ // (InputEvent.SHIFT_DOWN_MASK |
1354
+ // InputEvent.CTRL_DOWN_MASK |
1355
+ // InputEvent.META_DOWN_MASK |
1356
+ // InputEvent.ALT_DOWN_MASK);
1357
+ int peModifiers = event.getModifiers() &
1358
+ (InputEvent.SHIFT_MASK |
1359
+ InputEvent.CTRL_MASK |
1360
+ InputEvent.META_MASK |
1361
+ InputEvent.ALT_MASK);
1362
+
1363
+ sketch.postEvent(new KeyEvent(event, event.getWhen(),
1364
+ peAction, peModifiers,
1365
+ event.getKeyChar(), event.getKeyCode()));
1366
+ }
1367
+
1368
+
1369
+ // listeners, for all my men!
1370
+ protected void addListeners() {
1371
+
1372
+ canvas.addMouseListener(new MouseListener() {
1373
+
1374
+ public void mousePressed(java.awt.event.MouseEvent e) {
1375
+ nativeMouseEvent(e);
1376
+ }
1377
+
1378
+ public void mouseReleased(java.awt.event.MouseEvent e) {
1379
+ nativeMouseEvent(e);
1380
+ }
1381
+
1382
+ public void mouseClicked(java.awt.event.MouseEvent e) {
1383
+ nativeMouseEvent(e);
1384
+ }
1385
+
1386
+ public void mouseEntered(java.awt.event.MouseEvent e) {
1387
+ nativeMouseEvent(e);
1388
+ }
1389
+
1390
+ public void mouseExited(java.awt.event.MouseEvent e) {
1391
+ nativeMouseEvent(e);
1392
+ }
1393
+ });
1394
+
1395
+ canvas.addMouseMotionListener(new MouseMotionListener() {
1396
+
1397
+ public void mouseDragged(java.awt.event.MouseEvent e) {
1398
+ nativeMouseEvent(e);
1399
+ }
1400
+
1401
+ public void mouseMoved(java.awt.event.MouseEvent e) {
1402
+ nativeMouseEvent(e);
1403
+ }
1404
+ });
1405
+
1406
+ canvas.addMouseWheelListener(new MouseWheelListener() {
1407
+
1408
+ public void mouseWheelMoved(MouseWheelEvent e) {
1409
+ nativeMouseEvent(e);
1410
+ }
1411
+ });
1412
+
1413
+ canvas.addKeyListener(new KeyListener() {
1414
+
1415
+ public void keyPressed(java.awt.event.KeyEvent e) {
1416
+ nativeKeyEvent(e);
1417
+ }
1418
+
1419
+
1420
+ public void keyReleased(java.awt.event.KeyEvent e) {
1421
+ nativeKeyEvent(e);
1422
+ }
1423
+
1424
+
1425
+ public void keyTyped(java.awt.event.KeyEvent e) {
1426
+ nativeKeyEvent(e);
1427
+ }
1428
+ });
1429
+
1430
+ canvas.addFocusListener(new FocusListener() {
1431
+
1432
+ public void focusGained(FocusEvent e) {
1433
+ sketch.focused = true;
1434
+ sketch.focusGained();
1435
+ }
1436
+
1437
+ public void focusLost(FocusEvent e) {
1438
+ sketch.focused = false;
1439
+ sketch.focusLost();
1440
+ }
1441
+ });
1442
+ }
1443
+
1444
+
1445
+ /*
1446
+ public void addListeners(Component comp) {
1447
+ comp.addMouseListener(this);
1448
+ comp.addMouseWheelListener(this);
1449
+ comp.addMouseMotionListener(this);
1450
+ comp.addKeyListener(this);
1451
+ comp.addFocusListener(this);
1452
+ }
1453
+
1454
+
1455
+ public void removeListeners(Component comp) {
1456
+ comp.removeMouseListener(this);
1457
+ comp.removeMouseWheelListener(this);
1458
+ comp.removeMouseMotionListener(this);
1459
+ comp.removeKeyListener(this);
1460
+ comp.removeFocusListener(this);
1461
+ }
1462
+ */
1463
+
1464
+
1465
+ // /**
1466
+ // * Call to remove, then add, listeners to a component.
1467
+ // * Avoids issues with double-adding.
1468
+ // */
1469
+ // public void updateListeners(Component comp) {
1470
+ // removeListeners(comp);
1471
+ // addListeners(comp);
1472
+ // }
1473
+
1474
+
1475
+
1476
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1477
+
1478
+
1479
+ int cursorType = PConstants.ARROW;
1480
+ boolean cursorVisible = true;
1481
+ Cursor invisibleCursor;
1482
+
1483
+
1484
+ @Override
1485
+ public void setCursor(int kind) {
1486
+ // Swap the HAND cursor because MOVE doesn't seem to be available on OS X
1487
+ // https://github.com/processing/processing/issues/2358
1488
+ if (PApplet.platform == PConstants.MACOSX && kind == PConstants.MOVE) {
1489
+ kind = PConstants.HAND;
1490
+ }
1491
+ canvas.setCursor(Cursor.getPredefinedCursor(kind));
1492
+ cursorVisible = true;
1493
+ this.cursorType = kind;
1494
+ }
1495
+
1496
+
1497
+ @Override
1498
+ public void setCursor(PImage img, int x, int y) {
1499
+ // Don't set cursorType, instead use cursorType to save the last
1500
+ // regular cursor type used for when cursor() is called.
1501
+ //cursor_type = Cursor.CUSTOM_CURSOR;
1502
+
1503
+ // this is a temporary workaround for the CHIP, will be removed
1504
+ Dimension cursorSize = Toolkit.getDefaultToolkit().getBestCursorSize(img.width, img.height);
1505
+ if (cursorSize.width == 0 || cursorSize.height == 0) {
1506
+ return;
1507
+ }
1508
+
1509
+ Cursor cursor =
1510
+ canvas.getToolkit().createCustomCursor((Image) img.getNative(),
1511
+ new Point(x, y),
1512
+ "custom");
1513
+ canvas.setCursor(cursor);
1514
+ cursorVisible = true;
1515
+ }
1516
+
1517
+
1518
+ @Override
1519
+ public void showCursor() {
1520
+ // Maybe should always set here? Seems dangerous, since it's likely that
1521
+ // Java will set the cursor to something else on its own, and the sketch
1522
+ // will be stuck b/c p5 thinks the cursor is set to one particular thing.
1523
+ if (!cursorVisible) {
1524
+ cursorVisible = true;
1525
+ canvas.setCursor(Cursor.getPredefinedCursor(cursorType));
1526
+ }
1527
+ }
1528
+
1529
+
1530
+ @Override
1531
+ public void hideCursor() {
1532
+ // Because the OS may have shown the cursor on its own,
1533
+ // don't return if 'cursorVisible' is set to true. [rev 0216]
1534
+
1535
+ if (invisibleCursor == null) {
1536
+ BufferedImage cursorImg =
1537
+ new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
1538
+ // this is a temporary workaround for the CHIP, will be removed
1539
+ Dimension cursorSize = Toolkit.getDefaultToolkit().getBestCursorSize(16, 16);
1540
+ if (cursorSize.width == 0 || cursorSize.height == 0) {
1541
+ invisibleCursor = Cursor.getDefaultCursor();
1542
+ } else {
1543
+ invisibleCursor =
1544
+ canvas.getToolkit().createCustomCursor(cursorImg, new Point(8, 8), "blank");
1545
+ }
1546
+ }
1547
+ canvas.setCursor(invisibleCursor);
1548
+ cursorVisible = false;
1549
+ }
1550
+
1551
+
1552
+ @Override
1553
+ public Thread createThread() {
1554
+ return new AnimationThread() {
1555
+ @Override
1556
+ public void callDraw() {
1557
+ sketch.handleDraw();
1558
+ render();
1559
+ }
1560
+ };
1561
+ }
1562
+
1563
+
1564
+ void debug(String format, Object ... args) {
1565
+ System.out.format(format + "%n", args);
1566
+ }
1567
+ }