Skip to content

Commit 1913987

Browse files
committed
more function moving
1 parent 3eb5ac1 commit 1913987

4 files changed

Lines changed: 275 additions & 308 deletions

File tree

app/src/processing/app/syntax/PdeTextArea.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,13 @@ public PdeTextArea(TextAreaDefaults defaults, InputHandler inputHandler,
6666
}
6767

6868

69-
public Image getGutterGradient() {
69+
@Override
70+
protected TextAreaPainter createPainter(final TextAreaDefaults defaults) {
71+
return new PdeTextAreaPainter(this, defaults);
72+
}
73+
74+
75+
public Image getGutterGradient() {
7076
return gutterGradient;
7177
}
7278

app/src/processing/app/syntax/PdeTextAreaPainter.java

Lines changed: 248 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,26 @@
2222

2323
import java.awt.Color;
2424
import java.awt.Font;
25+
import java.awt.Graphics;
26+
import java.awt.Graphics2D;
2527
import java.awt.event.MouseAdapter;
2628
import java.awt.event.MouseEvent;
29+
import java.awt.geom.GeneralPath;
30+
import java.util.List;
31+
32+
import javax.swing.text.BadLocationException;
33+
import javax.swing.text.Segment;
34+
import javax.swing.text.Utilities;
2735

2836
import processing.app.Mode;
37+
import processing.app.Problem;
2938
import processing.app.ui.Editor;
3039

3140

41+
/**
42+
* Adds support to TextAreaPainter for background colors,
43+
* and the left hand gutter area with background color and text.
44+
*/
3245
public class PdeTextAreaPainter extends TextAreaPainter {
3346
public Color errorUnderlineColor;
3447
public Color warningUnderlineColor;
@@ -87,14 +100,247 @@ public void setMode(Mode mode) {
87100
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
88101

89102

103+
/**
104+
* Paint a line. Paints the gutter (with background color and text) then the
105+
* line (background color and text).
106+
*
107+
* @param gfx the graphics context
108+
* @param tokenMarker
109+
* @param line 0-based line number
110+
* @param x horizontal position
111+
*/
112+
@Override
113+
protected void paintLine(Graphics gfx, int line, int x, TokenMarker marker) {
114+
try {
115+
// TODO This line is causing NPEs randomly ever since I added the
116+
// toggle for Java Mode/Debugger toolbar. [Manindra]
117+
super.paintLine(gfx, line, x + Editor.LEFT_GUTTER, marker);
118+
119+
} catch (Exception e) {
120+
e.printStackTrace();
121+
}
122+
123+
paintLeftGutter(gfx, line, x);
124+
paintErrorLine(gfx, line, x);
125+
}
126+
127+
128+
/**
129+
* Paints the underline for an error/warning line
130+
*/
131+
protected void paintErrorLine(Graphics gfx, int line, int x) {
132+
List<Problem> problems = getEditor().findProblems(line);
133+
for (Problem problem : problems) {
134+
int startOffset = problem.getStartOffset();
135+
int stopOffset = problem.getStopOffset();
136+
137+
int lineOffset = textArea.getLineStartOffset(line);
138+
139+
int wiggleStart = Math.max(startOffset, lineOffset);
140+
int wiggleStop = Math.min(stopOffset, textArea.getLineStopOffset(line));
141+
142+
int y = textArea.lineToY(line) + fm.getLeading() + fm.getMaxDescent();
143+
144+
try {
145+
String badCode = null;
146+
String goodCode = null;
147+
try {
148+
SyntaxDocument doc = textArea.getDocument();
149+
badCode = doc.getText(wiggleStart, wiggleStop - wiggleStart);
150+
goodCode = doc.getText(lineOffset, wiggleStart - lineOffset);
151+
//log("paintErrorLine() LineText GC: " + goodCode);
152+
//log("paintErrorLine() LineText BC: " + badCode);
153+
} catch (BadLocationException bl) {
154+
// Error in the import statements or end of code.
155+
// System.out.print("BL caught. " + ta.getLineCount() + " ,"
156+
// + line + " ,");
157+
// log((ta.getLineStopOffset(line) - start - 1));
158+
return;
159+
}
160+
161+
int trimmedLength = badCode.trim().length();
162+
int rightTrimmedLength = trimRight(badCode).length();
163+
int leftTrimLength = rightTrimmedLength - trimmedLength;
164+
165+
// Fix offsets when bad code is just whitespace
166+
if (trimmedLength == 0) {
167+
leftTrimLength = 0;
168+
rightTrimmedLength = badCode.length();
169+
}
170+
171+
int x1 = textArea.offsetToX(line, goodCode.length() + leftTrimLength);
172+
int x2 = textArea.offsetToX(line, goodCode.length() + rightTrimmedLength);
173+
if (x1 == x2) x2 += fm.stringWidth(" ");
174+
int y1 = y + fm.getHeight() - 2;
175+
176+
if (line != problem.getLineNumber()) {
177+
x1 = Editor.LEFT_GUTTER; // on the following lines, wiggle extends to the left border
178+
}
179+
180+
gfx.setColor(errorUnderlineColor);
181+
if (problem.isWarning()) {
182+
gfx.setColor(warningUnderlineColor);
183+
}
184+
paintSquiggle(gfx, y1, x1, x2);
185+
186+
} catch (Exception e) {
187+
e.printStackTrace();
188+
}
189+
}
190+
}
191+
192+
193+
/**
194+
* Paint the gutter: draw the background, draw line numbers, break points.
195+
* @param gfx the graphics context
196+
* @param line 0-based line number
197+
* @param x horizontal position
198+
*/
199+
protected void paintLeftGutter(Graphics gfx, int line, int x) {
200+
int y = textArea.lineToY(line) + fm.getLeading() + fm.getMaxDescent();
201+
if (line == textArea.getSelectionStopLine()) {
202+
gfx.setColor(gutterLineHighlightColor);
203+
gfx.fillRect(0, y, Editor.LEFT_GUTTER, fm.getHeight());
204+
} else {
205+
//gfx.setColor(getJavaTextArea().gutterBgColor);
206+
gfx.setClip(0, y, Editor.LEFT_GUTTER, fm.getHeight());
207+
gfx.drawImage(((PdeTextArea) textArea).getGutterGradient(), 0, 0, getWidth(), getHeight(), this);
208+
gfx.setClip(null); // reset
209+
}
210+
211+
String text = null;
212+
if (getEditor().isDebuggerEnabled()) {
213+
text = getPdeTextArea().getGutterText(line);
214+
}
215+
216+
gfx.setColor(line < textArea.getLineCount() ? gutterTextColor : gutterPastColor);
217+
// if (line >= textArea.getLineCount()) {
218+
// //gfx.setColor(new Color(gutterTextColor.getRGB(), );
219+
// }
220+
int textRight = Editor.LEFT_GUTTER - Editor.GUTTER_MARGIN;
221+
int textBaseline = textArea.lineToY(line) + fm.getHeight();
222+
223+
if (text != null) {
224+
if (text.equals(PdeTextArea.BREAK_MARKER)) {
225+
drawDiamond(gfx, textRight - 8, textBaseline - 8, 8, 8);
226+
227+
} else if (text.equals(PdeTextArea.STEP_MARKER)) {
228+
//drawRightArrow(gfx, textRight - 7, textBaseline - 7, 7, 6);
229+
drawRightArrow(gfx, textRight - 7, textBaseline - 7.5f, 7, 7);
230+
}
231+
} else {
232+
// if no special text for a breakpoint, just show the line number
233+
text = String.valueOf(line + 1);
234+
//text = makeOSF(String.valueOf(line + 1));
235+
236+
gfx.setFont(gutterTextFont);
237+
// ((Graphics2D) gfx).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
238+
// RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
239+
// Right-align the text
240+
char[] txt = text.toCharArray();
241+
int tx = textRight - gfx.getFontMetrics().charsWidth(txt, 0, txt.length);
242+
// Using 'fm' here because it's relative to the editor text size,
243+
// not the numbers in the gutter
244+
Utilities.drawTabbedText(new Segment(txt, 0, text.length()),
245+
tx, textBaseline, gfx, this, 0);
246+
}
247+
}
248+
249+
250+
static private void drawDiamond(Graphics g,
251+
float x, float y, float w, float h) {
252+
Graphics2D g2 = (Graphics2D) g;
253+
GeneralPath path = new GeneralPath();
254+
path.moveTo(x + w/2, y);
255+
path.lineTo(x + w, y + h/2);
256+
path.lineTo(x + w/2, y + h);
257+
path.lineTo(x, y + h/2);
258+
path.closePath();
259+
g2.fill(path);
260+
}
261+
262+
263+
static private void drawRightArrow(Graphics g,
264+
float x, float y, float w, float h) {
265+
Graphics2D g2 = (Graphics2D) g;
266+
GeneralPath path = new GeneralPath();
267+
path.moveTo(x, y);
268+
path.lineTo(x + w, y + h/2);
269+
path.lineTo(x, y + h);
270+
path.closePath();
271+
g2.fill(path);
272+
}
273+
274+
275+
/**
276+
* Remove all trailing whitespace from a line
277+
*/
278+
static private String trimRight(String str) {
279+
int i = str.length() - 1;
280+
while (i >= 0 && Character.isWhitespace(str.charAt(i))) {
281+
i--;
282+
}
283+
return str.substring(0, i+1);
284+
}
285+
286+
287+
static private void paintSquiggle(Graphics g, int y, int x1, int x2) {
288+
int xx = x1;
289+
290+
while (xx < x2) {
291+
g.drawLine(xx, y, xx + 2, y + 1);
292+
xx += 2;
293+
g.drawLine(xx, y + 1, xx + 2, y);
294+
xx += 2;
295+
}
296+
}
297+
298+
299+
@Override
300+
public String getToolTipText(MouseEvent event) {
301+
int line = event.getY() / getFontMetrics().getHeight() + textArea.getFirstLine();
302+
if (line >= 0 || line < textArea.getLineCount()) {
303+
List<Problem> problems = getEditor().findProblems(line);
304+
for (Problem problem : problems) {
305+
int lineStart = textArea.getLineStartOffset(line);
306+
int lineEnd = textArea.getLineStopOffset(line);
307+
308+
int errorStart = problem.getStartOffset();
309+
int errorEnd = problem.getStopOffset() + 1;
310+
311+
int startOffset = Math.max(errorStart, lineStart) - lineStart;
312+
int stopOffset = Math.min(errorEnd, lineEnd) - lineStart;
313+
314+
int x = event.getX();
315+
316+
if (x >= textArea.offsetToX(line, startOffset) &&
317+
x <= textArea.offsetToX(line, stopOffset)) {
318+
getEditor().statusToolTip(this, problem.getMessage(), problem.isError());
319+
return super.getToolTipText(event);
320+
}
321+
}
322+
}
323+
setToolTipText(null);
324+
return super.getToolTipText(event);
325+
}
326+
327+
328+
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
329+
330+
90331
@Override
91332
public int getScrollWidth() {
92-
// https://github.com/processing/processing/issues/3591
333+
// TODO https://github.com/processing/processing/issues/3591
93334
return super.getWidth() - Editor.LEFT_GUTTER;
94335
}
95336

96337

97338
public Editor getEditor() {
98-
return ((PdeTextArea) textArea).editor;
339+
return getPdeTextArea().editor;
340+
}
341+
342+
343+
public PdeTextArea getPdeTextArea() {
344+
return (PdeTextArea) textArea;
99345
}
100346
}

java/src/processing/mode/java/pdex/JavaTextArea.java

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,11 @@
4545
import processing.mode.java.tweak.Handle;
4646

4747

48+
/**
49+
* TextArea implementation for Java Mode. Primary differences from PdeTextArea
50+
* are completions, suggestions, and tweak handling.
51+
*/
4852
public class JavaTextArea extends PdeTextArea {
49-
//protected final JavaEditor editor;
50-
5153
private CompletionPanel suggestion;
5254

5355

@@ -79,6 +81,8 @@ protected JavaTextAreaPainter getJavaPainter() {
7981

8082
/**
8183
* Handles KeyEvents for TextArea (code completion begins from here).
84+
* TODO Needs explanation of why this implemented with an override
85+
* of processKeyEvent() instead of using listeners.
8286
*/
8387
@Override
8488
public void processKeyEvent(KeyEvent evt) {
@@ -234,7 +238,6 @@ private void prepareSuggestions(final KeyEvent evt) {
234238
* @param evt - the KeyEvent which triggered this method
235239
*/
236240
protected void fetchPhrase() {
237-
238241
if (suggestionRunning) {
239242
suggestionRequested = true;
240243
return;
@@ -345,8 +348,8 @@ protected void fetchPhrase() {
345348
});
346349
}
347350

348-
protected static String parsePhrase(final String lineText) {
349351

352+
protected static String parsePhrase(final String lineText) {
350353
boolean overloading = false;
351354

352355
{ // Check if we can provide suggestions for this phrase ending
@@ -505,25 +508,10 @@ protected static String parsePhrase(final String lineText) {
505508
if (phrase.length() == 0 || Character.isDigit(phrase.charAt(0))) {
506509
return null; // Can't suggest for numbers or empty phrases
507510
}
508-
509511
return phrase;
510512
}
511513

512514

513-
// appears unused, removed when looking to change completion trigger [fry 140801]
514-
/*
515-
public void showSuggestionLater(final DefaultListModel defListModel, final String word) {
516-
SwingUtilities.invokeLater(new Runnable() {
517-
@Override
518-
public void run() {
519-
showSuggestion(defListModel,word);
520-
}
521-
522-
});
523-
}
524-
*/
525-
526-
527515
/**
528516
* Calculates location of caret and displays the suggestion pop-up.
529517
*/
@@ -651,6 +639,6 @@ private void tweakRestoreBaseListeners() {
651639

652640
public void updateInterface(List<List<Handle>> handles,
653641
List<List<ColorControlBox>> colorBoxes) {
654-
getJavaPainter().updateInterface(handles, colorBoxes);
642+
getJavaPainter().updateTweakInterface(handles, colorBoxes);
655643
}
656644
}

0 commit comments

Comments
 (0)