--- /dev/null
+package org.simantics.district.network.ui.visualisations;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IEditorPart;
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.UniqueRead;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.procedure.Listener;
+import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.profile.DynamicVisualisationsRequest;
+import org.simantics.district.network.visualisations.DynamicVisualisationsContributions;
+import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicColoringObject;
+import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicSizingObject;
+import org.simantics.district.network.visualisations.model.ColorBarOptions;
+import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsLocation;
+import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsSize;
+import org.simantics.district.network.visualisations.model.DynamicColorContribution;
+import org.simantics.district.network.visualisations.model.DynamicColorMap;
+import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
+import org.simantics.district.network.visualisations.model.DynamicSizeMap;
+import org.simantics.district.network.visualisations.model.DynamicVisualisation;
+import org.simantics.district.network.visualisations.model.SizeBarOptions;
+import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsLocation;
+import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsSize;
+import org.simantics.ui.workbench.IResourceEditorPart;
+import org.simantics.utils.datastructures.Pair;
+import org.simantics.utils.ui.workbench.WorkbenchUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DynamicVisualisationsUI extends Composite {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationsUI.class);
+
+ private Resource diagramResource;
+ private VisualisationListener listener;
+ private DynamicVisualisation visualisation;
+
+ private Button showSizeButton;
+ private Button sizeTicksButton;
+ private Combo sizeLocationCombo;
+ private Combo sizeSizeCombo;
+ private Button showColorButton;
+ private Button colorTicksButton;
+ private Combo colorLocationCombo;
+ private Combo colorSizeCombo;
+
+ public DynamicVisualisationsUI(Composite parent, int style) {
+ super(parent, style);
+
+ defaultInitializeUI();
+ }
+
+ private void defaultInitializeUI() {
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(this);
+ GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5).applyTo(this);
+
+ Composite coloringObjectsComposite = new Composite(this, SWT.NONE);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(coloringObjectsComposite);
+ GridLayoutFactory.fillDefaults().numColumns(1).applyTo(coloringObjectsComposite);
+ initializeColoringObjects(coloringObjectsComposite);
+
+ Composite colorBarsComposite = new Composite(this, SWT.NONE);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(colorBarsComposite);
+ GridLayoutFactory.fillDefaults().numColumns(1).applyTo(colorBarsComposite);
+ initializeColorBars(colorBarsComposite);
+
+ Composite objectSizesComposite = new Composite(this, SWT.NONE);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(objectSizesComposite);
+ GridLayoutFactory.fillDefaults().numColumns(1).applyTo(objectSizesComposite);
+ initializeObjectSizes(objectSizesComposite);
+
+ Composite sizeBarsComposite = new Composite(this, SWT.NONE);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(sizeBarsComposite);
+ GridLayoutFactory.fillDefaults().numColumns(1).applyTo(sizeBarsComposite);
+ initializeSizeBars(sizeBarsComposite);
+
+ }
+
+ private void initializeColoringObjects(Composite parent) {
+ Group group = new Group(parent, SWT.NONE);
+ group.setText("Coloring Objects");
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
+ GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
+
+ {
+ createColoringObjectHeaderRow(group);
+ }
+ List<Supplier<Pair<String, DynamicColorContribution>>> suppliers = new ArrayList<>();
+ {
+ try {
+ Collection<DynamicColoringObject> result = Simantics.getSession().syncRequest(new UniqueRead<Collection<DynamicColoringObject>>() {
+
+ @Override
+ public Collection<DynamicColoringObject> perform(ReadGraph graph) throws DatabaseException {
+ return DynamicVisualisationsContributions.dynamicColoringObjects(graph);
+ }
+ });
+
+ for (DynamicColoringObject object : result) {
+ suppliers.add(createColoringObjectRow(group, object));
+ }
+
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ }
+ }
+ {
+ Button applyButton = new Button(group, SWT.NONE);
+ applyButton.setText("Apply");
+ applyButton.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ List<Pair<String, DynamicColorContribution>> collect = suppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ DistrictNetworkUtil.setColorContributions(graph, DynamicVisualisationsUI.this.diagramResource, collect);
+ }
+ });
+ }
+ });
+ }
+ }
+
+ private void createColoringObjectHeaderRow(Composite parent) {
+
+ Label label = new Label(parent, SWT.NONE);
+ label.setText("Label");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Used");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Variable");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Min");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Max");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Unit");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("ColorMap");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Default");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+ }
+
+ private Map<String, ColoringObjectRow> coloringRows = new HashMap<>();
+ private Map<String, SizingObjectRow> sizingRows = new HashMap<>();
+
+ private static class ColoringObjectRow {
+
+ private final Label label;
+ private final Button usedButton;
+ private final Combo variableCombo;
+ private final Text minText;
+ private final Text maxText;
+ private final Label unit;
+ private final Combo colorMapCombo;
+ private final Button defaultButton;
+
+ public ColoringObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Label unit,
+ Combo colorMapCombo, Button defaultButton) {
+ super();
+ this.label = label;
+ this.usedButton = usedButton;
+ this.variableCombo = variableCombo;
+ this.minText = minText;
+ this.maxText = maxText;
+ this.unit = unit;
+ this.colorMapCombo = colorMapCombo;
+ this.defaultButton = defaultButton;
+ }
+
+ public void update(DynamicColorContribution colorContribution) {
+ String[] items = variableCombo.getItems();
+ for (int i = 0; i < items.length; i++) {
+ if (colorContribution.getLabel().equals(items[i])) {
+ variableCombo.select(i);
+ break;
+ }
+ }
+ minText.setText(Double.toString(colorContribution.getDefaultMin()));
+ maxText.setText(Double.toString(colorContribution.getDefaultMax()));
+ unit.setText(colorContribution.getUnit());
+
+ // color map only supports single for now
+ colorMapCombo.setItems(colorContribution.getDefaultColorMap().getLabel());
+ colorMapCombo.select(0);
+// String[] colorItems = colorMapCombo.getItems();
+// for (int i = 0; i < colorItems.length; i++) {
+//
+// if (colorContribution.getDefaultColorMap().getLabel().equals(colorItems[i])) {
+// colorMapCombo.select(i);
+// break;
+// }
+// }
+ }
+ }
+
+ private static class SizingObjectRow {
+
+ private final Label label;
+ private final Button usedButton;
+ private final Combo variableCombo;
+ private final Text minText;
+ private final Text maxText;
+ private final Label unit;
+ private final Combo sizeMapCombo;
+ private final Button defaultButton;
+
+ public SizingObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Label unit,
+ Combo sizeMapCombo, Button defaultButton) {
+ super();
+ this.label = label;
+ this.usedButton = usedButton;
+ this.variableCombo = variableCombo;
+ this.minText = minText;
+ this.maxText = maxText;
+ this.unit = unit;
+ this.sizeMapCombo = sizeMapCombo;
+ this.defaultButton = defaultButton;
+ }
+
+ public void update(DynamicSizeContribution sizeContribution) {
+ String[] items = variableCombo.getItems();
+ for (int i = 0; i < items.length; i++) {
+ if (sizeContribution.getLabel().equals(items[i])) {
+ variableCombo.select(i);
+ break;
+ }
+ }
+ minText.setText(Double.toString(sizeContribution.getDefaultMin()));
+ maxText.setText(Double.toString(sizeContribution.getDefaultMax()));
+ unit.setText(sizeContribution.getUnit());
+
+ // color map only supports single for now
+ sizeMapCombo.setItems(sizeContribution.getDefaultSizeMap().getLabel());
+ sizeMapCombo.select(0);
+// String[] colorItems = colorMapCombo.getItems();
+// for (int i = 0; i < colorItems.length; i++) {
+//
+// if (colorContribution.getDefaultColorMap().getLabel().equals(colorItems[i])) {
+// colorMapCombo.select(i);
+// break;
+// }
+// }
+ }
+ }
+
+ private Supplier<Pair<String, DynamicColorContribution>> createColoringObjectRow(Composite parent, DynamicColoringObject object) {
+ Label label = new Label(parent, SWT.NONE);
+ label.setText(object.getColoringObject().getName());
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ Map<String, DynamicColorContribution> colorContributions = object.getColorContributions();
+
+ Button usedButton = new Button(parent, SWT.CHECK);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
+
+ Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
+ variableCombo.setItems(colorContributions.keySet().toArray(new String[colorContributions.size()]));
+
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
+
+ Text minText = new Text(parent, SWT.BORDER);
+ GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(minText);
+
+ Text maxText = new Text(parent, SWT.BORDER);
+ GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
+
+ Label unit = new Label(parent, SWT.NONE);
+ unit.setText("");
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(unit);
+
+ Combo colorMapCombo = new Combo(parent, SWT.READ_ONLY);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(colorMapCombo);
+
+ Button defaultButton = new Button(parent, SWT.CHECK);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
+
+ variableCombo.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // handle update for others
+
+ DynamicColorContribution cont = colorContributions.get(variableCombo.getText());
+
+ if (minText.getText().isEmpty()) {
+ minText.setText(Double.toString(cont.getDefaultMin()));
+ }
+ if (maxText.getText().isEmpty()) {
+ maxText.setText(Double.toString(cont.getDefaultMax()));
+ }
+ unit.setText(cont.getUnit());
+
+ colorMapCombo.setItems(cont.getDefaultColorMap().getLabel());
+ colorMapCombo.select(0);
+
+ defaultButton.setSelection(true);
+ }
+ });
+
+ coloringRows.put(object.getColoringObject().getName(), new ColoringObjectRow(label, usedButton, variableCombo, minText, maxText, unit, colorMapCombo, defaultButton));
+
+ return new Supplier<Pair<String, DynamicColorContribution>>() {
+
+ @Override
+ public Pair<String, DynamicColorContribution> get() {
+ DynamicColorContribution cont = colorContributions.get(variableCombo.getText());
+ if (cont != null) {
+ String colorMap = colorMapCombo.getItem(colorMapCombo.getSelectionIndex());
+ try {
+ Map<String, DynamicColorMap> colorMaps = Simantics.getSession().syncRequest(new UniqueRead<Map<String, DynamicColorMap>>() {
+
+ @Override
+ public Map<String, DynamicColorMap> perform(ReadGraph graph) throws DatabaseException {
+ return DynamicVisualisationsContributions.dynamicColorMaps(graph);
+ }
+ });
+ DynamicColorMap dColorMap = colorMaps.get(colorMap);
+ String label = variableCombo.getItem(variableCombo.getSelectionIndex());
+
+ DynamicColorContribution dcc = new DynamicColorContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
+ dcc.setUsed(usedButton.getSelection());
+ dcc.setUseDefault(defaultButton.getSelection());
+
+ return Pair.make(object.getColoringObject().getName(), dcc);
+ } catch (DatabaseException e) {
+ LOGGER.error("Could not get DynamicColorContribution", e);
+ }
+ }
+ return null;
+ }
+ };
+ }
+
+ private void createSizingObjectHeaderRow(Composite parent) {
+
+ Label label = new Label(parent, SWT.NONE);
+ label.setText("Label");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Used");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Variable");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Min");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Max");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Unit");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("SizeMap");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Default");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+ }
+
+ private Supplier<Pair<String, DynamicSizeContribution>> createSizingObjectRow(Composite parent, DynamicSizingObject object) {
+ Label label = new Label(parent, SWT.NONE);
+ label.setText(object.getSizingObject().getName());
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ Map<String, DynamicSizeContribution> sizeContributions = object.getSizeContributions();
+
+ Button usedButton = new Button(parent, SWT.CHECK);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
+
+ Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
+ variableCombo.setItems(sizeContributions.keySet().toArray(new String[sizeContributions.size()]));
+
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
+
+ Text minText = new Text(parent, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(minText);
+
+ Text maxText = new Text(parent, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
+
+ Label unit = new Label(parent, SWT.NONE);
+ unit.setText("");
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(unit);
+
+ Combo sizeMapCombo = new Combo(parent, SWT.READ_ONLY);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(sizeMapCombo);
+
+ Button defaultButton = new Button(parent, SWT.CHECK);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
+
+ variableCombo.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // handle update for others
+
+ DynamicSizeContribution cont = sizeContributions.get(variableCombo.getText());
+
+ if (minText.getText().isEmpty()) {
+ minText.setText(Double.toString(cont.getDefaultMin()));
+ }
+ if (maxText.getText().isEmpty()) {
+ maxText.setText(Double.toString(cont.getDefaultMax()));
+ }
+ unit.setText(cont.getUnit());
+
+ sizeMapCombo.setItems(cont.getDefaultSizeMap().getLabel());
+ sizeMapCombo.select(0);
+
+ defaultButton.setSelection(true);
+ }
+ });
+
+ sizingRows.put(object.getSizingObject().getName(), new SizingObjectRow(label, usedButton, variableCombo, minText, maxText, unit, sizeMapCombo, defaultButton));
+
+ return new Supplier<Pair<String, DynamicSizeContribution>>() {
+
+ @Override
+ public Pair<String, DynamicSizeContribution> get() {
+ DynamicSizeContribution cont = sizeContributions.get(variableCombo.getText());
+ if (cont != null) {
+ String sizeMap = sizeMapCombo.getItem(sizeMapCombo.getSelectionIndex());
+ try {
+ Map<String, DynamicSizeMap> sizeMaps = Simantics.getSession().syncRequest(new UniqueRead<Map<String, DynamicSizeMap>>() {
+
+ @Override
+ public Map<String, DynamicSizeMap> perform(ReadGraph graph) throws DatabaseException {
+ return DynamicVisualisationsContributions.dynamicSizeMaps(graph);
+ }
+ });
+ DynamicSizeMap dColorMap = sizeMaps.get(sizeMap);
+ String label = variableCombo.getItem(variableCombo.getSelectionIndex());
+
+ DynamicSizeContribution dsc = new DynamicSizeContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
+ dsc.setUsed(usedButton.getSelection());
+ dsc.setUseDefault(defaultButton.getSelection());
+
+ return Pair.make(object.getSizingObject().getName(), dsc);
+ } catch (DatabaseException e) {
+ LOGGER.error("Could not get DynamicColorContribution", e);
+ }
+ }
+ return null;
+ }
+ };
+ }
+
+ private void initializeColorBars(Composite parent) {
+ Group group = new Group(parent, SWT.NONE);
+ group.setText("Color Bars");
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
+ GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(group);
+
+ createColorBars(group);
+ }
+
+ private void createColorBars(Composite parent) {
+
+ showColorButton = new Button(parent, SWT.CHECK);
+ showColorButton.setText("Show");
+
+ colorTicksButton = new Button(parent, SWT.CHECK);
+ colorTicksButton.setText("Ticks");
+
+ Label label = new Label(parent, SWT.NONE);
+ label.setText("Location");
+ colorLocationCombo = new Combo(parent, SWT.READ_ONLY);
+ colorLocationCombo.setItems(Stream.of(ColorBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new));
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Size");
+ colorSizeCombo = new Combo(parent, SWT.READ_ONLY);
+ colorSizeCombo.setItems(Stream.of(ColorBarsSize.values()).map(size -> size.toString()).toArray(String[]::new));
+
+ Button applyButton = new Button(parent, SWT.NONE);
+ applyButton.setText("Apply");
+
+ applyButton.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // persist changes
+ IEditorPart activeEditor = WorkbenchUtils.getActiveEditor();
+ if (activeEditor instanceof IResourceEditorPart) {
+ Resource diagram = ((IResourceEditorPart) activeEditor).getResourceInput().getResource();
+ ColorBarOptions options = new ColorBarOptions()
+ .showColorBars(showColorButton.getSelection())
+ .showColorBarsTicks(colorTicksButton.getSelection())
+ .withLocation(ColorBarsLocation.valueOf(colorLocationCombo.getText().toUpperCase()))
+ .withSize(ColorBarsSize.valueOf(colorSizeCombo.getText().toUpperCase()));
+
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ DistrictNetworkUtil.setColorBarOptions(graph, diagram, options);
+ }
+ });
+ }
+ }
+ });
+ }
+
+ private void initializeObjectSizes(Composite parent) {
+ Group group = new Group(parent, SWT.NONE);
+ group.setText("Object Sizes");
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
+ GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
+
+ {
+ createSizingObjectHeaderRow(group);
+ createObjectSizes(group);
+ }
+ }
+
+ private void createObjectSizes(Composite parent) {
+
+ List<Supplier<Pair<String, DynamicSizeContribution>>> suppliers = new ArrayList<>();
+ try {
+ Collection<DynamicSizingObject> resultSizing = Simantics.getSession().syncRequest(new UniqueRead<Collection<DynamicSizingObject>>() {
+
+ @Override
+ public Collection<DynamicSizingObject> perform(ReadGraph graph) throws DatabaseException {
+ return DynamicVisualisationsContributions.dynamicSizingObjects(graph);
+ }
+ });
+
+ for (DynamicSizingObject object : resultSizing) {
+ suppliers.add(createSizingObjectRow(parent, object));
+ }
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ }
+
+ {
+ Button applyButton = new Button(parent, SWT.NONE);
+ applyButton.setText("Apply");
+ applyButton.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ List<Pair<String, DynamicSizeContribution>> collect = suppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ DistrictNetworkUtil.setSizeContributions(graph, DynamicVisualisationsUI.this.diagramResource, collect);
+ }
+ });
+ }
+ });
+ }
+ }
+
+ private void initializeSizeBars(Composite parent) {
+ Group group = new Group(parent, SWT.NONE);
+ group.setText("Size Bars");
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
+ GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(group);
+
+ createSizeBars(group);
+ }
+
+ private void createSizeBars(Composite parent) {
+ showSizeButton = new Button(parent, SWT.CHECK);
+ showSizeButton.setText("Show");
+
+ sizeTicksButton = new Button(parent, SWT.CHECK);
+ sizeTicksButton.setText("Ticks");
+
+ Label label = new Label(parent, SWT.NONE);
+ label.setText("Location");
+ sizeLocationCombo = new Combo(parent, SWT.READ_ONLY);
+ sizeLocationCombo.setItems(Stream.of(SizeBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new));
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Size");
+ sizeSizeCombo = new Combo(parent, SWT.NONE);
+ sizeSizeCombo.setItems(Stream.of(SizeBarsSize.values()).map(size -> size.toString()).toArray(String[]::new));
+
+ Button applyButton = new Button(parent, SWT.READ_ONLY);
+ applyButton.setText("Apply");
+
+ applyButton.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // persist changes
+ IEditorPart activeEditor = WorkbenchUtils.getActiveEditor();
+ if (activeEditor instanceof IResourceEditorPart) {
+ Resource diagram = ((IResourceEditorPart) activeEditor).getResourceInput().getResource();
+ SizeBarOptions options = new SizeBarOptions()
+ .showSizeBars(showSizeButton.getSelection())
+ .showSizeBarsTicks(sizeTicksButton.getSelection())
+ .withLocation(SizeBarsLocation.valueOf(sizeLocationCombo.getText().toUpperCase()))
+ .withSize(SizeBarsSize.valueOf(sizeSizeCombo.getText().toUpperCase()));
+
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ DistrictNetworkUtil.setSizeBarOptions(graph, diagram, options);
+ }
+ });
+ }
+ }
+ });
+ }
+
+ public void setDiagramResource(Resource diagramResource) {
+ if (this.diagramResource != diagramResource) {
+ this.diagramResource = diagramResource;
+ updateListening();
+ }
+ }
+
+ private void updateListening() {
+ if (listener != null) {
+ listener.dispose();
+ }
+ listener = new VisualisationListener(this);
+ Simantics.getSession().asyncRequest(new DynamicVisualisationsRequest(diagramResource), listener);
+ }
+
+ private static class VisualisationListener implements Listener<DynamicVisualisation> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationListener.class);
+
+ private boolean disposed;
+ private DynamicVisualisationsUI ui;
+
+ public VisualisationListener(DynamicVisualisationsUI ui) {
+ this.ui = ui;
+ }
+
+ @Override
+ public void execute(DynamicVisualisation result) {
+ ui.updateVisualisation(result);
+ }
+
+ @Override
+ public void exception(Throwable t) {
+ LOGGER.error("Could not listen visualisation", t);
+ }
+
+ @Override
+ public boolean isDisposed() {
+ return disposed || ui.isDisposed();
+ }
+
+ public void dispose() {
+ this.disposed = true;
+ }
+ }
+
+ public void updateVisualisation(DynamicVisualisation result) {
+ this.visualisation = result;
+ Display.getDefault().asyncExec(() -> {
+ if (getParent().isDisposed())
+ return;
+
+ Map<String, DynamicColorContribution> colorContributions = visualisation.getColorContributions();
+ for (Entry<String, DynamicColorContribution> entry : colorContributions.entrySet()) {
+
+ ColoringObjectRow coloringObjectRow = coloringRows.get(entry.getKey());
+ if (coloringObjectRow != null) {
+
+ coloringObjectRow.update(entry.getValue());
+
+ } else {
+ LOGGER.info("No coloring object visualisation row for key {}", entry.getKey());
+ }
+ }
+ ColorBarOptions colorOptions = visualisation.getColorBarOptions();
+ showColorButton.setSelection(colorOptions.isShowColorBars());
+ colorTicksButton.setSelection(colorOptions.isShowColorBarsTicks());
+ for (int i = 0; i < colorLocationCombo.getItems().length; i++) {
+ String item = colorLocationCombo.getItem(i);
+ if (item.equals(colorOptions.getLocation().toString())) {
+ colorLocationCombo.select(i);
+ break;
+ }
+ }
+ for (int i = 0; i < colorSizeCombo.getItems().length; i++) {
+ String item = colorSizeCombo.getItem(i);
+ if (item.equals(colorOptions.getSize().toString())) {
+ colorSizeCombo.select(i);
+ break;
+ }
+ }
+
+ Map<String, DynamicSizeContribution> sizeContributions = visualisation.getSizeContributions();
+ for (Entry<String, DynamicSizeContribution> entry : sizeContributions.entrySet()) {
+
+ SizingObjectRow sizingObjectRow = sizingRows.get(entry.getKey());
+ if (sizingObjectRow != null) {
+
+ sizingObjectRow.update(entry.getValue());
+
+ } else {
+ LOGGER.info("No sizing object visualisation row for key {}", entry.getKey());
+ }
+ }
+ SizeBarOptions sizeOptions = visualisation.getSizeBarOptions();
+ showSizeButton.setSelection(sizeOptions.isShowSizeBars());
+ sizeTicksButton.setSelection(sizeOptions.isShowSizeBarsTicks());
+ for (int i = 0; i < sizeLocationCombo.getItems().length; i++) {
+ String item = sizeLocationCombo.getItem(i);
+ if (item.equals(sizeOptions.getLocation().toString())) {
+ sizeLocationCombo.select(i);
+ break;
+ }
+ }
+ for (int i = 0; i < sizeSizeCombo.getItems().length; i++) {
+ String item = sizeSizeCombo.getItem(i);
+ if (item.equals(sizeOptions.getSize().toString())) {
+ sizeSizeCombo.select(i);
+ break;
+ }
+ }
+ });
+ }
+}