10000 GUI: bugfixes for conflicting shortcuts and improvements for hiDPI di… · scijava/script-editor@676b370 · GitHub
[go: up one dir, main page]

Skip to content

Commit 676b370

Browse files
committed
GUI: bugfixes for conflicting shortcuts and improvements for hiDPI displays
- Improve size of code folding icons when using large fonts (as in hiDPI screens) - Fixes for conflicting shortcuts - Misc dialog improvements - Ensure 'View' options are immediately applied to active pane
1 parent 1ebf352 commit 676b370

File tree

5 files changed

+216
-68
lines changed

5 files changed

+216
-68
lines changed

src/main/java/org/scijava/ui/swing/script/EditorPane.java

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@
3434
import java.awt.Container;
3535
import java.awt.Dimension;
3636
import java.awt.Font;
37-
import java.awt.Graphics2D;
37+
import java.awt.Toolkit;
3838
import java.awt.event.ActionEvent;
39+
import java.awt.event.KeyEvent;
3940
import java.awt.event.MouseAdapter;
4041
import java.awt.event.MouseEvent;
41-
import java.awt.image.BufferedImage;
4242
import java.io.BufferedReader;
4343
import java.io.BufferedWriter;
4444
import java.io.File;
@@ -55,7 +55,6 @@
5555
import java.util.regex.Pattern;
5656

5757
import javax.swing.Action;
58-
import javax.swing.ImageIcon;
5958
import javax.swing.JMenu;
6059
import javax.swing.JMenuItem;
6160
import javax.swing.JOptionPane;
@@ -87,6 +86,7 @@
8786
import org.fife.ui.rsyntaxtextarea.Style;
8887
import org.fife.ui.rsyntaxtextarea.SyntaxScheme;
8988
import org.fife.ui.rsyntaxtextarea.Theme;
89+
import org.fife.ui.rsyntaxtextarea.parser.TaskTagParser;
9090
import org.fife.ui.rtextarea.Gutter;
9191
import org.fife.ui.rtextarea.GutterIconInfo;
9292
import org.fife.ui.rtextarea.RTextArea;
@@ -95,7 +95,9 @@
9595
import org.fife.ui.rtextarea.RTextAreaEditorKit.InvertSelectionCaseAction;
9696
import org.fife.ui.rtextarea.RTextAreaEditorKit.LineMoveAction;
9797
import org.fife.ui.rtextarea.RTextAreaEditorKit.LowerSelectionCaseAction;
98+
import org.fife.ui.rtextarea.RTextAreaEditorKit.NextBookmarkAction;
9899
import org.fife.ui.rtextarea.RTextAreaEditorKit.TimeDateAction;
100+
import org.fife.ui.rtextarea.RTextAreaEditorKit.ToggleBookmarkAction;
99101
import org.fife.ui.rtextarea.RTextAreaEditorKit.UpperSelectionCaseAction;
100102
import org.fife.ui.rtextarea.RTextScrollPane;
101103
import org.fife.ui.rtextarea.RecordableTextAction;
@@ -184,7 +186,8 @@ public void hyperlinkUpdate(final HyperlinkEvent hle) {
184186
}
185187
}
186188
});
187-
189+
// Add support for TODO, FIXME, HACK
190+
addParser(new TaskTagParser());
188191
// load preferences
189192
loadPreferences();
190193

@@ -202,6 +205,11 @@ public void hyperlinkUpdate(final HyperlinkEvent hle) {
202205
if (getActionMap().get(RSyntaxTextAreaEditorKit.rstaCopyAsStyledTextAction) != null)
203206
getActionMap().put(RSyntaxTextAreaEditorKit.rstaCopyAsStyledTextAction, new CopyAsStyledTextAction());
204207

208+
// Fix conflicts with historical shortcuts: override defaults
209+
getActionMap().put(RTextAreaEditorKit.rtaNextBookmarkAction, new NextBookMarkActionImpl(RTextAreaEditorKit.rtaNextBookmarkAction, true));
210+
getActionMap().put(RTextAreaEditorKit.rtaPrevBookmarkAction, new NextBookMarkActionImpl(RTextAreaEditorKit.rtaPrevBookmarkAction, false));
211+
getActionMap().put(RTextAreaEditorKit.rtaToggleBookmarkAction, new ToggleBookmarkActionImpl());
212+
205213
adjustPopupMenu();
206214

207215
ToolTipManager.sharedInstance().registerComponent(this);
@@ -300,37 +308,12 @@ public RTextScrollPane wrappedInScrollbars() {
300308
sp.setIconRowHeaderEnabled(true);
301309
gutter = sp.getGutter();
302310
gutter.setBookmarkingEnabled(true);
303-
updateBookmarkIcon();
304311
gutter.setShowCollapsedRegionToolTips(true);
305312
gutter.setFoldIndicatorEnabled(true);
313+
GutterUtils.updateIcons(gutter);
306314
return sp;
307315
}
308316

309-
protected void updateBookmarkIcon() {
310-
// this will clear existing bookmarks, so we'll need restore existing ones
311-
final GutterIconInfo[] stash = gutter.getBookmarks();
312-
gutter.setBookmarkIcon(createBookmarkIcon());
313-
try {
314-
for (final GutterIconInfo info : stash)
315-
gutter.toggleBookmark(info.getMarkedOffset());
316-
} catch (final BadLocationException ignored) {
317-
JOptionPane.showMessageDialog(this, "Some bookmarks may have been lost.", "Lost Bookmarks",
318-
JOptionPane.WARNING_MESSAGE);
319-
}
320-
}
321-
322-
private ImageIcon createBookmarkIcon() {
323-
final int size = gutter.getLineNumberFont().getSize();
324-
final BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
325-
final Graphics2D graphics = image.createGraphics();
326-
graphics.setColor(gutter.getLineNumberColor());
327-
graphics.fillRect(0, 0, size, size);
328-
graphics.setXORMode(getCurrentLineHighlightColor());
329-
graphics.drawRect(0, 0, size - 1, size - 1);
330-
image.flush();
331-
return new ImageIcon(image);
332-
}
333-
334317
RecordableTextAction wordMovement(final String id, final int direction, final boolean select) {
335318
return new RecordableTextAction(id) {
336319
private static final long serialVersionUID = 1L;
@@ -690,8 +673,8 @@ protected void setLanguage(final ScriptLanguage language,
690673
}
691674

692675
if ("None".equals(languageName) ) {
693-
supportStatus = null; // no need to update console
694-
return;
676+
supportStatus = "Active language: None";
677+
return; // no need to update console any further
695678
}
696679
String supportLevel = "SciJava supported";
697680
// try to get language support for current language, may be null.
@@ -829,7 +812,7 @@ public void increaseFontSize(final float factor) {
829812
if (gutter != null) {
830813
final float lnSize = size * 0.8f;
831814
gutter.setLineNumberFont(font.deriveFont(lnSize));
832-
updateBookmarkIcon();
815+
GutterUtils.updateIcons(gutter);
833816
}
834817
Component parent = getParent();
835818
if (parent instanceof JViewport) {
@@ -1033,7 +1016,7 @@ private void applyTheme(final Theme th) throws IllegalArgumentException {
10331016
final float existingFontSize = getFontSize();
10341017
th.apply(this);
10351018
setFontSize(existingFontSize);
1036-
updateBookmarkIcon(); // update bookmark icon color
1019+
GutterUtils.updateIcons(gutter);
10371020
}
10381021

10391022
private static Theme getTheme(final String theme) throws IllegalArgumentException {
@@ -1198,6 +1181,33 @@ public String getMacroID() {
11981181

11991182
}
12001183

1184+
/** solves hot-key conflicts with historical shortcuts */
1185+
static class NextBookMarkActionImpl extends NextBookmarkAction {
1186+
private static final long serialVersionUID = 1L;
1187+
1188+
public NextBookMarkActionImpl(String name, boolean forward) {
1189+
super(name, forward);
1190+
final KeyStroke keystroke = KeyStroke.getKeyStroke(KeyEvent.VK_F2, (forward) ? 0 : ActionEvent.SHIFT_MASK);
1191+
setAccelerator(keystroke);
1192+
}
1193+
1194+
}
1195+
/** solves hot-key conflicts with historical shortcuts */
1196+
class ToggleBookmarkActionImpl extends ToggleBookmarkAction {
1197+
private static final long serialVersionUID = 1L;
1198+
1199+
public ToggleBookmarkActionImpl() {
1200+
super();
1201+
final KeyStroke keystroke = KeyStroke.getKeyStroke(KeyEvent.VK_F2, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
1202+
setAccelerator(keystroke);
1203+
}
1204+
1205+
@Override
1206+
public void actionPerformedImpl(ActionEvent e, RTextArea textArea) {
1207+
toggleBookmark();
1208+
}
1209+
}
1210+
12011211
/** Modified from DecreaseIndentAction */
12021212
static class IncreaseIndentAction extends RecordableTextAction {
12031213

src/main/java/org/scijava/ui/swing/script/ErrorParser.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,11 @@ private void parse(final String errorLog) {
172172
// Do nothing if disabled, or if only selected text was evaluated in the
173173
// script but we don't know where in the document such selection occurred
174174
if (!enabled) {
175-
abort("When Auto-imports are active errors are not tractable in the Editor");
175+
abort("Execution errors are not highlighted when auto-imports are active");
176176
return;
177177
}
178178
if (lineOffset == -1) {
179-
abort("Code selection unknown: Erros are not tractable in the Editor");
179+
abort("Code selection unknown: Erros are not highlighted in the Editor");
180180
return;
181181
}
182182
final ScriptLanguage lang = editorPane.getCurrentLanguage();
@@ -254,8 +254,11 @@ private void parseJava(final String filename, final String line, final Collectio
254254
}
255255

256256
private void abort(final String msg) {
257-
if (writer != null)
258-
writer.textArea.insert("[WARNING] " + msg + "\n", lengthOfJTextAreaWriter);
257+
if (writer != null) {
258+
String finalMsg = "[WARNING] " + msg + "\n";
259+
finalMsg += "[WARNING] Error line(s) below may not match line numbers in the editor\n";
260+
writer.textArea.insert(finalMsg, lengthOfJTextAreaWriter);
261+
}
259262
errorLines = null;
260263
}
261264

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package org.scijava.ui.swing.script;
2+
3+
import java.awt.Color;
4+
import java.awt.Component;
5+
import java.awt.Graphics;
6+
import java.awt.Graphics2D;
7+
import java.awt.image.BufferedImage;
8+
9+
import javax.swing.Icon;
10+
import javax.swing.ImageIcon;
11+
import javax.swing.text.BadLocationException;
12+
13+
import org.fife.ui.rtextarea.FoldIndicator;
14+
import org.fife.ui.rtextarea.Gutter;
15+
import org.fife.ui.rtextarea.GutterIconInfo;
16+
17+
public class GutterUtils {
18+
19+
private final Gutter gutter;
20+
21+
GutterUtils(final Gutter gutter) {
22+
this.gutter = gutter;
23+
gutter.setSpacingBetweenLineNumbersAndFoldIndicator(0);
24+
}
25+
26+
private void updateFoldIcons() {
27+
int size;
28+
try {
29+
size = (int) new FoldIndicator(null).getPreferredSize().getWidth();
30+
} catch (final Exception | Error ignored) {
31+
size = 12; // FoldIndicator#WIDTH
32+
}
33+
if (size < 8)
34+
size = 8; // the default foldicon size in FoldIndicator
35+
final int fontSize = gutter.getLineNumberFont().getSize();
36+
if (size > fontSize)
37+
size = fontSize;
38+
gutter.setFoldIcons(new FoldIcon(true, size), new FoldIcon(false, size));
39+
}
40+
41+
private ImageIcon getBookmarkIcon() {
42+
final int size = gutter.getLineNumberFont().getSize();
43+
final BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
44+
final Graphics2D graphics = image.createGraphics();
45+
graphics.setColor(gutter.getLineNumberColor());
46+
graphics.fillRect(0, 0, size, size);
47+
graphics.setXORMode(gutter.getBorderColor());
48+
graphics.drawRect(0, 0, size - 1, size - 1);
49+
image.flush();
50+
return new ImageIcon(image);
51+
}
52+
53+
private void updateBookmarkIcon() {
54+
// this will clear existing bookmarks, so we'll need restore existing ones
55+
final GutterIconInfo[] stash = gutter.getBookmarks();
56+
gutter.setBookmarkIcon(getBookmarkIcon());
57+
58+
for (final GutterIconInfo info : stash) {
59+
try {
60+
gutter.toggleBookmark(info.getMarkedOffset());
61+
} catch (final BadLocationException ignored) {
62+
// do nothing
63+
}
64+
}
65+
}
66+
67+
public static void updateIcons(final Gutter gutter) {
68+
final GutterUtils utils = new GutterUtils(gutter);
69+
utils.updateFoldIcons();
70+
utils.updateBookmarkIcon();
71+
}
72+
73+
private class FoldIcon implements Icon {
74+
75+
private final boolean collapsed;
76+
private final Color background;
77+
private final Color foreground;
78+
private final int size;
79+
80+
FoldIcon(final boolean collapsed, final int size) {
81+
this.collapsed = collapsed;
82+
this.background = gutter.getBorderColor();
83+
this.foreground = gutter.getActiveLineRangeColor();
84+
this.size = size;
85+
}
86+
87+
@Override
88+
public int getIconHeight() {
89+
return size;
90+
}
91+
92+
@Override
93+
public int getIconWidth() {
94+
return size;
95+
}
96+
97+
@Override
98+
public void paintIcon(final Component c, final Graphics g, final int x, final int y) {
99+
g.setColor(background);
100+
g.fillRect(x, y, size, size);
101+
g.setColor(foreground);
102+
g.drawRect(x, y, size, size);
103+
g.drawLine(x + 2, y + size / 2, x + 2 + size / 2, y + size / 2);
104+
if (collapsed) {
105+
g.drawLine(x + size / 2, y + 2, x + size / 2, y + size / 2 + 2);
106+
}
107+
}
108+
}
109+
}

0 commit comments

Comments
 (0)
0