package org.eclipse.iee.pad.graph.ui; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.draw2d.Figure; import org.eclipse.draw2d.GridData; import org.eclipse.draw2d.GridLayout; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.ToolbarLayout; import org.eclipse.iee.editor.core.bindings.ConvertedObservableValue; import org.eclipse.iee.editor.core.bindings.DefaultObservableValue; import org.eclipse.iee.editor.core.bindings.IObservableValue; import org.eclipse.iee.editor.core.bindings.IObserver; import org.eclipse.iee.editor.core.bindings.ObservableProperty; import org.eclipse.iee.editor.core.bindings.converter.DoubleConverter; import org.eclipse.iee.editor.core.pad.common.text.AbstractVisualTextEditor; import org.eclipse.iee.editor.core.pad.common.text.IEditorLocation; import org.eclipse.iee.editor.core.pad.common.text.TextPartEditor; import org.eclipse.iee.pad.formula.ui.utils.UIFormulaRenderer; import org.eclipse.iee.pad.graph.model.GraphElement; import org.eclipse.iee.pad.graph.model.GraphModel; import org.eclipse.jface.window.IShellProvider; import org.eclipse.swt.widgets.Caret; import org.jfree.chart.JFreeChart; import org.jfree.util.PaintUtilities; import com.google.common.base.Converter; import com.google.common.base.Optional; import com.google.common.reflect.TypeToken; public class GraphModelEditor extends AbstractVisualTextEditor<GraphModel, IFigure> { private Map<GraphElement, GraphElementEditor> editors = new HashMap<>(); private UIFormulaRenderer fFormulaRenderer; private IObserver<List<GraphElement>> fListener; private Figure fSeries; private IShellProvider fShellProvider; private ChartEditor fChartEditor; private ObservableProperty<Double> fMinXValue; private ObservableProperty<Double> fMaxXValue; private ObservableProperty<Double> fMinYValue; private ObservableProperty<Double> fMaxYValue; private ObservableProperty<List<String>> fVariablesValue; private ObservableProperty<List<GraphElement>> fElementsValue; public GraphModelEditor(UIFormulaRenderer formulaRenderer, IShellProvider shellProvider) { fFormulaRenderer = formulaRenderer; fShellProvider = shellProvider; fListener = new IObserver<List<GraphElement>>() { @Override public void valueChanged(List<GraphElement> oldValue, List<GraphElement> newValue) { updateElements(newValue); } }; } protected IFigure createFigure() { IFigure figure = new Figure(); GridLayout manager = new GridLayout(); manager.numColumns = 2; figure.setLayoutManager(manager); fChartEditor = new ChartEditor(fShellProvider); IFigure seriesFigure = createSeriesFigure(); GridData seriesData = new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL); figure.add(seriesFigure, seriesData); addEditor(fChartEditor); IFigure chartFigure = fChartEditor.getFigure(); GridData chartData = new GridData( GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL); figure.add(chartFigure, chartData); figure.add(new Figure()); IFigure variablesFigure = createVariablesFigure(); GridData varsData = new GridData( GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); figure.add(variablesFigure, varsData); return figure; } public IFigure createSeriesFigure() { IFigure figure = new Figure(); GridLayout layout = new GridLayout(); layout.numColumns = 1; figure.setLayoutManager(layout); GridData maxXdata = new GridData(); TextPartEditor maxY = new TextPartEditor(); maxY.bindValue(ConvertedObservableValue.from(fMaxYValue, DoubleConverter.REVERSE_INSTANCE)); figure.add(maxY.getFigure(), maxXdata); addEditor(maxY); fSeries = new Figure(); fSeries.setLayoutManager(new ToolbarLayout(false)); GridData seriesData = new GridData(GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_CENTER); figure.add(fSeries, seriesData); GridData minXdata = new GridData(); TextPartEditor minY = new TextPartEditor(); minY.bindValue(ConvertedObservableValue.from(fMinYValue, DoubleConverter.REVERSE_INSTANCE)); addEditor(minY); figure.add(minY.getFigure(), minXdata); updateElements(getModel()!= null ? getModel().getElements() : Collections.<GraphElement> emptyList()); return figure; } public IFigure createVariablesFigure() { IFigure figure = new Figure(); GridLayout layout = new GridLayout(); layout.numColumns = 3; figure.setLayoutManager(layout); GridData minXdata = new GridData(); TextPartEditor minX = new TextPartEditor(); minX.bindValue(ConvertedObservableValue.from(fMinXValue, DoubleConverter.REVERSE_INSTANCE)); addEditor(minX); figure.add(minX.getFigure(), minXdata); GridData varsData = new GridData(); varsData.horizontalAlignment = GridData.CENTER; varsData.grabExcessHorizontalSpace = true; TextPartEditor vars = new TextPartEditor(); vars.bindValue(ConvertedObservableValue.from(fVariablesValue, new Converter<List<String>, String>() { @Override protected String doForward(List<String> variables) { StringBuilder sb = new StringBuilder(); for (String variable : variables) { if (sb.length() > 0) { sb.append(","); } sb.append(variable); } return sb.toString(); } @Override protected List<String> doBackward(String b) { String[] variables = b.split(","); return Arrays.asList(variables); } })); addEditor(vars); figure.add(vars.getFigure(), varsData); GridData maxXdata = new GridData(); maxXdata.horizontalAlignment = GridData.END; TextPartEditor maxX = new TextPartEditor(); maxX.bindValue(ConvertedObservableValue.from(fMaxXValue, DoubleConverter.REVERSE_INSTANCE)); addEditor(maxX); figure.add(maxX.getFigure(), maxXdata); return figure; } private void addElementComposite(final GraphElement graphElement) { GraphElementEditor elementEditor = new GraphElementEditor(fFormulaRenderer, fChartEditor.getDrawingSupplier(), fShellProvider); elementEditor.bindValue(DefaultObservableValue.fromValue(graphElement)); addEditor(elementEditor); editors.put(graphElement, elementEditor); fSeries.add(elementEditor.getFigure()); } public void addNewElement() { GraphElement newElement = new GraphElement(); newElement.setNumberOfPoints(100); newElement.setColor(getNextColor()); getModel().getElements().add(newElement); addElementComposite(newElement); } public void removeElement(GraphElement element) { GraphElementEditor editor = editors.get(element); fSeries.remove(editor.getFigure()); editor.dispose(); editors.remove(element); } private void updateElements(List<GraphElement> elements) { if (fSeries == null) { return; } for (GraphElementEditor editor: editors.values()) { fSeries.remove(editor.getFigure()); removeEditor(editor); editor.dispose(); } editors.clear(); for (GraphElement graphElement : elements) { addElementComposite(graphElement); } } public void bindGraphElementModel(IObservableValue<GraphModel> model) { setValue(Optional.of(model)); } @SuppressWarnings("serial") @Override protected void doBindValue(GraphModel value) { fMinXValue = new ObservableProperty<Double>(value, "minX", Double.class); fMaxXValue = new ObservableProperty<Double>(value, "maxX", Double.class); fMinYValue = new ObservableProperty<Double>(value, "minY", Double.class); fMaxYValue = new ObservableProperty<Double>(value, "maxY", Double.class); fVariablesValue = new ObservableProperty<List<String>>(value, "variables", new TypeToken<List<String>> (){}); fElementsValue = new ObservableProperty<List<GraphElement>>(value, "elements", new TypeToken<List<GraphElement>>() {}); fElementsValue.addObserver(fListener); } @Override protected void doUnbindValue(GraphModel oldValue) { fMaxXValue.dispose(); fMaxYValue.dispose(); fMinXValue.dispose(); fMinYValue.dispose(); fVariablesValue.dispose(); fElementsValue.dispose(); } @Override protected void onValueChanged(GraphModel oldValue, GraphModel newValue) { updateElements(newValue.getElements()); } public String getNextColor() { return PaintUtilities.colorToString((java.awt.Color) fChartEditor.getDrawingSupplier().getNextPaint()); } @Override public boolean isSelectable() { // TODO Auto-generated method stub return false; } @Override public void setSelected(boolean b) { // TODO Auto-generated method stub } @Override public void setActive(boolean b) { // TODO Auto-generated method stub } public void setResult(Map<Integer, double[][]> result) { fChartEditor.setResult(result); } public JFreeChart getChart() { return fChartEditor.getChart(); } }