import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.preference.IPersistentPreferenceStore;
import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.FontDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.window.DefaultToolTip;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.custom.VerifyKeyListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.ui.preferences.ScopedPreferenceStore;
+import org.simantics.scl.runtime.tuple.Tuple2;
/**
* A console with input and output area that can be embedded
*/
public abstract class AbstractCommandConsole extends Composite {
+ /**
+ * Use this option mask to hide and disable the console input field.
+ */
+ public static final int HIDE_INPUT = 1 << 0;
+
public static final String PLUGIN_ID = "org.simantics.scl.ui";
public static final int COMMAND_HISTORY_SIZE = 50;
public static final int SASH_HEIGHT = 3;
LocalResourceManager resourceManager;
-
+
+ protected final int options;
+
StyledText output;
Sash sash;
protected StyledText input;
protected Color greenColor;
protected Color redColor;
-
+ protected Font textFont;
+
ArrayList<String> commandHistory = new ArrayList<String>();
int commandHistoryPos = 0;
Shell tip = null;
Label label = null;
*/
-
- public AbstractCommandConsole(Composite parent, int style) {
- super(parent, style);
+
+ public AbstractCommandConsole(Composite parent, int style, int options) {
+ super(parent, style);
+ this.options = options;
createControl();
}
-
+
@Override
public boolean setFocus() {
- return input.setFocus();
+ return input != null ? input.setFocus() : output.setFocus();
}
-
+
protected boolean canExecuteCommand() {
return true;
}
+ private boolean hasOption(int mask) {
+ return (options & mask) != 0;
+ }
+
private void createControl() {
resourceManager = new LocalResourceManager(JFaceResources.getResources(), this);
greenColor = resourceManager.createColor(new RGB(0, 128, 0));
redColor = resourceManager.createColor(new RGB(172, 0, 0));
-
+ textFont = resourceManager.createFont( FontDescriptor.createFrom("Courier New", 12, SWT.NONE) );
+
setLayout(new FormLayout());
-
- Font textFont = new Font(getDisplay(),"Courier New",12,SWT.NONE);
// Sash
sash = new Sash(this, /*SWT.BORDER |*/ SWT.HORIZONTAL);
// Upper
output = new StyledText(this, SWT.MULTI /*| SWT.READ_ONLY*/ | SWT.V_SCROLL | SWT.H_SCROLL);
output.setFont(textFont);
- {
- FormData formData = new FormData();
- formData.top = new FormAttachment(0);
- formData.bottom = new FormAttachment(sash);
- formData.left = new FormAttachment(0);
- formData.right = new FormAttachment(100);
- output.setLayoutData(formData);
- }
+ output.setLayoutData( formData(0, sash, 0, 100) );
output.addVerifyListener(new VerifyListener() {
@Override
public void verifyText(VerifyEvent e) {
if(outputModiLock)
return;
- input.append(e.text);
- input.setFocus();
- input.setCaretOffset(input.getText().length());
+ if (input != null) {
+ input.append(e.text);
+ input.setFocus();
+ input.setCaretOffset(input.getText().length());
+ }
e.doit = false;
}
});
- // Deco
- StyledText deco = new StyledText(this, SWT.MULTI | SWT.READ_ONLY);
+ if (hasOption(HIDE_INPUT)) {
+ sash.setLayoutData( formData(new Tuple2(100, 0), null, 0, 100, 0) );
+ layout(true);
+ } else {
+ createInputArea();
+ }
+
+ readPreferences();
+
+ addListener(SWT.Dispose, event -> {
+ try {
+ writePreferences();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ });
+ }
+
+ protected void createInputArea() {
+ // "> " Decoration
+ StyledText deco = new StyledText(this, SWT.MULTI | SWT.READ_ONLY);
deco.setFont(textFont);
deco.setEnabled(false);
GC gc = new GC(deco);
int inputLeftPos = gc.getFontMetrics().getAverageCharWidth()*2;
+ gc.dispose();
deco.setText(">");
- {
- FormData formData = new FormData();
- formData.top = new FormAttachment(sash);
- formData.bottom = new FormAttachment(100);
- formData.left = new FormAttachment(0);
- formData.right = new FormAttachment(0, inputLeftPos);
- deco.setLayoutData(formData);
- }
-
- // Input area
- input = new StyledText(this, SWT.MULTI);
+ deco.setLayoutData( formData(sash, 100, 0, new Tuple2(0, inputLeftPos)) );
+
+ // Input area
+ input = new StyledText(this, SWT.MULTI);
input.setFont(textFont);
- {
- FormData formData = new FormData();
- formData.top = new FormAttachment(sash);
- formData.bottom = new FormAttachment(100);
- formData.left = new FormAttachment(0, inputLeftPos);
- formData.right = new FormAttachment(100);
- input.setLayoutData(formData);
- }
+ input.setLayoutData( formData(sash, 100, new Tuple2(0, inputLeftPos), 100) );
adjustInputSize("");
- input.addVerifyKeyListener(new VerifyKeyListener() {
-
- @Override
- public void verifyKey(VerifyEvent event) {
- switch(event.keyCode) {
- case SWT.KEYPAD_CR:
- case SWT.CR:
- if((event.stateMask & SWT.CTRL) == 0) {
- if(canExecuteCommand())
- execute();
- event.doit = false;
+ input.addVerifyKeyListener(event -> {
+ switch(event.keyCode) {
+ case SWT.KEYPAD_CR:
+ case SWT.CR:
+ if((event.stateMask & SWT.CTRL) == 0) {
+ if(canExecuteCommand())
+ execute();
+ event.doit = false;
+ }
+ break;
+ case SWT.ARROW_UP:
+ case SWT.ARROW_DOWN:
+ if((event.stateMask & SWT.CTRL) != 0) {
+ int targetHistoryPos = commandHistoryPos;
+ if(event.keyCode == SWT.ARROW_UP) {
+ if(commandHistoryPos <= 0)
+ return;
+ --targetHistoryPos;
}
- break;
- case SWT.ARROW_UP:
- case SWT.ARROW_DOWN:
- if((event.stateMask & SWT.CTRL) != 0) {
- int targetHistoryPos = commandHistoryPos;
- if(event.keyCode == SWT.ARROW_UP) {
- if(commandHistoryPos <= 0)
- return;
- --targetHistoryPos;
- }
- else {
- if(commandHistoryPos >= commandHistory.size()-1)
- return;
- ++targetHistoryPos;
- }
- setInputText(commandHistory.get(targetHistoryPos));
- commandHistoryPos = targetHistoryPos;
- event.doit = false;
+ else {
+ if(commandHistoryPos >= commandHistory.size()-1)
+ return;
+ ++targetHistoryPos;
}
- break;
-// case SWT.ESC:
-// setInputText("");
-// commandHistoryPos = commandHistory.size();
-// break;
- }
- }
-
- });
- input.addVerifyListener(new VerifyListener() {
- @Override
- public void verifyText(VerifyEvent e) {
- if(e.text.contains("\n")) {
- int lineId = input.getLineAtOffset(e.start);
- int lineOffset = input.getOffsetAtLine(lineId);
- int indentAmount;
- for(indentAmount=0;
- lineOffset+indentAmount < input.getCharCount() &&
- input.getTextRange(lineOffset+indentAmount, 1).equals(" ");
- ++indentAmount);
- StringBuilder indent = new StringBuilder();
- indent.append('\n');
- for(int i=0;i<indentAmount;++i)
- indent.append(' ');
- e.text = e.text.replace("\n", indent);
+ setInputText(commandHistory.get(targetHistoryPos));
+ commandHistoryPos = targetHistoryPos;
+ event.doit = false;
}
+ break;
+// case SWT.ESC:
+// setInputText("");
+// commandHistoryPos = commandHistory.size();
+// break;
}
});
- input.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- adjustInputSize(input.getText());
- commandHistoryPos = commandHistory.size();
- //asyncValidate();
+ input.addVerifyListener(e -> {
+ if(e.text.contains("\n")) {
+ int lineId = input.getLineAtOffset(e.start);
+ int lineOffset = input.getOffsetAtLine(lineId);
+ int indentAmount;
+ for(indentAmount=0;
+ lineOffset+indentAmount < input.getCharCount() &&
+ input.getTextRange(lineOffset+indentAmount, 1).equals(" ");
+ ++indentAmount);
+ StringBuilder indent = new StringBuilder();
+ indent.append('\n');
+ for(int i=0;i<indentAmount;++i)
+ indent.append(' ');
+ e.text = e.text.replace("\n", indent);
}
});
+ input.addModifyListener(e -> {
+ adjustInputSize(input.getText());
+ commandHistoryPos = commandHistory.size();
+ //asyncValidate();
+ });
Listener hoverListener = new Listener() {
DefaultToolTip toolTip = new DefaultToolTip(input, ToolTip.RECREATE, true);
toolTipVisible = false;
}
return;
- }
- }
+ }
+ }
};
input.addListener(SWT.MouseHover, hoverListener);
input.addListener(SWT.MouseMove, hoverListener);
input.addListener(SWT.MouseExit, hoverListener);
-
- readPreferences();
-
- addListener(SWT.Dispose, new Listener() {
-
- @Override
- public void handleEvent(Event event) {
- try {
- writePreferences();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- });
-
}
-
+
+ private FormData formData(Object top, Object bottom, Object left, Object right) {
+ return formData(top, bottom, left, right, null);
+ }
+
+ private FormData formData(Object top, Object bottom, Object left, Object right, Integer height) {
+ FormData d = new FormData();
+ d.top = formAttachment(top);
+ d.bottom = formAttachment(bottom);
+ d.left = formAttachment(left);
+ d.right = formAttachment(right);
+ d.height = height != null ? (Integer) height : SWT.DEFAULT;
+ return d;
+ }
+
+ private FormAttachment formAttachment(Object o) {
+ if (o == null)
+ return null;
+ if (o instanceof Control)
+ return new FormAttachment((Control) o);
+ if (o instanceof Integer)
+ return new FormAttachment((Integer) o);
+ if (o instanceof Tuple2) {
+ Tuple2 t = (Tuple2) o;
+ return new FormAttachment((Integer) t.c0, (Integer) t.c1);
+ }
+ throw new IllegalArgumentException("argument not supported: " + o);
+ }
+
private int getOffsetInInput(int x, int y) {
int offset;
try {
}
public void setInputText(String text) {
+ if (input == null)
+ return;
input.setText(text);
input.setCaretOffset(text.length());
adjustInputSize(text);
};
- Job preValidationJob = new Job("SCL input validation") {
+ Job preValidationJob = new Job("SCL input validation") {
@Override
protected IStatus run(IProgressMonitor monitor) {
if(!input.isDisposed()) {
- input.getDisplay().asyncExec(new Runnable() {
- @Override
- public void run() {
- if(!input.isDisposed()) {
- validatedText = input.getText();
- validationJob.setPriority(Job.BUILD);
- validationJob.schedule();
- }
- }
- });
+ input.getDisplay().asyncExec(() -> {
+ if(!input.isDisposed()) {
+ validatedText = input.getText();
+ validationJob.setPriority(Job.BUILD);
+ validationJob.schedule();
+ }
+ });
}
return Status.OK_STATUS;
}
private void setInputHeight(int inputHeight) {
- FormData formData = new FormData();
- formData.top = new FormAttachment(100, -inputHeight);
- formData.left = new FormAttachment(0);
- formData.right = new FormAttachment(100);
- formData.height = SASH_HEIGHT;
- sash.setLayoutData(formData);
+ sash.setLayoutData( formData(new Tuple2(100, -inputHeight), null, 0, 100, SASH_HEIGHT) );
AbstractCommandConsole.this.layout(true);
}
private StringBuilder outputBuffer = new StringBuilder();
private ArrayList<StyleRange> styleRanges = new ArrayList<StyleRange>();
private volatile boolean outputScheduled = false;
-
+
public void appendOutput(final String text, final Color foreground, final Color background) {
synchronized (outputBuffer) {
styleRanges.add(new StyleRange(outputBuffer.length(), text.length(), foreground, background));
outputScheduled = true;
final Display display = Display.getDefault();
if(display.isDisposed()) return;
- display.asyncExec(new Runnable() {
- @Override
- public void run() {
- if(output.isDisposed()) return;
- String outputText;
- StyleRange[] styleRangeArray;
- synchronized(outputBuffer) {
- outputScheduled = false;
-
- outputText = outputBuffer.toString();
- outputBuffer = new StringBuilder();
-
- styleRangeArray = styleRanges.toArray(new StyleRange[styleRanges.size()]);
- styleRanges.clear();
- }
- int pos = output.getCharCount();
+ display.asyncExec(() -> {
+ if(output.isDisposed()) return;
+ String outputText;
+ StyleRange[] styleRangeArray;
+ synchronized(outputBuffer) {
+ outputScheduled = false;
- outputModiLock = true;
- output.replaceTextRange(pos, 0, outputText);
- outputModiLock = false;
-
- for(StyleRange styleRange : styleRangeArray) {
- styleRange.start += pos;
- output.setStyleRange(styleRange);
- }
+ outputText = outputBuffer.toString();
+ outputBuffer = new StringBuilder();
+
+ styleRangeArray = styleRanges.toArray(new StyleRange[styleRanges.size()]);
+ styleRanges.clear();
+ }
+ int pos = output.getCharCount();
- output.setCaretOffset(output.getCharCount());
- output.showSelection();
+ outputModiLock = true;
+ output.replaceTextRange(pos, 0, outputText);
+ outputModiLock = false;
+
+ for(StyleRange styleRange : styleRangeArray) {
+ styleRange.start += pos;
+ output.setStyleRange(styleRange);
}
+
+ output.setCaretOffset(output.getCharCount());
+ output.showSelection();
});
}
}
-
- private void execute() {
+
+ private void execute() {
String command = input.getText().trim();
if(command.isEmpty())
return;
if(input.isDisposed())
return;
if(!input.getText().equals(forCommand))
- return;
+ return;
syncSetErrorAnnotations(forCommand, annotations);
}
});