import org.eclipse.swt.events.MouseListener;\r
import org.eclipse.swt.events.SelectionEvent;\r
import org.eclipse.swt.events.SelectionListener;\r
-import org.eclipse.swt.graphics.Font;\r
import org.eclipse.swt.graphics.Point;\r
import org.eclipse.swt.widgets.Composite;\r
import org.eclipse.swt.widgets.Label;\r
\r
public class EquationTab extends PropertyTabContributorImpl {\r
\r
- static public final Font FONT = new Font(null, "Courier New", 12, SWT.NORMAL);\r
-\r
NameWidget nameWidget;\r
ExpressionTypeWidget expressionTypeWidget;\r
UnitWidget unitWidget;\r
\r
\r
Label label = new Label(composite, SWT.SINGLE );\r
- label.setFont(EquationTab.FONT);\r
label.setText("Type:");\r
GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
\r
\r
\r
label = new Label(composite, SWT.SINGLE );\r
- label.setFont(EquationTab.FONT);\r
label.setText("Unit:");\r
GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
\r
Composite expressionComposite = new Composite(composite, SWT.NONE);\r
GridDataFactory.fillDefaults().grab(true, true).span(5, 1).applyTo(expressionComposite);\r
expressionWidget = new ExpressionWidget(expressionComposite, support, SWT.NONE);\r
-\r
+ expressionWidget.setVariableTable(shortcutTabWidget.getVariableTable());\r
+ \r
addListeners();\r
}\r
\r
\r
@Override\r
public void mouseUp(MouseEvent e) {\r
- expressionWidget.getExpression().focus();\r
}\r
\r
});\r
\r
@Override\r
public void modifyText(ModifyEvent e) {\r
- expressionWidget.validateFields(shortcutTabWidget.getVariableTable().getItems());\r
+ expressionWidget.validateFields();\r
}\r
});\r
\r
\r
@Override\r
public void focusGained(FocusEvent e) {\r
- expressionWidget.validateFields(shortcutTabWidget.getVariableTable().getItems());\r
+ expressionWidget.validateFields();\r
}\r
}); \r
}\r
import org.simantics.db.common.request.ReadRequest;\r
import org.simantics.db.exception.DatabaseException;\r
import org.simantics.sysdyn.SysdynResource;\r
-import org.simantics.sysdyn.ui.properties.EquationTab;\r
import org.simantics.sysdyn.ui.properties.widgets.ExpressionTypes.ExpressionType;\r
import org.simantics.ui.SimanticsUI;\r
import org.simantics.utils.ui.ISelectionUtils;\r
support.register(this);\r
\r
typeCombo = new Combo(parent, style);\r
- typeCombo.setFont(EquationTab.FONT);\r
\r
int columns = 6;\r
GC gc = new GC (typeCombo);\r
@Override\r
public void run(ReadGraph graph) throws DatabaseException {\r
SysdynResource sr = SysdynResource.getInstance(graph);\r
- \r
+\r
final ExpressionType[] expressionTypes;\r
if(graph.isInstanceOf(variable, sr.Auxiliary))\r
expressionTypes = ExpressionTypes.auxiliaryExpressions;\r
expressionTypes = ExpressionTypes.valveExpressions;\r
else\r
expressionTypes = new ExpressionType[] {};\r
- \r
- \r
+\r
+\r
typeCombo.getDisplay().asyncExec(new Runnable() {\r
- \r
+\r
@Override\r
public void run() {\r
- setExpressionTypes(expressionTypes);\r
- setExpressionType(et); \r
+ if(!typeCombo.isDisposed()){\r
+ setExpressionTypes(expressionTypes);\r
+ setExpressionType(et); \r
+ }\r
}\r
});\r
\r
}\r
- \r
+\r
});\r
- \r
+\r
}\r
}\r
}\r
- \r
+\r
private void setExpressionTypes(ExpressionType[] expressionTypes) {\r
if(expressionTypes != null) {\r
for(ExpressionType et : expressionTypes) {\r
typeCombo.select(index);\r
}\r
}\r
- \r
- \r
+\r
+\r
public void addSelectionListener(SelectionListener listener) {\r
this.typeCombo.addSelectionListener(listener);\r
}\r
import java.util.HashMap;\r
import java.util.Map;\r
\r
-import org.eclipse.jface.layout.GridLayoutFactory;\r
import org.eclipse.jface.viewers.ISelection;\r
import org.eclipse.jface.viewers.IStructuredSelection;\r
import org.eclipse.swt.events.FocusListener;\r
import org.eclipse.swt.events.ModifyListener;\r
import org.eclipse.swt.widgets.Composite;\r
import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Table;\r
import org.eclipse.swt.widgets.TableItem;\r
import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
private IExpression expression;\r
private ModifyListener modifyListener;\r
private FocusListener focusListener;\r
+ private Table variableTable;\r
\r
\r
public ExpressionWidget(Composite parent, WidgetSupport support, int style) {\r
support.register(this);\r
- GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(parent);\r
this.parent = parent;\r
this.data = new HashMap<String, Object>();\r
}\r
exp.addFocusListener(focusListener);\r
this.expression = exp;\r
this.parent.layout();\r
+ validateFields();\r
} \r
}\r
\r
return expression;\r
}\r
\r
- public void validateFields(TableItem[] connectedVariables) {\r
+ public void setVariableTable(Table table) {\r
+ this.variableTable = table;\r
+ }\r
+ \r
+ public void validateFields() {\r
+ if(this.variableTable == null) return;\r
+ TableItem[] connectedVariables = this.variableTable.getItems();\r
try {\r
final Resource configuration = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
\r
import org.simantics.sysdyn.representation.Configuration;\r
import org.simantics.sysdyn.representation.IElement;\r
import org.simantics.sysdyn.representation.Variable;\r
-import org.simantics.sysdyn.ui.properties.EquationTab;\r
import org.simantics.ui.SimanticsUI;\r
import org.simantics.utils.ui.ISelectionUtils;\r
\r
public NameWidget(Composite parent, WidgetSupport support, int style) {\r
support.register(this);\r
nameText = new org.eclipse.swt.widgets.Text(parent, style);\r
- nameText.setFont(EquationTab.FONT);\r
\r
GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText);\r
\r
import org.simantics.db.procedure.Listener;\r
import org.simantics.db.request.Read;\r
import org.simantics.sysdyn.SysdynResource;\r
-import org.simantics.sysdyn.ui.properties.EquationTab;\r
import org.simantics.ui.SimanticsUI;\r
import org.simantics.utils.ui.ExceptionUtils;\r
import org.simantics.utils.ui.ISelectionUtils;\r
support.register(this);\r
\r
unitCombo = new Combo(parent, style);\r
- unitCombo.setFont(EquationTab.FONT);\r
\r
int columns = 6;\r
GC gc = new GC (unitCombo);\r
import java.util.Map;\r
\r
import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
import org.eclipse.jface.text.BadLocationException;\r
import org.eclipse.jface.text.IDocument;\r
import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.FocusAdapter;\r
+import org.eclipse.swt.events.FocusEvent;\r
import org.eclipse.swt.events.FocusListener;\r
import org.eclipse.swt.events.KeyListener;\r
import org.eclipse.swt.events.ModifyListener;\r
import org.simantics.db.exception.DatabaseException;\r
import org.simantics.db.request.Read;\r
import org.simantics.sysdyn.SysdynResource;\r
-import org.simantics.sysdyn.ui.properties.EquationTab;\r
import org.simantics.ui.SimanticsUI;\r
\r
public class BasicExpression implements IExpression {\r
\r
- ExpressionField expression;\r
- Resource expressionType;\r
+ private ExpressionField expression;\r
+ protected Resource expressionType;\r
+ private Point caretPosition; // Bug or something in source viewer's text widget. Cursor goes to 0, 0 on focus lost\r
\r
@Override\r
public void createExpressionFields(Composite parent, Map<String, Object> data) {\r
+ GridLayoutFactory.fillDefaults().numColumns(2).applyTo(parent);\r
String equation = data.get("equation") != null ? (String)data.get("equation") : "";\r
\r
Label l = new Label(parent, SWT.NONE);\r
- l.setFont(EquationTab.FONT);\r
l.setText("=");\r
\r
expression = new ExpressionField(parent, SWT.BORDER);\r
expression.setExpression(equation);\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
+ \r
+ expression.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
+\r
+ @Override\r
+ public void focusLost(FocusEvent e) {\r
+ caretPosition = expression.getSelection();\r
+ }\r
+ });\r
}\r
\r
@Override\r
public void focus() {\r
- if(this.expression != null) this.expression.focus();\r
+ if(this.expression != null && caretPosition != null) {\r
+ this.expression.focus();\r
+ expression.getSourceViewer().getTextWidget().setSelection(caretPosition.x, caretPosition.x + caretPosition.y);\r
+ }\r
\r
}\r
\r
import java.util.Map;\r
\r
import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
import org.eclipse.jface.text.BadLocationException;\r
import org.eclipse.jface.text.IDocument;\r
import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.FocusAdapter;\r
+import org.eclipse.swt.events.FocusEvent;\r
import org.eclipse.swt.events.FocusListener;\r
import org.eclipse.swt.events.KeyListener;\r
import org.eclipse.swt.events.ModifyListener;\r
import org.simantics.db.exception.DatabaseException;\r
import org.simantics.db.request.Read;\r
import org.simantics.sysdyn.SysdynResource;\r
-import org.simantics.sysdyn.ui.properties.EquationTab;\r
import org.simantics.ui.SimanticsUI;\r
\r
public class StockExpression implements IExpression {\r
\r
private Text integral;\r
private ExpressionField expression;\r
+ private Point caretPosition; // Bug or something in source viewer's text widget. Cursor goes to 0, 0 on focus lost\r
\r
@Override\r
public void createExpressionFields(Composite parent, Map<String, Object> data) {\r
+ GridLayoutFactory.fillDefaults().numColumns(2).applyTo(parent);\r
String initialEquation = data.get("initialEquation") != null ? (String)data.get("initialEquation") : "";\r
String integralEquation = data.get("integral") != null ? (String)data.get("integral") : "";\r
\r
\r
Label label = new Label(parent, SWT.NONE);\r
- label.setFont(EquationTab.FONT);\r
label.setText("Integral");\r
\r
integral = new Text(parent, SWT.MULTI | SWT.V_SCROLL | SWT.BORDER);\r
integral.setEditable(false);\r
- integral.setFont(EquationTab.FONT);\r
integral.setText(integralEquation);\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(integral);\r
\r
\r
label = new Label(parent, SWT.NONE);\r
- label.setFont(EquationTab.FONT);\r
label.setText("Initial\nValue");\r
\r
expression = new ExpressionField(parent, SWT.BORDER);\r
\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
\r
+ expression.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
+\r
+ @Override\r
+ public void focusLost(FocusEvent e) {\r
+ caretPosition = expression.getSelection();\r
+ }\r
+ });\r
+ \r
}\r
\r
@Override\r
public void focus() {\r
- if(this.expression != null) this.expression.focus();\r
+ if(this.expression != null && caretPosition != null) {\r
+ this.expression.focus();\r
+ expression.getSourceViewer().getTextWidget().setSelection(caretPosition.x, caretPosition.x + caretPosition.y);\r
+ }\r
\r
}\r
\r
package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
\r
+import java.awt.BasicStroke;\r
+import java.awt.Frame;\r
+import java.awt.event.ActionEvent;\r
+import java.awt.event.ActionListener;\r
+import java.awt.geom.Point2D;\r
+import java.io.StringReader;\r
+import java.util.ArrayList;\r
import java.util.Arrays;\r
import java.util.List;\r
import java.util.Map;\r
\r
+import javax.swing.Timer;\r
+\r
import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
import org.eclipse.jface.text.BadLocationException;\r
import org.eclipse.jface.text.IDocument;\r
import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.awt.SWT_AWT;\r
import org.eclipse.swt.events.FocusAdapter;\r
import org.eclipse.swt.events.FocusEvent;\r
import org.eclipse.swt.events.FocusListener;\r
import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.events.ModifyEvent;\r
import org.eclipse.swt.events.ModifyListener;\r
import org.eclipse.swt.events.SelectionAdapter;\r
import org.eclipse.swt.events.SelectionEvent;\r
import org.eclipse.swt.widgets.Button;\r
import org.eclipse.swt.widgets.Composite;\r
import org.eclipse.swt.widgets.Label;\r
+import org.jfree.chart.ChartFactory;\r
+import org.jfree.chart.ChartPanel;\r
+import org.jfree.chart.JFreeChart;\r
+import org.jfree.chart.plot.PlotOrientation;\r
+import org.jfree.data.xy.XYDataset;\r
+import org.jfree.data.xy.XYSeries;\r
+import org.jfree.data.xy.XYSeriesCollection;\r
import org.simantics.db.Builtins;\r
import org.simantics.db.ReadGraph;\r
import org.simantics.db.Resource;\r
import org.simantics.db.exception.DatabaseException;\r
import org.simantics.db.request.Read;\r
import org.simantics.sysdyn.SysdynResource;\r
-import org.simantics.sysdyn.ui.properties.EquationTab;\r
+import org.simantics.sysdyn.tableParser.ParseException;\r
+import org.simantics.sysdyn.tableParser.TableParser;\r
+import org.simantics.sysdyn.tableParser.Token;\r
import org.simantics.ui.SimanticsUI;\r
\r
public class WithLookupExpression implements IExpression {\r
private ExpressionField lastSelectedText = expression;\r
private Resource variable;\r
private LookupChartInfo chartInfo;\r
+ private Timer updateChartTimer;\r
+ \r
+ ChartPanel smallPanel;\r
+ Frame smallFrame;\r
\r
public WithLookupExpression(Resource variable) {\r
this.variable = variable;\r
\r
@Override\r
public void createExpressionFields(Composite parent, final Map<String, Object> data) {\r
+ GridLayoutFactory.fillDefaults().numColumns(3).applyTo(parent);\r
+ \r
+ updateChartTimer = new Timer(1000, new ActionListener() {\r
+ \r
+ @Override\r
+ public void actionPerformed(ActionEvent e) {\r
+ updateChart();\r
+ }\r
+ });\r
+ updateChartTimer.setRepeats(false);\r
\r
String equation = data.get("equation") != null ? (String)data.get("equation") : "";\r
String lookupTable = data.get("lookup") != null ? (String)data.get("lookup") : "";\r
\r
Label l = new Label(parent, SWT.NONE);\r
- l.setFont(EquationTab.FONT);\r
l.setText("With\nLookup");\r
\r
expression = new ExpressionField(parent, SWT.BORDER);\r
}\r
});\r
\r
+ Composite chartContainer = new Composite(parent, SWT.NONE);\r
+ createChart(chartContainer, data);\r
+ \r
\r
l = new Label(parent, SWT.NONE);\r
- l.setFont(EquationTab.FONT);\r
l.setText("Lookup\ntable");\r
\r
lookup = new ExpressionField(parent, SWT.BORDER);\r
lastSelectedText = lookup;\r
}\r
});\r
-\r
- asGraph = new Button(parent, SWT.None);\r
- asGraph.setText("As graph");\r
- asGraph.setFont(EquationTab.FONT);\r
- asGraph.addSelectionListener(new SelectionAdapter() {\r
- public void widgetSelected(SelectionEvent e) {\r
- if(chartInfo == null) chartInfo = new LookupChartInfo(expression.getExpression(), lookup.getExpression(), variable, data);\r
- LookupPopup pud = new LookupPopup(asGraph.getParent().getShell(), chartInfo);\r
- LookupChartInfo newInfo = pud.open(false);\r
- if(pud.getReturnCode() == org.eclipse.jface.window.Window.OK) {\r
- chartInfo = newInfo;\r
- lookup.setExpression(chartInfo.lookupTable);\r
- lookup.focus();\r
- }\r
+ \r
+ lookup.getSourceViewer().getTextWidget().addModifyListener(new ModifyListener() {\r
+ \r
+ @Override\r
+ public void modifyText(ModifyEvent e) {\r
+ if(!updateChartTimer.isRunning())\r
+ updateChartTimer.start();\r
+ else\r
+ updateChartTimer.restart();\r
}\r
});\r
-\r
+ \r
+ updateChart();\r
}\r
\r
@Override\r
this.expression.getSourceViewer().getTextWidget().addFocusListener(listener);\r
this.lookup.getSourceViewer().getTextWidget().addFocusListener(listener);\r
}\r
+ \r
+ private void createChart(Composite composite, final Map<String, Object> data) {\r
+ GridLayoutFactory.fillDefaults().applyTo(composite);\r
+ GridDataFactory.fillDefaults().span(1, 2).hint(150, SWT.DEFAULT).applyTo(composite);\r
+ final Composite chartComposite = new Composite(composite, \r
+ SWT.NO_BACKGROUND | SWT.EMBEDDED);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(chartComposite);\r
+ smallFrame = SWT_AWT.new_Frame(chartComposite);\r
+\r
+ XYDataset dataset = new XYSeriesCollection(new XYSeries("Lookup Table"));\r
+ JFreeChart chart = createChart(dataset);\r
+ smallPanel = new ChartPanel(chart);\r
+ smallFrame.add(smallPanel);\r
+ \r
+ asGraph = new Button(composite, SWT.NONE);\r
+ GridDataFactory.fillDefaults().align(SWT.END, SWT.BEGINNING).applyTo(asGraph);\r
+ asGraph.setText("Configure visually");\r
+ asGraph.addSelectionListener(new SelectionAdapter() {\r
+ public void widgetSelected(SelectionEvent e) {\r
+ if(chartInfo == null) chartInfo = new LookupChartInfo(expression.getExpression(), lookup.getExpression(), variable, data);\r
+ LookupPopup pud = new LookupPopup(asGraph.getParent().getShell(), chartInfo);\r
+ LookupChartInfo newInfo = pud.open(false);\r
+ if(pud.getReturnCode() == org.eclipse.jface.window.Window.OK) {\r
+ chartInfo = newInfo;\r
+ lookup.setExpression(chartInfo.lookupTable);\r
+ updateChart();\r
+ lookup.focus();\r
+ }\r
+ }\r
+ });\r
+ }\r
+ \r
+ private static JFreeChart createChart(XYDataset dataset) {\r
+ JFreeChart chart = ChartFactory.createXYLineChart(\r
+ null,\r
+ null,\r
+ null,\r
+ dataset,\r
+ PlotOrientation.VERTICAL,\r
+ true,\r
+ true,\r
+ false\r
+ );\r
+ chart.removeLegend();\r
+ chart.getXYPlot().getDomainAxis().setTickLabelsVisible(false);\r
+ chart.getXYPlot().getDomainAxis().setAxisLineVisible(false);\r
+ chart.getXYPlot().getDomainAxis().setTickMarksVisible(false);\r
+ chart.getXYPlot().getRangeAxis().setTickLabelsVisible(false);\r
+ chart.getXYPlot().getRangeAxis().setAxisLineVisible(false);\r
+ chart.getXYPlot().getRangeAxis().setTickMarksVisible(false);\r
+ chart.getXYPlot().getRenderer().setSeriesStroke(0, new BasicStroke(3.0f));\r
+ return chart;\r
+ }\r
+ \r
+ private void updateChart() {\r
+ ArrayList<Point2D> dataPoints = new ArrayList<Point2D>();\r
+ TableParser parser = new TableParser(new StringReader(""));\r
+ parser.ReInit(new StringReader(lookup.getExpression()));\r
+ try {\r
+ parser.table();\r
+ ArrayList<Token> xTokens = parser.getXTokens();\r
+ for(Token token : xTokens) {\r
+ dataPoints.add(new Point2D.Double(\r
+ Double.parseDouble(token.image), \r
+ Double.parseDouble(token.next.next.image)));\r
+ }\r
+ } catch (ParseException e1) {\r
+ return;\r
+ }\r
+ \r
+ if(dataPoints.size() == 0) return;\r
+ \r
+ XYSeries series = new XYSeries("Lookup Table");\r
+ for(Point2D point : dataPoints) {\r
+ series.add(point.getX(), point.getY());\r
+ }\r
+ XYSeriesCollection dataset = new XYSeriesCollection(series);\r
+ smallPanel.getChart().getXYPlot().setDataset(dataset);\r
+ }\r
+\r
\r
}\r