]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Basic functions of Lookup Popup. Users can create a lookup table graphically
authorlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 27 May 2010 14:29:27 +0000 (14:29 +0000)
committerlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 27 May 2010 14:29:27 +0000 (14:29 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@15966 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/EquationView.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupChartPanel.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupInputOutputTable.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupPopup.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/WithLookupExpressionViewFactor.java
org.simantics.sysdyn/META-INF/MANIFEST.MF
org.simantics.sysdyn/src/org/simantics/sysdyn/SysdynResource.java
org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/TableParser.jj [new file with mode: 0644]

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