8000 Merge pull request #56 from scijava/gui-improvements · scijava/script-editor@0308ae2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0308ae2

Browse files
authored
Merge pull request #56 from scijava/gui-improvements
GUI improvements
2 parents 519b346 + ee92ec4 commit 0308ae2

10 files changed

+2282
-441
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</parent>
1111

1212
<artifactId>script-editor</artifactId>
13-
<version>0.6.2-SNAPSHOT</version>
13+
<version>0.7.0-SNAPSHOT</version>
1414

1515
<name>SciJava Script Editor</name>
1616
<description>Script Editor and Interpreter for SciJava script languages.</description>

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

Lines changed: 178 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
import java.awt.Container;
3434
import java.awt.Dimension;
3535
import java.awt.Font;
36+
import java.awt.Graphics2D;
3637
import java.awt.event.ActionEvent;
38+
import java.awt.image.BufferedImage;
3739
import java.io.BufferedReader;
3840
import java.io.BufferedWriter;
3941
import java.io.File;
@@ -45,6 +47,8 @@
4547
import java.util.Collection;
4648
import java.util.List;
4749

50+
import javax.swing.ImageIcon;
51+
import javax.swing.JOptionPane;
4852
import javax.swing.JScrollPane;
4953
import javax.swing.JViewport;
5054
import javax.swing.ToolTipManager;
@@ -54,13 +58,13 @@
5458
import javax.swing.text.DefaultEditorKit;
5559

5660
import org.fife.rsta.ac.LanguageSupport;
61+
import org.fife.rsta.ac.LanguageSupportFactory;
5762
import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
5863
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
5964
import org.fife.ui.rsyntaxtextarea.Style;
6065
import org.fife.ui.rsyntaxtextarea.SyntaxScheme;
6166
import org.fife.ui.rtextarea.Gutter;
6267
import org.fife.ui.rtextarea.GutterIconInfo;
63-
import org.fife.ui.rtextarea.IconGroup;
6468
import org.fife.ui.rtextarea.RTextArea;
6569
import org.fife.ui.rtextarea.RTextScrollPane;
6670
import org.fife.ui.rtextarea.RecordableTextAction;
@@ -88,11 +92,14 @@ public class EditorPane extends RSyntaxTextArea implements DocumentListener {
8892
private long fileLastModified;
8993
private ScriptLanguage currentLanguage;
9094
private Gutter gutter;
91-
private IconGroup iconGroup;
9295
private int A3D4 modifyCount;
9396

9497
private boolean undoInProgress;
9598
private boolean redoInProgress;
99+
private boolean autoCompletionEnabled;
100+
private boolean autoCompletionJavaFallback;
101+
private boolean autoCompletionWithoutKey;
102+
private String supportStatus;
96103

97104
@Parameter
98105
Context context;
@@ -111,8 +118,19 @@ public class EditorPane extends RSyntaxTextArea implements DocumentListener {
111118
* Constructor.
112119
*/
113120
public EditorPane() {
114-
setLineWrap(false);
115-
setTabSize(8);
121+
122+
// set sensible defaults
123+
setAntiAliasingEnabled(true);
124+
setAutoIndentEnabled(true);
125+
setBracketMatchingEnabled(true);
126+
setCloseCurlyBraces(true);
127+
setCloseMarkupTags(true);
128+
setCodeFoldingEnabled(true);
129+
setShowMatchedBracketPopup(true);
130+
setClearWhitespaceLinesEnabled(false); // most folks wont't want this set?
131+
132+
// load preferences
133+
loadPreferences();
116134

117135
getActionMap()
118136
.put(DefaultEditorKit.nextWordAction, wordMovement(+1, false));
@@ -147,15 +165,39 @@ public RTextScrollPane wrappedInScrollbars() {
147165
final RTextScrollPane sp = new RTextScrollPane(this);
148166
sp.setPreferredSize(new Dimension(600, 350));
149167
sp.setIconRowHeaderEnabled(true);
150-
151168
gutter = sp.getGutter();
152-
iconGroup = new IconGroup("bullets", "images/", null, "png", null);
153-
gutter.setBookmarkIcon(iconGroup.getIcon("var"));
154169
gutter.setBookmarkingEnabled(true);
155-
170+
updateBookmarkIcon();
171+
gutter.setShowCollapsedRegionToolTips(true);
172+
gutter.setFoldIndicatorEnabled(true);
156173
return sp;
157174
}
158175

176+
protected void updateBookmarkIcon() {
177+
// this will clear existing bookmarks, so we'll need restore existing ones
178+
final GutterIconInfo[] stash = gutter.getBookmarks();
179+
gutter.setBookmarkIcon(createBookmarkIcon());
180+
try {
181+
for (final GutterIconInfo info : stash)
182+
gutter.toggleBookmark(info.getMarkedOffset());
183+
} catch (final BadLocationException ignored) {
184+
JOptionPane.showMessageDialog(this, "Some bookmarks may have been lost.", "Lost Bookmarks",
185+
JOptionPane.WARNING_MESSAGE);
186+
}
187+
}
188+
189+
private ImageIcon createBookmarkIcon() {
190+
final int size = gutter.getLineNumberFont().getSize();
191+
final BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
192+
final Graphics2D graphics = image.createGraphics();
193+
graphics.setColor(gutter.getLineNumberColor());
194+
graphics.fillRect(0, 0, size, size);
195+
graphics.setXORMode(getCurrentLineHighlightColor());
196+
graphics.drawRect(0, 0, size - 1, size - 1);
197+
image.flush();
198+
return new ImageIcon(image);
199+
}
200+
159201
/**
160202
* TODO
161203
*
@@ -509,18 +551,85 @@ protected void setLanguage(final ScriptLanguage language,
509551
setText(header += getText());
510552
}
511553

554+
String supportLevel = "SciJava supported";
512555
// try to get language support for current language, may be null.
513556
support = languageSupportService.getLanguageSupport(currentLanguage);
514557

515-
if (support != null && autoCompletionEnabled) {
558+
// that did not work. See if there is internal support for it.
559+
if (support == null) {
560+
support = LanguageSupportFactory.get().getSupportFor(styleName);
561+
supportLevel = "Legacy supported";
562+
}
563+
// that did not work, Fallback to Java
564+
if (!"None".equals(languageName) && support == null && autoCompletionJavaFallback) {
565+
support = languageSupportService.getLanguageSupport(scriptService.getLanguageByName("Java"));
566+
supportLevel = "N/A. Using Java as fallback";
567+
}
568+
if (support != null) {
< F42D /code>
569+
support.setAutoCompleteEnabled(autoCompletionEnabled);
570+
support.setAutoActivationEnabled(autoCompletionWithoutKey);
571+
support.setAutoActivationDelay(200);
516572
support.install(this);
573+
if (!autoCompletionEnabled)
574+
supportLevel += " but currently disabled\n";
575+
else {
576+
supportLevel += " triggered by Ctrl+Space";
577+
if (autoCompletionWithoutKey)
578+
supportLevel += " & auto-display ";
579+
supportLevel += "\n";
580+
}
581+
} else {
582+
supportLevel = "N/A";
517583
}
584+
supportStatus = "Active language: " + languageName + "\nAutocompletion: " + supportLevel;
585+
}
586+
587+
/**
588+
* Toggles whether auto-completion is enabled.
589+
*
590+
* @param enabled Whether auto-activation is enabled.
591+
*/
592+
public void setAutoCompletion(final boolean enabled) {
593+
autoCompletionEnabled = enabled;
594+
if (currentLanguage != null)
595+
setLanguage(currentLanguage);
518596
}
519597

520-
private boolean autoCompletionEnabled = true;
521-
public void setAutoCompletionEnabled(boolean value) {
522-
autoCompletionEnabled = value;
523-
setLanguage(currentLanguage);
598+
/**
599+
* Toggles whether auto-completion should adopt Java completions if the current
600+
* language does not support auto-completion.
601+
*
602+
* @param enabled Whether Java should be enabled as fallback language for
603+
* auto-completion
604+
*/
605+
void setFallbackAutoCompletion(final boolean value) {
606+
autoCompletionJavaFallback = value;
607+
if (autoCompletionEnabled && currentLanguage != null)
608+
setLanguage(currentLanguage);
609+
}
610+
611+
/**
612+
* Toggles whether auto-activation of auto-completion is enabled. Ignored if
613+
* auto-completion is not enabled.
614+
*
615+
* @param enabled Whether auto-activation is enabled.
616+
*/
617+
void setKeylessAutoCompletion(final boolean enabled) {
618+
autoCompletionWithoutKey = enabled;
619+
if (autoCompletionEnabled && currentLanguage != null)
620+
setLanguage(currentLanguage);
621+
}
622+
623+
public boolean isAutoCompletionEnabled() {
624+
return autoCompletionEnabled;
625+
}
626+
627+
public boolean isAutoCompletionKeyless() {
628+
return autoCompletionWithoutKey;
629+
}
630+
631+
public boolean isAutoCompletionFallbackEnabled() {
632+
return autoCompletionJavaFallback;
524633
}
525634

526635
/**
@@ -575,6 +684,12 @@ public void increaseFontSize(final float factor) {
575684
final float size = Math.max(5, font.getSize2D() * factor);
576685
setFont(font.deriveFont(size));
577686
setSyntaxScheme(scheme);
687+
// Adjust gutter size
688+
if (gutter != null) {
689+
final float lnSize = size * 0.8f;
690+
gutter.setLineNumberFont(font.deriveFont(lnSize));
691+
updateBookmarkIcon();
692+
}
578693
Component parent = getParent();
579694
if (parent instanceof JViewport) {
580695
parent = parent.getParent();
@@ -611,7 +726,8 @@ public void toggleBookmark(final int line) {
611726
}
612727
catch (final BadLocationException e) {
613728
/* ignore */
614-
log.error("Cannot toggle bookmark at this location.");
729+
JOptionPane.showMessageDialog(this, "Cannot toggle bookmark at this location.", "Error",
730+
JOptionPane.ERROR_MESSAGE);
615731
}
616732
}
617733
}
@@ -709,34 +825,69 @@ public void convertSpacesToTabs() {
709825
public static final String LINE_WRAP_PREFS = "script.editor.WrapLines";
710826
public static final String TAB_SIZE_PREFS = "script.editor.TabSize";
711827
public static final String TABS_EMULATED_PREFS = "script.editor.TabsEmulated";
828+
public static final String WHITESPACE_VISIBLE_PREFS = "script.editor.Whitespace";
829+
public static final String TABLINES_VISIBLE_PREFS = "script.editor.Tablines";
830+
public static final String THEME_PREFS = "script.editor.theme";
831+
public static final String AUTOCOMPLETE_PREFS = "script.editor.AC";
832+
public static final String AUTOCOMPLETE_KEYLESS_PREFS = "script.editor.ACNoKey";
833+
public static final String AUTOCOMPLETE_FALLBACK_PREFS = "script.editor.ACFallback";
834+
public static final String MARK_OCCURRENCES_PREFS = "script.editor.Occurrences";
712835
public static final String FOLDERS_PREFS = "script.editor.folders";
713-
714836
public static final int DEFAULT_TAB_SIZE = 4;
837+
public static final String DEFAULT_THEME = "default";
715838

716839
/**
717-
* Loads the preferences for the Tab and apply them.
840+
* Loads and applies the preferences for the tab (theme excluded).
841+
* @see TextEditor#applyTheme(String)
718842
*/
719843
public void loadPreferences() {
720-
resetTabSize();
721-
setFontSize(prefService.getFloat(getClass(), FONT_SIZE_PREFS, getFontSize()));
722-
setLineWrap(prefService.getBoolean(getClass(), LINE_WRAP_PREFS, getLineWrap()));
723-
setTabsEmulated(prefService.getBoolean(getClass(), TABS_EMULATED_PREFS,
724-
getTabsEmulated()));
844+
if (prefService == null) {
845+
setLineWrap(false);
846+
setTabSize(DEFAULT_TAB_SIZE);
847+
setLineWrap(false);
848+
setTabsEmulated(false);
849+
setPaintTabLines(false);
850+
setAutoCompletion(true);
851+
setKeylessAutoCompletion(true); // true for backwards compatibility with IJ1 macro auto-completion
852+
setFallbackAutoCompletion(false);
853+
setMarkOccurrences(false);
854+
} else {
855+
resetTabSize();
856+
setFontSize(prefService.getFloat(getClass(), FONT_SIZE_PREFS, getFontSize()));
857+
setLineWrap(prefService.getBoolean(getClass(), LINE_WRAP_PREFS, getLineWrap()));
858+
setTabsEmulated(prefService.getBoolean(getClass(), TABS_EMULATED_PREFS, getTabsEmulated()));
859+
setWhitespaceVisible(prefService.getBoolean(getClass(), WHITESPACE_VISIBLE_PREFS, isWhitespaceVisible()));
860+
setPaintTabLines(prefService.getBoolean(getClass(), TABLINES_VISIBLE_PREFS, getPaintTabLines()));
861+
setAutoCompletion(prefService.getBoolean(getClass(), AUTOCOMPLETE_PREFS, true));
862+
setKeylessAutoCompletion(prefService.getBoolean(getClass(), AUTOCOMPLETE_KEYLESS_PREFS, true)); // true for backwards compatibility with IJ1 macro
863+
setFallbackAutoCompletion(prefService.getBoolean(getClass(), AUTOCOMPLETE_FALLBACK_PREFS, false));
864+
setMarkOccurrences(prefService.getBoolean(getClass(), MARK_OCCURRENCES_PREFS, false));
865+
}
725866
}
726-
867+
868+
public String themeName() {
869+
return prefService.get(getClass(), THEME_PREFS, DEFAULT_THEME);
870+
}
871+
727872
public String loadFolders() {
728873
return prefService.get(getClass(), FOLDERS_PREFS, System.getProperty("user.home"));
729874
}
730875

731876
/**
732877
* Retrieves and saves the preferences to the persistent store
733878
*/
734-
public void savePreferences(final String top_folders) {
879+
public void savePreferences(final String top_folders, final String theme) {
735880
prefService.put(getClass(), TAB_SIZE_PREFS, getTabSize());
736881
prefService.put(getClass(), FONT_SIZE_PREFS, getFontSize());
737882
prefService.put(getClass(), LINE_WRAP_PREFS, getLineWrap());
738883
prefService.put(getClass(), TABS_EMULATED_PREFS, getTabsEmulated());
884+
prefService.put(getClass(), WHITESPACE_VISIBLE_PREFS, isWhitespaceVisible());
885+
prefService.put(getClass(), TABLINES_VISIBLE_PREFS, getPaintTabLines());
886+
prefService.put(getClass(), AUTOCOMPLETE_PREFS, isAutoCompletionEnabled());
887+
prefService.put(getClass(), AUTOCOMPLETE_KEYLESS_PREFS, isAutoCompletionKeyless());
888+
prefService.put(getClass(), AUTOCOMPLETE_FALLBACK_PREFS, isAutoCompletionFallbackEnabled());
739889
if (null != top_folders) prefService.put(getClass(), FOLDERS_PREFS, top_folders);
890+
if (null != theme) prefService.put(getClass(), THEME_PREFS, theme);
740891
}
741892

742893
/**
@@ -746,4 +897,8 @@ public void resetTabSize() {
746897
setTabSize(prefService.getInt(getClass(), TAB_SIZE_PREFS, DEFAULT_TAB_SIZE));
747898
}
748899

900+
String getSupportStatus() {
901+
return supportStatus;
902+
}
903+
749904
}

0 commit comments

Comments
 (0)
0