From: lempinen Date: Thu, 27 May 2010 14:29:27 +0000 (+0000) Subject: Basic functions of Lookup Popup. Users can create a lookup table graphically X-Git-Tag: simantics-1.2.0~233 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=2ec0f67479fbe4f0949d12e65a6d77ea6ae543cb;p=simantics%2Fsysdyn.git Basic functions of Lookup Popup. Users can create a lookup table graphically git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@15966 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/EquationView.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/EquationView.java index dacca6c0..6ace86f6 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/EquationView.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/EquationView.java @@ -347,8 +347,7 @@ public class EquationView extends ViewPart implements ISelectionListener { private void addExpressionFieldListeners() { if(expressionComposite.getExpressionViewFactor() != null) - for(ExpressionField ef : expressionComposite.getExpressionViewFactor().getExpressionFields()) { - final String expression = ef.getExpression(); + for(final ExpressionField ef : expressionComposite.getExpressionViewFactor().getExpressionFields()) { StyledText st = ef.getSourceViewer().getTextWidget(); st.addModifyListener(new ModifyListener() { @@ -365,9 +364,9 @@ public class EquationView extends ViewPart implements ISelectionListener { @Override public void keyPressed(KeyEvent e) { - if(e.keyCode == SWT.ESC && expression != null) { - ((Text)e.widget).setText(expression); - ((Text)e.widget).setSelection(expression.length()); + if(e.keyCode == SWT.ESC && ef.getExpression() != null) { + ((StyledText)e.widget).setText(ef.getExpression()); + ((StyledText)e.widget).setSelection(ef.getExpression().length()); } } }); diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupChartPanel.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupChartPanel.java new file mode 100644 index 00000000..da6b2372 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupChartPanel.java @@ -0,0 +1,150 @@ +package org.simantics.sysdyn.ui.equation.expressions; + +import java.awt.Point; +import java.awt.event.MouseEvent; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import org.jfree.chart.ChartPanel; +import org.jfree.chart.ChartRenderingInfo; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.axis.ValueAxis; +import org.jfree.chart.entity.ChartEntity; +import org.jfree.chart.entity.PlotEntity; +import org.jfree.chart.entity.XYItemEntity; +import org.jfree.chart.plot.XYPlot; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; + +@SuppressWarnings("serial") +public class LookupChartPanel extends ChartPanel { + + private XYItemEntity dragPrevEntity; + private boolean drawing; + private XYSeries series; + private JFreeChart chart; + private LookupInputOutputTable table; + + public LookupChartPanel(JFreeChart chart) { + super(chart); + this.chart = chart; + XYSeriesCollection collection = (XYSeriesCollection) ((XYPlot)chart.getPlot()).getDataset(); + series = collection.getSeries(0); + } + + public void setTable(LookupInputOutputTable table) { + this.table = table; + } + + public void mouseDragged(MouseEvent e) + { + if(dragPrevEntity != null) { + + int item = dragPrevEntity.getItem(); + XYPlot plot = (XYPlot)chart.getPlot(); + ValueAxis rangeAxis = plot.getRangeAxis(); + ValueAxis domainAxis = plot.getDomainAxis(); + Point2D location = getLocationOnChart(getMouseLocation(e)); + Number prevX = item == 0 ? null : series.getX(item - 1); + Number nextX = item == series.getItemCount() - 1 ? null : series.getX(item + 1); + + + if(series.indexOf(location.getX()) >= 0 && series.indexOf(location.getX()) != item) + return; + else if (prevX != null && location.getX() < prevX.doubleValue()) + location.setLocation(series.getX(item).doubleValue(), location.getY()); + else if (nextX != null && location.getX() > nextX.doubleValue()) + location.setLocation(series.getX(item).doubleValue(), location.getY()); + else if (location.getX() > domainAxis.getUpperBound()) + location.setLocation(domainAxis.getUpperBound(), location.getY()); + else if (location.getX() < domainAxis.getLowerBound()) + location.setLocation(domainAxis.getLowerBound(), location.getY()); + + if (location.getY() > rangeAxis.getUpperBound()) + location.setLocation(location.getX(), rangeAxis.getUpperBound()); + else if (location.getY() < rangeAxis.getLowerBound()) + location.setLocation(location.getX(), rangeAxis.getLowerBound()); + + removeItemFromSeries(dragPrevEntity.getItem()); + addLocationToSeries(location); + } else { + ChartEntity currEntity = this.getEntityForPoint(e.getX(),e.getY()); + if(!drawing && currEntity instanceof XYItemEntity) { + dragPrevEntity = ((XYItemEntity)currEntity); + } else if (currEntity instanceof PlotEntity){ + drawing = true; + Point2D locationOnChart = getLocationOnChart(getMouseLocation(e)); + int item = series.indexOf(locationOnChart.getX()); + if (item >= 0) { + Point2D location = new Point2D.Double(series.getX(item).doubleValue(), series.getY(item).doubleValue()); + Point2D javaLocation = getLocationOnJava2D(location); + removeItemFromSeries(item); + addLocationToSeries(getLocationOnChart(new Point2D.Double(javaLocation.getX(), e.getY()))); + } + } + } + + } + + public void mouseReleased(MouseEvent e) { + + dragPrevEntity = null; + drawing = false; + } + + public void mouseClicked(MouseEvent e) + { + if(e.getButton() == MouseEvent.BUTTON1) { + addLocationToSeries(getLocationOnChart(getMouseLocation(e))); + } else if (e.getButton() == MouseEvent.BUTTON3) { + ChartEntity entity = this.getEntityForPoint(e.getX(),e.getY()); + if(entity instanceof XYItemEntity) { + XYItemEntity xyentity = ((XYItemEntity)entity); + removeItemFromSeries(xyentity.getItem()); + } + } + } + + private Point2D getLocationOnChart(Point2D coordinates) { + XYPlot plot = (XYPlot)chart.getPlot(); + ChartRenderingInfo info = getChartRenderingInfo(); + Rectangle2D dataArea = info.getPlotInfo().getDataArea(); + double chartX = plot.getDomainAxis().java2DToValue(coordinates.getX(), dataArea, + plot.getDomainAxisEdge()); + double chartY = plot.getRangeAxis().java2DToValue(coordinates.getY(), dataArea, + plot.getRangeAxisEdge()); + return new Point2D.Double(chartX, chartY); + } + + private Point2D getLocationOnJava2D(Point2D location) { + XYPlot plot = (XYPlot)chart.getPlot(); + ChartRenderingInfo info = getChartRenderingInfo(); + Rectangle2D dataArea = info.getPlotInfo().getDataArea(); + double javaX = plot.getDomainAxis().valueToJava2D(location.getX(), dataArea, + plot.getDomainAxisEdge()); + double javaY = plot.getRangeAxis().valueToJava2D(location.getY(), dataArea, + plot.getRangeAxisEdge()); + return new Point2D.Double(javaX, javaY); + } + + public void addLocationToSeries(Point2D location) { + series.add(location.getX(), location.getY()); + table.addLocation(location); + } + + public void removeItemFromSeries(int item){ + Point2D location = new Point2D.Double(series.getX(item).doubleValue(),series.getY(item).doubleValue()); + series.remove(item); + table.removeLocation(location); + } + + private Point2D getMouseLocation(MouseEvent e) { + int mouseX = e.getX(); + int mouseY = e.getY(); + Point2D p = translateScreenToJava2D( + new Point(mouseX, mouseY)); + return p; + } + + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupInputOutputTable.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupInputOutputTable.java new file mode 100644 index 00000000..4a63d818 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupInputOutputTable.java @@ -0,0 +1,203 @@ +package org.simantics.sysdyn.ui.equation.expressions; + +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; + +public class LookupInputOutputTable extends Composite { + + public static final String INPUT = "Input"; + public static final String OUTPUT = "Output"; + public static final String[] PROPS = { INPUT, OUTPUT }; + + Table table; + TableViewer tableViewer; + List tableRows; + + + public LookupInputOutputTable(Composite parent, int style) { + super(parent, style); + + GridLayoutFactory.fillDefaults().applyTo(this); + GridDataFactory.fillDefaults().grab(true, true).applyTo(this); + table = new Table(this, SWT.BORDER|SWT.SINGLE|SWT.FULL_SELECTION); + GridDataFactory.fillDefaults().grab(true, true).applyTo(table); + table.setHeaderVisible (true); + table.setLinesVisible(true); + + TableColumn column = new TableColumn (table, SWT.LEFT); + column.setText (INPUT); + column.setWidth (60); + + column = new TableColumn (table, SWT.LEFT); + column.setText (OUTPUT); + column.setWidth (60); + + // Create the viewer and connect it to the view + tableViewer = new TableViewer (table); + + tableViewer.setContentProvider (new ArrayContentProvider()); + tableViewer.setLabelProvider (new InputOutputLabelProvider()); + + tableRows = new ArrayList(); + tableViewer.setInput(tableRows); + + CellEditor[] editors = new CellEditor[2]; + editors[0] = new TextCellEditor(table); + editors[1] = new TextCellEditor(table); + tableViewer.setCellEditors(editors); + tableViewer.setColumnProperties(PROPS); + + } + + private class InputOutputLabelProvider extends LabelProvider implements ITableLabelProvider { + public Image getColumnImage (Object element, int columnIndex) { + return null; + } + public String getColumnText (Object element, int columnIndex) { + if(element instanceof InputOutput) { + InputOutput io = (InputOutput)element; + switch (columnIndex) { + case 0: return (String)io.getInput(String.class); + case 1: return (String)io.getOutput(String.class); + } + } + return ""; + } + } + + public void addLocation(Point2D location) { + tableRows.add(new InputOutput(location.getX(), location.getY())); + tableViewer.getTable().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + refresh(); + } + }); + + } + + public void removeLocation(Point2D location) { + for(InputOutput io : tableRows) { + if((Double)io.getInput(Double.class) == location.getX()) { + tableRows.remove(io); + tableViewer.getTable().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + refresh(); + } + }); + break; + } + } + + } + + + class InputOutput { + private double input, output; + + public InputOutput(double input, double output) { + this.input = input; + this.output = output; + } + + /** + * + * @param clazz String.class or Double.class + * @return input as string or double or null if asked for something else + */ + @SuppressWarnings("unchecked") + public Object getInput(Class clazz) { + if(clazz == String.class) { + return "" + input; + } else if (clazz == Double.class) { + return input; + } + return null; + } + + public Double setInput(String input) { + try { + this.input = Double.parseDouble(input); + return this.input; + } catch (NumberFormatException e) { + return null; + } + } + + public void setInput(double input) { + this.input = input; + } + + /** + * + * @param clazz String.class or Double.class + * @return output as string or double or null if asked for something else + */ + @SuppressWarnings("unchecked") + public Object getOutput(Class clazz) { + if(clazz == String.class) { + return "" + output; + } else if (clazz == Double.class) { + return output; + } + return null; + } + + public void setOutput(String output) { + try { + this.output = Double.parseDouble(output); + } catch (NumberFormatException e) { + + } + } + + public void setOutput(double output) { + this.output = output; + } + + } + + class InputOutputComparator extends ViewerComparator { + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + if ((e1 instanceof InputOutput) && + (e2 instanceof InputOutput)) { + InputOutput io1 = (InputOutput)e1; + InputOutput io2 = (InputOutput)e2; + Double d1 = (Double)io1.getInput((Double.class)); + Double d2 = (Double)io2.getInput((Double.class)); + return d1.compareTo(d2); + } + return 0; + } + } + + public TableViewer getTableViewer() { + return this.tableViewer; + } + + public void refresh() { + tableViewer.setComparator(new InputOutputComparator()); + tableViewer.refresh(); + } +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupPopup.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupPopup.java new file mode 100644 index 00000000..34fe9ad2 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupPopup.java @@ -0,0 +1,340 @@ +package org.simantics.sysdyn.ui.equation.expressions; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.GridLayout; +import java.awt.event.MouseEvent; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Point2D; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Iterator; + +import javax.swing.JComponent; +import javax.swing.JPanel; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Widget; +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.axis.ValueAxis; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; +import org.jfree.data.xy.XYDataItem; +import org.jfree.data.xy.XYDataset; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; +import org.simantics.db.Resource; +import org.simantics.g2d.chassis.SWTAWTComponent; +import org.simantics.sysdyn.tableParser.ParseException; +import org.simantics.sysdyn.tableParser.Token; +import org.simantics.sysdyn.tableParser.TableParser; +import org.simantics.sysdyn.ui.equation.expressions.LookupInputOutputTable.InputOutput; + +/** + * should do something in format {{0,1},{1,2},{2,3}} + * @author TLTEEMU + * + */ + +public class LookupPopup extends Dialog { + + JFreeChart chart; + LookupChartPanel chartPanel; + SWTAWTComponent c; + JPanel panel; + Resource variable; + LookupInputOutputTable table; + ArrayList dataPoints; + + Text minX, maxX, minY, maxY; + + protected LookupPopup(Shell parentShell, Resource variable, String tableAsString) { + super(parentShell); + this.variable = variable; + this.dataPoints = new ArrayList(); + + TableParser parser = new TableParser(new StringReader("")); + parser.ReInit(new StringReader(tableAsString)); + try { + parser.table(); + ArrayList xTokens = parser.getXTokens(); + for(Token token : xTokens) { + dataPoints.add(new Point2D.Double( + Double.parseDouble(token.image), + Double.parseDouble(token.next.next.image))); + } + } catch (ParseException e1) { + + } + + } + + @Override + protected Control createDialogArea(Composite parent) { + + chartPanel = new LookupChartPanel(createChart()); + chartPanel.setPreferredSize(new java.awt.Dimension(500, 270)); + chartPanel.setMouseZoomable(true, false); + chartPanel.setDomainZoomable(false); + chartPanel.setRangeZoomable(false); + + XYPlot plot = (XYPlot) chart.getPlot(); + ValueAxis rangeAxis = plot.getRangeAxis(); + ValueAxis domainAxis = plot.getDomainAxis(); + + Composite container = new Composite(parent, SWT.None); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(3).applyTo(container); + + Composite yAxis = new Composite(container, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(yAxis); + GridDataFactory.fillDefaults().grab(false, true).applyTo(yAxis); + maxY = new Text(yAxis, SWT.BORDER | SWT.RIGHT); + GridDataFactory.fillDefaults().hint(40, SWT.DEFAULT).applyTo(maxY); + maxY.addModifyListener(getAxisBoundModifyListener()); + maxY.setText("" + rangeAxis.getUpperBound()); + Composite fillY = new Composite(yAxis, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).applyTo(fillY); + minY = new Text(yAxis, SWT.BORDER | SWT.RIGHT); + GridDataFactory.fillDefaults().hint(40, SWT.DEFAULT).applyTo(minY); + minY.addModifyListener(getAxisBoundModifyListener()); + minY.setText("" + rangeAxis.getLowerBound()); + + c = new SWTAWTComponent(container, SWT.BORDER) { + @Override + protected JComponent createSwingComponent() { + panel = new JPanel(); + panel.setLayout(new GridLayout(1, 1)); + panel.setPreferredSize(new java.awt.Dimension(500, 270)); + panel.add(chartPanel); + panel.doLayout(); + return panel; + } + }; + GridDataFactory.fillDefaults().hint(500, 300).applyTo(c); + c.populate(); + + + Composite valueTableComposite = new Composite(container, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(valueTableComposite); + GridLayoutFactory.fillDefaults().applyTo(valueTableComposite); + + + table = new LookupInputOutputTable(valueTableComposite, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(table); + chartPanel.setTable(table); + table.getTableViewer().setCellModifier(new InputOutputCellModifier()); + table.getTableViewer().getTable().addMouseListener(new MouseListener() { + + @Override + public void mouseUp(org.eclipse.swt.events.MouseEvent e) { + if(e.button == MouseEvent.BUTTON3) { + Table table = (Table)e.widget; + TableItem item = (TableItem)table.getItem(new org.eclipse.swt.graphics.Point(e.x, e.y)); + chartPanel.removeItemFromSeries(table.indexOf(item)); + } + } + @Override + public void mouseDown(org.eclipse.swt.events.MouseEvent e) { } + @Override + public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent e) { } + }); + for(Point2D location : this.dataPoints) { + chartPanel.addLocationToSeries(location); + } + + + Label l = new Label(container, SWT.NONE); + l.setText(""); + + Composite xAxis = new Composite(container, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(xAxis); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(xAxis); + minX = new Text(xAxis, SWT.BORDER | SWT.RIGHT); + GridDataFactory.fillDefaults().hint(40, SWT.DEFAULT).applyTo(minX); + minX.addModifyListener(getAxisBoundModifyListener()); + minX.setText("" + domainAxis.getLowerBound()); + Composite fillX = new Composite(xAxis, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(fillX); + GridLayoutFactory.fillDefaults().applyTo(fillX); + l = new Label(fillX, SWT.NONE); + maxX = new Text(xAxis, SWT.BORDER | SWT.RIGHT); + GridDataFactory.fillDefaults().hint(40, SWT.DEFAULT).applyTo(maxX); + maxX.addModifyListener(getAxisBoundModifyListener()); + maxX.setText("" + domainAxis.getUpperBound()); + + return null; + } + + + public String open(boolean moi) { + Shell shell = this.getShell(); + if (shell == null || shell.isDisposed()) { + shell = null; + create(); + shell = this.getShell(); + } + constrainShellSize(); + + shell.open(); + Display display = getParentShell().getDisplay(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + return graphToModelicaTable(); + } + + @SuppressWarnings("unchecked") + private String graphToModelicaTable() { + StringBuilder b = new StringBuilder(); + b.append("{"); + XYSeriesCollection collection = (XYSeriesCollection) ((XYPlot)chart.getPlot()).getDataset(); + XYSeries series = collection.getSeries(0); + if(series.isEmpty()) + return ""; + Iterator iterator = series.getItems().iterator(); + while(iterator.hasNext()){ + XYDataItem item = (XYDataItem)iterator.next(); + b.append("{" + item.getX() + "," + item.getY() + "}"); + if(iterator.hasNext()) + b.append(","); + } + b.append("}"); + return b.toString(); + } + + private JFreeChart createChart() { + XYDataset dataset = createDataset(); + chart = ChartFactory.createXYLineChart("Lookup", "X", "Y", + dataset, PlotOrientation.VERTICAL, false, true, false); + XYPlot plot = (XYPlot) chart.getPlot(); + XYLineAndShapeRenderer renderer + = (XYLineAndShapeRenderer) plot.getRenderer(); + renderer.setBaseShapesVisible(true); + renderer.setDrawOutlines(true); + renderer.setUseFillPaint(true); + renderer.setBaseFillPaint(Color.white); + renderer.setSeriesStroke(0, new BasicStroke(3.0f)); + renderer.setSeriesOutlineStroke(0, new BasicStroke(2.0f)); + renderer.setSeriesShape(0, new Ellipse2D.Double(-5.0, -5.0, 10.0, 10.0)); + + ValueAxis rangeAxis = plot.getRangeAxis(); + rangeAxis.setAutoRange(false); + rangeAxis.setRange(0, 40); + + ValueAxis domainAxis = plot.getDomainAxis(); + domainAxis.setAutoRange(false); + domainAxis.setRange(0, 30); + return chart; + } + + public XYDataset createDataset() { + XYSeries series = new XYSeries("Series"); + XYSeriesCollection dataset = new XYSeriesCollection(); + dataset.addSeries(series); + return dataset; + } + + private ModifyListener getAxisBoundModifyListener() { + return new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + Widget widget = e.widget; + if(widget instanceof Text) { + Text text = (Text)widget; + Double value; + try { + value = Double.parseDouble(text.getText()); + } catch (NumberFormatException e1 ) { + return; + } + XYPlot plot = (XYPlot) chart.getPlot(); + ValueAxis rangeAxis = plot.getRangeAxis(); + ValueAxis domainAxis = plot.getDomainAxis(); + if(text == minX) { + domainAxis.setLowerBound(value); + } else if (text == maxX) { + domainAxis.setUpperBound(value); + } else if (text == minY) { + rangeAxis.setLowerBound(value); + } else if (text == maxY) { + rangeAxis.setUpperBound(value); + } + } + } + }; + } + + private class InputOutputCellModifier implements ICellModifier { + + XYSeries series; + + public InputOutputCellModifier() { + XYSeriesCollection collection = (XYSeriesCollection) ((XYPlot)chart.getPlot()).getDataset(); + series = collection.getSeries(0); + } + + public boolean canModify(Object element, String property) { + return true; + } + + public Object getValue(Object element, String property) { + InputOutput io = (InputOutput)element; + if (LookupInputOutputTable.INPUT.equals(property)) + return (String)io.getInput(String.class); + else if (LookupInputOutputTable.OUTPUT.equals(property)) + return (String)io.getOutput(String.class); + else + return null; + } + + public void modify(Object element, String property, Object value) { + if (element instanceof Item) element = ((Item) element).getData(); + + InputOutput io = (InputOutput)element; + Double x = (Double)io.getInput(Double.class); + int item = series.indexOf(x); + series.remove(item); + + if (LookupInputOutputTable.INPUT.equals(property)) { + Double newX = io.setInput((String)value); + // if has the same x-value, revert back + if(newX != null && series.indexOf(newX) >= 0) { + io.setInput(x); + } + } else if (LookupInputOutputTable.OUTPUT.equals(property)) { + io.setOutput((String)value); + } + + series.add((Double)io.getInput(Double.class), (Double)io.getOutput(Double.class)); + + table.refresh(); + + } + } + + + + + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/WithLookupExpressionViewFactor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/WithLookupExpressionViewFactor.java index 5a3cda31..288fd3b3 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/WithLookupExpressionViewFactor.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/WithLookupExpressionViewFactor.java @@ -22,7 +22,10 @@ import org.eclipse.jface.text.IDocument; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.simantics.db.Builtins; @@ -42,7 +45,9 @@ public class WithLookupExpressionViewFactor implements IExpressionViewFactor { private ExpressionField expression; private Label lookupLabel; private ExpressionField lookup; + private Button asGraph; private ExpressionField lastSelectedText = expression; + private Resource variable; @Override public void createView(Composite parent, Map data) { @@ -87,6 +92,18 @@ public class WithLookupExpressionViewFactor implements IExpressionViewFactor { lastSelectedText = lookup; } }); + + asGraph = new Button(parent, SWT.None); + asGraph.setText("As graph"); + asGraph.setFont(FONT); + asGraph.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + if(e.widget == asGraph) { + LookupPopup pud = new LookupPopup(asGraph.getParent().getShell(), variable, lookup.getExpression()); + lookup.setExpression(pud.open(false)); + } + } + }); } @Override @@ -117,6 +134,7 @@ public class WithLookupExpressionViewFactor implements IExpressionViewFactor { } data.put("equation", results[0]); data.put("lookup", results[1]); + this.variable = variable; } } diff --git a/org.simantics.sysdyn/META-INF/MANIFEST.MF b/org.simantics.sysdyn/META-INF/MANIFEST.MF index cf01aeac..c7a329ca 100644 --- a/org.simantics.sysdyn/META-INF/MANIFEST.MF +++ b/org.simantics.sysdyn/META-INF/MANIFEST.MF @@ -13,4 +13,5 @@ Export-Package: org.simantics.sysdyn, org.simantics.sysdyn.manager, org.simantics.sysdyn.modelica, org.simantics.sysdyn.representation, - org.simantics.sysdyn.representation.visitors + org.simantics.sysdyn.representation.visitors, + org.simantics.sysdyn.tableParser diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/SysdynResource.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/SysdynResource.java index 8f3d8b31..3e0218ac 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/SysdynResource.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/SysdynResource.java @@ -21,6 +21,7 @@ import org.simantics.db.exception.DatabaseException; public class SysdynResource { public final Resource Auxiliary; + public final Resource AuxiliarySymbol; public final Resource Cloud; public final Resource Configuration; public final Resource ConfigurationDiagram; @@ -53,15 +54,18 @@ public class SysdynResource { public final Resource RefersTo; public final Resource Stock; public final Resource StockExpression; + public final Resource StockSymbol; public final Resource SysdynModel; public final Resource SysdynProject; public final Resource Terminal; public final Resource Valve; + public final Resource ValveSymbol; public final Resource Variable; public final Resource WithLookupExpression; public static class URIs { public static final String Auxiliary = "http://www.simantics.org/Sysdyn-1.0/Auxiliary"; + public static final String AuxiliarySymbol = "http://www.simantics.org/Sysdyn-1.0/AuxiliarySymbol"; public static final String Cloud = "http://www.simantics.org/Sysdyn-1.0/Cloud"; public static final String Configuration = "http://www.simantics.org/Sysdyn-1.0/Configuration"; public static final String ConfigurationDiagram = "http://www.simantics.org/Sysdyn-1.0/ConfigurationDiagram"; @@ -94,10 +98,12 @@ public class SysdynResource { public static final String RefersTo = "http://www.simantics.org/Sysdyn-1.0/RefersTo"; public static final String Stock = "http://www.simantics.org/Sysdyn-1.0/Stock"; public static final String StockExpression = "http://www.simantics.org/Sysdyn-1.0/StockExpression"; + public static final String StockSymbol = "http://www.simantics.org/Sysdyn-1.0/StockSymbol"; public static final String SysdynModel = "http://www.simantics.org/Sysdyn-1.0/SysdynModel"; public static final String SysdynProject = "http://www.simantics.org/Sysdyn-1.0/SysdynProject"; public static final String Terminal = "http://www.simantics.org/Sysdyn-1.0/Terminal"; public static final String Valve = "http://www.simantics.org/Sysdyn-1.0/Valve"; + public static final String ValveSymbol = "http://www.simantics.org/Sysdyn-1.0/ValveSymbol"; public static final String Variable = "http://www.simantics.org/Sysdyn-1.0/Variable"; public static final String WithLookupExpression = "http://www.simantics.org/Sysdyn-1.0/WithLookupExpression"; } @@ -113,6 +119,7 @@ public class SysdynResource { public SysdynResource(ReadGraph graph) { Auxiliary = getResourceOrNull(graph, URIs.Auxiliary); + AuxiliarySymbol = getResourceOrNull(graph, URIs.AuxiliarySymbol); Cloud = getResourceOrNull(graph, URIs.Cloud); Configuration = getResourceOrNull(graph, URIs.Configuration); ConfigurationDiagram = getResourceOrNull(graph, URIs.ConfigurationDiagram); @@ -145,10 +152,12 @@ public class SysdynResource { RefersTo = getResourceOrNull(graph, URIs.RefersTo); Stock = getResourceOrNull(graph, URIs.Stock); StockExpression = getResourceOrNull(graph, URIs.StockExpression); + StockSymbol = getResourceOrNull(graph, URIs.StockSymbol); SysdynModel = getResourceOrNull(graph, URIs.SysdynModel); SysdynProject = getResourceOrNull(graph, URIs.SysdynProject); Terminal = getResourceOrNull(graph, URIs.Terminal); Valve = getResourceOrNull(graph, URIs.Valve); + ValveSymbol = getResourceOrNull(graph, URIs.ValveSymbol); Variable = getResourceOrNull(graph, URIs.Variable); WithLookupExpression = getResourceOrNull(graph, URIs.WithLookupExpression); } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/TableParser.jj b/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/TableParser.jj new file mode 100644 index 00000000..e4bede05 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/TableParser.jj @@ -0,0 +1,81 @@ +options { + JDK_VERSION = "1.6"; + STATIC = false; +} + +PARSER_BEGIN(TableParser) +package org.simantics.sysdyn.tableParser; + +import java.util.ArrayList; + +public class TableParser { + ArrayList xTokens = new ArrayList(); + + public ArrayList getXTokens() { + return xTokens; + } + + +} +PARSER_END(TableParser) + +/*** Lexer *********************************************************/ + +SKIP: +{ +| +| +} + +TOKEN: +{ + "(" | ")" | "{" | "}" | "[" | "]" | "." | ":" | ";" | "," +| "if" | "then" | "else" | "elseif" +| "or" | "and" | "not" +| "<" | "<=" | ">" | ">=" | "==" | "<>" +| "+" | "-" | ".+" | ".-" +| "*" | "/" | ".*" | "./" +| "^" | ".^" +| "=" | ":=" +| "false" | "true" | "end" | "annotation" +| "each" | "fine" | "redeclare" | "replaceable" +| +| + { matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); } +| +| "." ()? (["e","E"] )? + | "." (["e","E"] )? + | ["e","E"] + ) > +} + +/*** Parser ********************************************************/ + +void table() : { +} { + "{" table_element() ( "," table_element() )* "}" +} + +void table_element() : { +} { + "{" x_value() "," y_value() "}" +} + +void x_value() : { +} { + + signed_number() { + xTokens.add(token); + } +} + +void y_value() : { +} { + signed_number() +} + +void signed_number() : { +} { + ("-")? ( | ) +} \ No newline at end of file