Skip to content

Commit 848cefd

Browse files
committed
Merge branch 'master' of github.com:processing/processing
2 parents 7ae8e1a + 1e09f10 commit 848cefd

File tree

2 files changed

+138
-41
lines changed

2 files changed

+138
-41
lines changed

app/src/processing/app/ChangeDetector.java

Lines changed: 86 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package processing.app;
22

3+
import java.awt.EventQueue;
4+
import java.awt.Frame;
35
import java.awt.event.WindowEvent;
46
import java.awt.event.WindowFocusListener;
57
import java.io.File;
68
import java.io.FilenameFilter;
79
import java.io.IOException;
10+
import java.lang.reflect.InvocationTargetException;
811

912
public class ChangeDetector implements WindowFocusListener {
1013
private Sketch sketch;
@@ -46,20 +49,84 @@ public void run() {
4649
th.start();
4750
}
4851

52+
private void showErrorAsync(final String title, final String message,
53+
final Exception e) {
54+
EventQueue.invokeLater(new Runnable() {
55+
@Override
56+
public void run() {
57+
Base.showError(title, message, e);
58+
}
59+
});
60+
}
61+
62+
private void showWarningAsync(final String title, final String message) {
63+
EventQueue.invokeLater(new Runnable() {
64+
@Override
65+
public void run() {
66+
Base.showWarning(title, message);
67+
}
68+
});
69+
}
70+
71+
private void showWarningTieredAsync(final String title,
72+
final String message1,
73+
final String message2, final Exception e) {
74+
EventQueue.invokeLater(new Runnable() {
75+
@Override
76+
public void run() {
77+
Base.showWarningTiered(title, message1, message2, e);
78+
}
79+
});
80+
}
81+
82+
private int showYesNoQuestionAsync(final Frame editor, final String title,
83+
final String message1,
84+
final String message2) {
85+
final int[] res = { -1 };
86+
try {
87+
//have to wait for a response on this one
88+
EventQueue.invokeAndWait(new Runnable() {
89+
@Override
90+
public void run() {
91+
res[0] = Base.showYesNoQuestion(editor, title, message1, message2);
92+
}
93+
});
94+
} catch (InvocationTargetException e) {
95+
//occurs if Base.showYesNoQuestion throws an error, so, shouldn't happen
96+
e.printStackTrace();
97+
} catch (InterruptedException e) {
98+
//occurs if the EDT is interrupted, so, shouldn't happen
99+
e.printStackTrace();
100+
}
101+
return res[0];
102+
}
103+
104+
private void rebuildHeaderAsync() {
105+
EventQueue.invokeLater(new Runnable() {
106+
@Override
107+
public void run() {
108+
editor.header.rebuild();
109+
}
110+
});
111+
}
112+
49113
private void checkFileChange() {
50114
//check that the content of each of the files in sketch matches what is in memory
51115
if (sketch == null) {
52116
return;
53117
}
54118

119+
//make sure the sketch folder exists at all. if it does not, it will be re-saved, and no changes will be detected
120+
//
121+
sketch.ensureExistence();
55122
//check file count first
56123
File sketchFolder = sketch.getFolder();
57124
int fileCount = sketchFolder.list(new FilenameFilter() {
58125
//return true if the file is a code file for this mode
59126
@Override
60127
public boolean accept(File dir, String name) {
61128
for (String s : editor.getMode().getExtensions()) {
62-
if (name.endsWith(s)) {
129+
if (name.toLowerCase().endsWith(s.toLowerCase())) {
63130
return true;
64131
}
65132
}
@@ -68,14 +135,14 @@ public boolean accept(File dir, String name) {
68135
}).length;
69136

70137
if (fileCount != sketch.getCodeCount()) {
71-
reloadSketch(null);
72-
if (fileCount < 1) {
138+
//if they chose to reload and there aren't any files left
139+
if (reloadSketch(null) && fileCount < 1) {
73140
try {
74141
//make a blank file
75142
sketch.getMainFile().createNewFile();
76143
} catch (Exception e1) {
77144
//if that didn't work, tell them it's un-recoverable
78-
Base.showError("Reload failed", "The sketch contains no code files.",
145+
showErrorAsync("Reload failed", "The sketch contains no code files.",
79146
e1);
80147
//don't try to reload again after the double fail
81148
//this editor is probably trashed by this point, but a save-as might be possible
@@ -84,11 +151,9 @@ public boolean accept(File dir, String name) {
84151
}
85152
//it's okay to do this without confirmation, because they already confirmed to deleting the unsaved changes above
86153
sketch.reload();
87-
editor.header.rebuild();
88-
Base
89-
.showWarning("Modified Reload",
90-
"You cannot delete the last code file in a sketch.\n"
91-
+ "A new blank sketch file has been generated for you.");
154+
showWarningAsync("Modified Reload",
155+
"You cannot delete the last code file in a sketch.\n"
156+
+ "A new blank sketch file has been generated for you.");
92157

93158
}
94159
return;
@@ -108,10 +173,9 @@ public boolean accept(File dir, String name) {
108173
try {
109174
onDisk = Base.loadFile(sketchFile);
110175
} catch (IOException e1) {
111-
Base
112-
.showWarningTiered("File Change Detection Failed",
113-
"Checking for changed files for this sketch has failed.",
114-
"The file change detector will be disabled.", e1);
176+
showWarningTieredAsync("File Change Detection Failed",
177+
"Checking for changed files for this sketch has failed.",
178+
"The file change detector will be disabled.", e1);
115179
enabled = false;
116180
return;
117181
}
@@ -130,18 +194,17 @@ private void setSketchCodeModified(SketchCode sc) {
130194
}
131195

132196
//returns true if the files in the sketch have been reloaded
133-
private void reloadSketch(SketchCode changed) {
134-
int response = Base
135-
.showYesNoQuestion(editor,
136-
"File Modified",
137-
"Your sketch has been modified externally.<br>Would you like to reload the sketch?",
138-
"If you reload the sketch, any unsaved changes will be lost!");
197+
private boolean reloadSketch(SketchCode changed) {
198+
int response = showYesNoQuestionAsync(editor,
199+
"File Modified",
200+
"Your sketch has been modified externally.<br>Would you like to reload the sketch?",
201+
"If you reload the sketch, any unsaved changes will be lost!");
139202
if (response == 0) {
140203
//reload the sketch
141204

142205
sketch.reload();
143-
editor.header.rebuild();
144-
206+
rebuildHeaderAsync();
207+
return true;
145208
} else {
146209
//they said no, make it possible for them to stop the errors by saving
147210
if (changed != null) {
@@ -157,11 +220,10 @@ private void reloadSketch(SketchCode changed) {
157220
}
158221
//if files were simply added, then nothing needs done
159222
}
160-
editor.header.rebuild();
223+
rebuildHeaderAsync();
161224
skip = true;
162-
return;
225+
return false;
163226
}
164-
return;
165227
}
166228

167229
@Override

java/libraries/lwjgl/src/processing/lwjgl/PSurfaceLWJGL.java

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,9 @@
66
import java.awt.GraphicsConfiguration;
77
import java.awt.GraphicsDevice;
88
import java.awt.GraphicsEnvironment;
9-
import java.awt.Image;
10-
import java.awt.Point;
119
import java.awt.Rectangle;
12-
import java.awt.Toolkit;
1310
import java.awt.geom.Rectangle2D;
1411
import java.awt.image.BufferedImage;
15-
import java.awt.image.MemoryImageSource;
1612
import java.nio.IntBuffer;
1713

1814
import org.lwjgl.BufferUtils;
@@ -52,6 +48,7 @@ public class PSurfaceLWJGL implements PSurface {
5248
int cursorType = PConstants.ARROW; // cursor type
5349
boolean cursorVisible = true; // cursor visibility flag
5450
Cursor invisibleCursor;
51+
Cursor currentCursor;
5552

5653
// ........................................................
5754

@@ -199,15 +196,29 @@ public void setResizable(boolean resizable) {
199196

200197
@Override
201198
public void placeWindow(int[] location) {
202-
Display.setLocation(location[0], location[1]);
203-
199+
if (location != null) {
200+
// a specific location was received from the Runner
201+
// (applet has been run more than once, user placed window)
202+
Display.setLocation(location[0], location[1]);
203+
} else { // just center on screen
204+
// Can't use frame.setLocationRelativeTo(null) because it sends the
205+
// frame to the main display, which undermines the --display setting.
206+
setFrameCentered();
207+
}
204208
}
205209

206210
@Override
207211
public void placeWindow(int[] location, int[] editorLocation) {
208212
// TODO Auto-generated method stub
209213

210214
}
215+
216+
private void setFrameCentered() {
217+
// Can't use frame.setLocationRelativeTo(null) because it sends the
218+
// frame to the main display, which undermines the --display setting.
219+
Display.setLocation(screenRect.x + (screenRect.width - sketchWidth) / 2,
220+
screenRect.y + (screenRect.height - sketchHeight) / 2);
221+
}
211222

212223
@Override
213224
public void placePresent(Color stopColor) {
@@ -319,11 +330,13 @@ public void blit() {
319330

320331
@Override
321332
public void setCursor(int kind) {
333+
System.err.println("Sorry, cursor types not supported in OpenGL, provide your cursor image");
322334
// TODO Auto-generated method stub
323-
if (PApplet.platform == PConstants.MACOSX && kind == PConstants.MOVE) {
324-
kind = PConstants.HAND;
325-
}
326-
java.awt.Cursor cursor0 = java.awt.Cursor.getPredefinedCursor(kind);
335+
// if (PApplet.platform == PConstants.MACOSX && kind == PConstants.MOVE) {
336+
// kind = PConstants.HAND;
337+
// }
338+
//
339+
// java.awt.Cursor cursor0 = java.awt.Cursor.getPredefinedCursor(kind);
327340

328341

329342
// Cursor cursor1 = Cursor(cursor0.,
@@ -336,9 +349,8 @@ public void setCursor(int kind) {
336349

337350

338351
// Mouse.setNativeCursor(cursor1);
339-
cursorVisible = true;
340-
this.cursorType = kind;
341-
352+
// cursorVisible = true;
353+
// this.cursorType = kind;
342354
}
343355

344356
@Override
@@ -347,9 +359,9 @@ public void setCursor(PImage image, int hotspotX, int hotspotY) {
347359
IntBuffer buf = IntBuffer.wrap(jimg.getRGB(0, 0, jimg.getWidth(), jimg.getHeight(),
348360
null, 0, jimg.getWidth()));
349361
try {
350-
Cursor cursor = new Cursor(jimg.getWidth(), jimg.getHeight(),
362+
currentCursor = new Cursor(jimg.getWidth(), jimg.getHeight(),
351363
hotspotX, hotspotY, 1, buf, null);
352-
Mouse.setNativeCursor(cursor);
364+
Mouse.setNativeCursor(currentCursor);
353365
cursorVisible = true;
354366
} catch (LWJGLException e) {
355367
// TODO Auto-generated catch block
@@ -359,10 +371,18 @@ public void setCursor(PImage image, int hotspotX, int hotspotY) {
359371

360372
@Override
361373
public void showCursor() {
362-
// if (!cursorVisible) {
374+
if (!cursorVisible) {
375+
// setCursor(cursorType);
363376
// cursorVisible = true;
364377
// Mouse.setCursor(Cursor.getPredefinedCursor(cursorType));
365-
// }
378+
try {
379+
Mouse.setNativeCursor(currentCursor);
380+
cursorVisible = true;
381+
} catch (LWJGLException e) {
382+
// TODO Auto-generated catch block
383+
e.printStackTrace();
384+
}
385+
}
366386
}
367387

368388
@Override
@@ -426,6 +446,8 @@ public void run() { // not good to make this synchronized, locks things up
426446
mousePoller = new MousePoller(sketch);
427447
mousePoller.start();
428448

449+
System.err.println(Mouse.getNativeCursor());
450+
429451
long beforeTime = System.nanoTime();
430452
long overSleepTime = 0L;
431453

@@ -551,6 +573,12 @@ protected class KeyPoller extends Thread {
551573
KeyPoller(PApplet parent) {
552574
this.parent = parent;
553575
stopRequested = false;
576+
try {
577+
Keyboard.create();
578+
} catch (LWJGLException e) {
579+
// TODO Auto-generated catch block
580+
e.printStackTrace();
581+
}
554582
}
555583

556584
@Override
@@ -642,6 +670,13 @@ protected class MousePoller extends Thread {
642670
MousePoller(PApplet parent) {
643671
this.parent = parent;
644672
stopRequested = false;
673+
try {
674+
Mouse.create();
675+
// Mouse.setNativeCursor(null);
676+
} catch (LWJGLException e) {
677+
// TODO Auto-generated catch block
678+
e.printStackTrace();
679+
}
645680
}
646681

647682
@Override

0 commit comments

Comments
 (0)