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.Optional; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; 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.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Widget; import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.common.NamedResource; import org.simantics.db.common.request.UniqueRead; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.util.RemoverUtil; import org.simantics.db.procedure.Listener; import org.simantics.district.network.profile.ActiveDynamicVisualisationsRequest; import org.simantics.district.network.profile.DynamicVisualisationsRequest; import org.simantics.district.network.visualisations.DynamicVisualisations; import org.simantics.district.network.visualisations.DynamicVisualisationsContributions; import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicArrowObject; 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.DynamicArrowContribution; 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.utils.datastructures.Pair; import org.simantics.utils.ui.dialogs.ShowError; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class DynamicVisualisationsUI { private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationsUI.class); private Resource parentResource; private VisualisationListener listener; private DynamicVisualisation visualisation; private Button showSizeButton; private Button sizeTicksButton; private Button sizeGradientButton; private Combo sizeLocationCombo; private Combo sizeSizeCombo; private Button showColorButton; private Button colorTicksButton; private Button colorGradientButton; private Combo colorLocationCombo; private Combo colorSizeCombo; private Combo templateSelectionCombo; private List>> colorSuppliers; private Button removeVisualisationTemplateButton; private Composite parent; private Button disableUpdatesButton; private Button resetVisualisationButton; private Button hoveringVertexEnabledButton; private Button hoveringEdgesEnabledButton; private Button elevationServerEnabledButton; private Button notInSimulationButton; private List>> edgeArrowSuppliers; private Button saveVisualisationTemplateAsButton; private Button hideEdgesButton; private Button hidePointsButton; private Button hideConsumersButton; private Button hideProducersButton; private Button hideValvesButton; private Button hidePumpingStationsButton; private Button networkBranchesStaticPropertiesButton; private Button pointsStaticPropertiesButton; private Button consumersStaticPropertiesButton; private Button dynamicSymbolsEdgesButton; private Button dynamicSymbolsProducersButton; private Button dynamicSymbolsValvesButton; private Button dynamicSymbolsPumpingStationsButton; private Text intervalText; public DynamicVisualisationsUI(Composite parent) { this.parent = parent; ScrolledComposite scrolledComposite = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL); scrolledComposite.setLayout(new GridLayout(1, false)); scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Composite firstContent = new Composite(scrolledComposite, SWT.NONE); firstContent.setLayout(new GridLayout(1, false)); firstContent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); defaultInitializeUI(firstContent); scrolledComposite.setContent(firstContent); scrolledComposite.setExpandHorizontal(true); scrolledComposite.setExpandVertical(true); scrolledComposite.setMinSize(firstContent.computeSize(SWT.DEFAULT, SWT.DEFAULT)); } private void defaultInitializeUI(Composite parent) { GridDataFactory.fillDefaults().grab(true, true).applyTo(parent); GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5).applyTo(parent); Composite selectionComposite = new Composite(parent, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(selectionComposite); GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(selectionComposite); Label templateNameLabel = new Label(selectionComposite, SWT.NONE); templateNameLabel.setText("Visualisation template"); templateSelectionCombo = new Combo(selectionComposite, SWT.READ_ONLY); GridDataFactory.fillDefaults().grab(true, false).applyTo(templateSelectionCombo); templateSelectionCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { String item = templateSelectionCombo.getItem(templateSelectionCombo.getSelectionIndex()); for (NamedResource template : visualisations) { if (item.equals(template.getName())) { if (parentResource != null) { Resource res = parentResource; Simantics.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { Resource vf = DynamicVisualisations.getVisualisationFolder(graph, res); DynamicVisualisations.setActiveVisualisation(graph, vf, template.getResource()); } }); break; } } } } }); Composite intervalElementsComposite = new Composite(parent, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(intervalElementsComposite); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(intervalElementsComposite); initializeIntervalElements(intervalElementsComposite); Composite hoverElementsComposite = new Composite(parent, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(hoverElementsComposite); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(hoverElementsComposite); initializeHoverElements(hoverElementsComposite); Composite hideElementsComposite = new Composite(parent, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(hideElementsComposite); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(hideElementsComposite); initializeHideElements(hideElementsComposite); Composite staticPropertiesComposite = new Composite(parent, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(staticPropertiesComposite); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(staticPropertiesComposite); initializeStaticProperties(staticPropertiesComposite); Composite dynamicSymbolsComposite = new Composite(parent, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(dynamicSymbolsComposite); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(dynamicSymbolsComposite); initializeDynamicSymbols(dynamicSymbolsComposite); Composite coloringObjectsComposite = new Composite(parent, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(coloringObjectsComposite); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(coloringObjectsComposite); initializeColoringObjects(coloringObjectsComposite); Composite colorBarsComposite = new Composite(parent, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(colorBarsComposite); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(colorBarsComposite); initializeColorBars(colorBarsComposite); Composite objectSizesComposite = new Composite(parent, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(objectSizesComposite); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(objectSizesComposite); initializeObjectSizes(objectSizesComposite); Composite sizeBarsComposite = new Composite(parent, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(sizeBarsComposite); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(sizeBarsComposite); initializeSizeBars(sizeBarsComposite); Composite edgeArrowsComposite = new Composite(parent, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(edgeArrowsComposite); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(edgeArrowsComposite); initializeEdgeArrows(edgeArrowsComposite); Composite buttonBarsComposite = new Composite(parent, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(buttonBarsComposite); GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonBarsComposite); saveVisualisationTemplateAsButton = new Button(buttonBarsComposite, SWT.NONE); saveVisualisationTemplateAsButton.setText("Save as visualisation template"); saveVisualisationTemplateAsButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { showSaveVisualisationTemplateDialog(e.widget.getDisplay().getActiveShell()); } }); removeVisualisationTemplateButton = new Button(buttonBarsComposite, SWT.NONE); removeVisualisationTemplateButton.setText("Remove"); removeVisualisationTemplateButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null); removeVisualisationTemplateButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { removeVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource())); } }); } private void initializeIntervalElements(Composite parent) { Group group = new Group(parent, SWT.NONE); group.setText("Generic"); GridDataFactory.fillDefaults().grab(true, false).applyTo(group); GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(group); createIntervalElements(group); } private void createIntervalElements(Composite parent) { Label label = new Label(parent, SWT.NONE); label.setText("Interval (seconds)"); intervalText = new Text(parent, SWT.BORDER); GridDataFactory.fillDefaults().grab(true, false).applyTo(intervalText); addSelectionListener(intervalText); disableUpdatesButton = new Button(parent, SWT.CHECK); disableUpdatesButton.setText("Disable updates"); addSelectionListener(disableUpdatesButton); resetVisualisationButton = new Button(parent, SWT.CHECK); resetVisualisationButton.setText("Reset Visualisation"); addSelectionListener(resetVisualisationButton); notInSimulationButton = new Button(parent, SWT.CHECK); notInSimulationButton.setText("Not in Simulation"); addSelectionListener(notInSimulationButton); elevationServerEnabledButton = new Button(parent, SWT.CHECK); elevationServerEnabledButton.setText("Elevation Server Bounding Box"); addSelectionListener(elevationServerEnabledButton); } private void initializeHoverElements(Composite parent) { Group group = new Group(parent, SWT.NONE); group.setText("Hover"); GridDataFactory.fillDefaults().grab(true, false).applyTo(group); GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(group); createHoverElements(group); } private void createHoverElements(Composite parent) { hoveringVertexEnabledButton = new Button(parent, SWT.CHECK); hoveringVertexEnabledButton.setText("Vertex Key Variables on Hover"); addSelectionListener(hoveringVertexEnabledButton); hoveringEdgesEnabledButton = new Button(parent, SWT.CHECK); hoveringEdgesEnabledButton.setText("Edge Key Variables on Hover"); addSelectionListener(hoveringEdgesEnabledButton); } private void initializeHideElements(Composite parent) { Group group = new Group(parent, SWT.NONE); group.setText("Hide Elements"); GridDataFactory.fillDefaults().grab(true, false).applyTo(group); GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group); createHideElements(group); } private void createHideElements(Composite parent) { hideEdgesButton = new Button(parent, SWT.CHECK); hideEdgesButton.setText("Edges"); addSelectionListener(hideEdgesButton); hidePointsButton = new Button(parent, SWT.CHECK); hidePointsButton.setText("Points"); addSelectionListener(hidePointsButton); hideConsumersButton = new Button(parent, SWT.CHECK); hideConsumersButton.setText("Consumers"); addSelectionListener(hideConsumersButton); hideProducersButton = new Button(parent, SWT.CHECK); hideProducersButton.setText("Producers"); addSelectionListener(hideProducersButton); hideValvesButton = new Button(parent, SWT.CHECK); hideValvesButton.setText("Valves"); addSelectionListener(hideValvesButton); hidePumpingStationsButton = new Button(parent, SWT.CHECK); hidePumpingStationsButton.setText("Pumping Stations"); addSelectionListener(hidePumpingStationsButton); } private void initializeStaticProperties(Composite parent) { Group group = new Group(parent, SWT.NONE); group.setText("Static Properties"); GridDataFactory.fillDefaults().grab(true, false).applyTo(group); GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group); createStaticProperties(group); } private void createStaticProperties(Composite parent) { networkBranchesStaticPropertiesButton = new Button(parent, SWT.CHECK); networkBranchesStaticPropertiesButton.setText("Network Branches"); addSelectionListener(networkBranchesStaticPropertiesButton); pointsStaticPropertiesButton = new Button(parent, SWT.CHECK); pointsStaticPropertiesButton.setText("Points"); addSelectionListener(pointsStaticPropertiesButton); consumersStaticPropertiesButton = new Button(parent, SWT.CHECK); consumersStaticPropertiesButton.setText("Consumers"); addSelectionListener(consumersStaticPropertiesButton); } private void initializeDynamicSymbols(Composite parent) { Group group = new Group(parent, SWT.NONE); group.setText("Dynamic Symbols"); GridDataFactory.fillDefaults().grab(true, false).applyTo(group); GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group); createDynamicSymbols(group); } private void createDynamicSymbols(Composite parent) { dynamicSymbolsEdgesButton = new Button(parent, SWT.CHECK); dynamicSymbolsEdgesButton.setText("Shutoff Valves in Pipes"); addSelectionListener(dynamicSymbolsEdgesButton); dynamicSymbolsProducersButton = new Button(parent, SWT.CHECK); dynamicSymbolsProducersButton.setText("Producers"); addSelectionListener(dynamicSymbolsProducersButton); dynamicSymbolsValvesButton = new Button(parent, SWT.CHECK); dynamicSymbolsValvesButton.setText("Valves"); addSelectionListener(dynamicSymbolsValvesButton); dynamicSymbolsPumpingStationsButton = new Button(parent, SWT.CHECK); dynamicSymbolsPumpingStationsButton.setText("Pumping Stations"); addSelectionListener(dynamicSymbolsPumpingStationsButton); } private void initializeEdgeArrows(Composite parent) { Group group = new Group(parent, SWT.NONE); group.setText("Edge Arrows"); GridDataFactory.fillDefaults().grab(true, false).applyTo(group); GridLayoutFactory.fillDefaults().numColumns(6).margins(5, 5).applyTo(group); createEdgeArrowsHeaderRow(group); edgeArrowSuppliers = new ArrayList<>(); { try { Collection result = Simantics.getSession().syncRequest(new UniqueRead>() { @Override public Collection perform(ReadGraph graph) throws DatabaseException { return DynamicVisualisationsContributions.dynamicEdgeArrowObjects(graph); } }); for (DynamicArrowObject object : result) { edgeArrowSuppliers.add(createEdgeArrowRow(group, object)); } } catch (DatabaseException e) { LOGGER.error("Could not create coloring objecst", e); } } } private void createEdgeArrowsHeaderRow(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("Gain"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); label = new Label(parent, SWT.NONE); label.setText("Bias"); 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> createEdgeArrowRow(Composite parent, DynamicArrowObject object) { Map arrowContributions = object.getArrowContributions(); if (arrowContributions.isEmpty()) { // ok, no point in showing empty combo boxes return null; } Label label = new Label(parent, SWT.NONE); label.setText(object.getArrowObject().getName()); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label); Button usedButton = new Button(parent, SWT.CHECK); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton); addSelectionListener(usedButton); Combo variableCombo = new Combo(parent, SWT.READ_ONLY); variableCombo.setItems(arrowContributions.keySet().toArray(new String[arrowContributions.size()])); GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo); Text gainText = new Text(parent, SWT.BORDER); GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(gainText); addSelectionListener(gainText); Text biasText = new Text(parent, SWT.BORDER); GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(biasText); addSelectionListener(biasText); Button defaultButton = new Button(parent, SWT.CHECK); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton); defaultButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { int index = variableCombo.getSelectionIndex(); if (index >= 0) { String key = variableCombo.getItem(index); DynamicArrowContribution cont = arrowContributions.get(key); gainText.setText(Double.toString(cont.getDefaultGain())); gainText.setEnabled(!defaultButton.getSelection()); biasText.setText(Double.toString(cont.getDefaultBias())); biasText.setEnabled(!defaultButton.getSelection()); } } }); addSelectionListener(defaultButton); variableCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // handle update for others String key = variableCombo.getItem(variableCombo.getSelectionIndex()); DynamicArrowContribution cont = arrowContributions.get(key); if (gainText.getText().isEmpty()) { gainText.setText(Double.toString(cont.getDefaultGain())); } if (biasText.getText().isEmpty()) { biasText.setText(Double.toString(cont.getDefaultBias())); } defaultButton.setSelection(true); } }); addSelectionListener(variableCombo); arrowRows.put(object.getArrowObject().getName(), new ArrowObjectRow(label, usedButton, variableCombo, gainText, biasText, defaultButton)); return new Supplier>() { @Override public Pair get() { int selectionIndex = variableCombo.getSelectionIndex(); if (selectionIndex >= 0) { String key = variableCombo.getItem(selectionIndex); DynamicArrowContribution cont = arrowContributions.get(key); if (cont != null) { String label = variableCombo.getItem(variableCombo.getSelectionIndex()); double gain = cont.getDefaultGain(); String gainS = gainText.getText(); if (gainS != null && !gainS.isEmpty()) { gain = Double.parseDouble(gainS); } double bias = cont.getDefaultBias(); String biasS = biasText.getText(); if (biasS != null && !biasS.isEmpty()) { bias = Double.parseDouble(biasText.getText()); } DynamicArrowContribution dsc = new DynamicArrowContribution(label, cont.getModuleName(), cont.getAttributeName(), gain, bias); dsc.setUsed(usedButton.getSelection()); dsc.setUseDefault(defaultButton.getSelection()); return Pair.make(object.getArrowObject().getName(), dsc); } } return null; } }; } protected void removeVisualisationTemplate(String name, Optional of) { if (of.isPresent()) { Resource visualisation = of.get(); Simantics.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { RemoverUtil.remove(graph, visualisation); } }); } } private void showSaveVisualisationTemplateDialog(Shell shell) { InputDialog dialog = new InputDialog(shell, "Save visualisation template", "Give template a name", "", new IInputValidator() { @Override public String isValid(String newText) { if (newText == null || newText.isEmpty()) return "Name cannot be empty"; return null; } }); if (dialog.open() == Dialog.OK) { String name = dialog.getValue(); try { persistVisualisationTemplate(name, Optional.empty()); } catch (Exception e) { LOGGER.error("Could not persist visualisation template", e); ShowError.showError("Could not persist visualisation template", e.getMessage(), e); } } } private void persistCurrentVisualisationTemplateIfAvailable() { if (visualisation != null) { try { persistVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource())); } catch (Exception e1) { LOGGER.error("Could not persist visualisation template", e1); ShowError.showError("Could not persist visualisation template", e1.getMessage(), e1); } } else { LOGGER.info("No current visualisation template selected for saving"); } } private void persistVisualisationTemplate(String templateName, Optional existing) throws Exception { List> colorCollect = colorSuppliers.stream().filter(Objects::nonNull).map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList()); String colorLocation = colorLocationCombo.getItem(colorLocationCombo.getSelectionIndex()); String colorSize = colorSizeCombo.getItem(colorSizeCombo.getSelectionIndex()); ColorBarOptions colorBarOptions = new ColorBarOptions() .showColorBars(showColorButton.getSelection()) .showColorBarsTicks(colorTicksButton.getSelection()) .useGradients(colorGradientButton.getSelection()) .withLocation(ColorBarsLocation.valueOf(colorLocation)) .withSize(ColorBarsSize.valueOf(colorSize)); List> sizeCollect = sizeSuppliers.stream().filter(Objects::nonNull).map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList()); String sizeLocation = sizeLocationCombo.getItem(sizeLocationCombo.getSelectionIndex()); String sizeSize = sizeSizeCombo.getItem(sizeSizeCombo.getSelectionIndex()); final SizeBarOptions sizeBarOptions = new SizeBarOptions() .showSizeBars(showSizeButton.getSelection()) .showSizeBarsTicks(sizeTicksButton.getSelection()) .useGradients(sizeGradientButton.getSelection()) .withLocation(SizeBarsLocation.valueOf(sizeLocation)) .withSize(SizeBarsSize.valueOf(sizeSize)); List> edgeArrowCollect = edgeArrowSuppliers.stream().filter(Objects::nonNull).map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList()); boolean hideEdges = hideEdgesButton.getSelection(); boolean hidePoints = hidePointsButton.getSelection(); boolean hideConsumers = hideConsumersButton.getSelection(); boolean hideProducers = hideProducersButton.getSelection(); boolean hideValves = hideValvesButton.getSelection(); boolean hidePumpingStations = hidePumpingStationsButton.getSelection(); boolean networkBranchesStaticProperties = networkBranchesStaticPropertiesButton.getSelection(); boolean pointsStaticProperties = pointsStaticPropertiesButton.getSelection(); boolean consumersStaticProperties = consumersStaticPropertiesButton.getSelection(); boolean dynamicSymbolsEdges = dynamicSymbolsEdgesButton.getSelection(); boolean dynamicSymbolsProducers = dynamicSymbolsProducersButton.getSelection(); boolean dynamicSymbolsValves = dynamicSymbolsValvesButton.getSelection(); boolean dynamicSymbolsPumpingStations = dynamicSymbolsPumpingStationsButton.getSelection(); boolean disabled = disableUpdatesButton.getSelection(); boolean resetVisualisation = resetVisualisationButton.getSelection(); Long interval; try { // inteval is in milliseconds but shown as seconds interval = (long)(Double.parseDouble(intervalText.getText()) * 1000); } catch (NumberFormatException e) { // ignore interval = 2000L; } final long finalInterval = interval; boolean hoverVertex = hoveringVertexEnabledButton.getSelection(); boolean hoverEdges = hoveringEdgesEnabledButton.getSelection(); boolean elevationServerBoundingBox = elevationServerEnabledButton.getSelection(); boolean notInSimulation = notInSimulationButton.getSelection(); Simantics.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { Resource exist; if (existing.isPresent()) { exist = existing.get(); } else { exist = DynamicVisualisations.createVisualisation(graph, parentResource, templateName); } DynamicVisualisations.setIntervalAndDisabled(graph, exist, finalInterval, disabled, resetVisualisation); DynamicVisualisations.setColorContributions(graph, exist, colorCollect); DynamicVisualisations.setColorBarOptions(graph, exist, colorBarOptions); DynamicVisualisations.setSizeContributions(graph, exist, sizeCollect); DynamicVisualisations.setSizeBarOptions(graph, exist, sizeBarOptions); DynamicVisualisations.setEdgeArrowContributions(graph, exist, edgeArrowCollect); DynamicVisualisations.setHideElements(graph, exist, hideEdges, hidePoints, hideConsumers, hideProducers, hideValves, hidePumpingStations ); DynamicVisualisations.setStaticProperties(graph, exist, networkBranchesStaticProperties, pointsStaticProperties, consumersStaticProperties ); DynamicVisualisations.setDynamicSymbols(graph, exist, dynamicSymbolsEdges, dynamicSymbolsProducers, dynamicSymbolsValves, dynamicSymbolsPumpingStations ); DynamicVisualisations.setKeyVariablesHover(graph, exist, hoverVertex, hoverEdges); DynamicVisualisations.setElevationServerBoundingBox(graph, exist, elevationServerBoundingBox); DynamicVisualisations.setNotInSimulation(graph, exist, notInSimulation); } }); } 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); } colorSuppliers = new ArrayList<>(); { try { Pair, Map> result = Simantics.getSession().syncRequest(new UniqueRead, Map>>() { @Override public Pair, Map> perform(ReadGraph graph) throws DatabaseException { Map dynamicColorMaps = DynamicVisualisationsContributions.dynamicColorMaps(graph); return Pair.make(DynamicVisualisationsContributions.dynamicColoringObjects(graph), dynamicColorMaps); } }); for (DynamicColoringObject object : result.first) { colorSuppliers.add(createColoringObjectRow(group, object, result.second)); } } catch (DatabaseException e) { LOGGER.error("Could not create coloring objecst", e); } } } 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 coloringRows = new HashMap<>(); private Map sizingRows = new HashMap<>(); private Map arrowRows = new HashMap<>(); private VisualisationsListener visualisationsListener; private Collection visualisations; private List>> sizeSuppliers; 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 Text unit; private final Combo colorMapCombo; private final Button defaultButton; public ColoringObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Text 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()); String[] colorItems = colorMapCombo.getItems(); for (int i = 0; i < colorItems.length; i++) { if (colorContribution.getDefaultColorMap().getLabel().equals(colorItems[i])) { colorMapCombo.select(i); break; } } usedButton.setSelection(colorContribution.isUsed()); defaultButton.setSelection(colorContribution.isUseDefault()); minText.setEnabled(!colorContribution.isUseDefault()); maxText.setEnabled(!colorContribution.isUseDefault()); colorMapCombo.setEnabled(!colorContribution.isUseDefault()); } } 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()); String[] sizeItems = sizeMapCombo.getItems(); for (int i = 0; i < sizeItems.length; i++) { if (sizeContribution.getDefaultSizeMap().getLabel().equals(sizeItems[i])) { sizeMapCombo.select(i); break; } } usedButton.setSelection(sizeContribution.isUsed()); defaultButton.setSelection(sizeContribution.isUseDefault()); minText.setEnabled(!sizeContribution.isUseDefault()); maxText.setEnabled(!sizeContribution.isUseDefault()); sizeMapCombo.setEnabled(!sizeContribution.isUseDefault()); } } private static class ArrowObjectRow { private final Label label; private final Button usedButton; private final Combo variableCombo; private final Text gainText; private final Text biasText; private final Button defaultButton; public ArrowObjectRow(Label label, Button usedButton, Combo variableCombo, Text gainText, Text biasText, Button defaultButton) { this.label = label; this.usedButton = usedButton; this.variableCombo = variableCombo; this.gainText = gainText; this.biasText = biasText; 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; } } gainText.setText(Double.toString(colorContribution.getDefaultMin())); biasText.setText(Double.toString(colorContribution.getDefaultMax())); usedButton.setSelection(colorContribution.isUsed()); defaultButton.setSelection(colorContribution.isUseDefault()); gainText.setEnabled(!colorContribution.isUseDefault()); biasText.setEnabled(!colorContribution.isUseDefault()); } } private Supplier> createColoringObjectRow(Composite parent, DynamicColoringObject object, Map colorMaps) { Label label = new Label(parent, SWT.NONE); label.setText(object.getColoringObject().getName()); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label); Map colorContributions = object.getColorContributions(); Button usedButton = new Button(parent, SWT.CHECK); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton); addSelectionListener(usedButton); Combo variableCombo = new Combo(parent, SWT.READ_ONLY); variableCombo.setItems(colorContributions.keySet().toArray(new String[colorContributions.size()])); GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo); Text minText = new Text(parent, SWT.BORDER); GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(minText); addSelectionListener(minText); Text maxText = new Text(parent, SWT.BORDER); GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(maxText); addSelectionListener(maxText); Text unit = new Text(parent, SWT.READ_ONLY); GridDataFactory.fillDefaults().grab(true, false).hint(30, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(unit); Combo colorMapCombo = new Combo(parent, SWT.READ_ONLY); GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(colorMapCombo); colorMapCombo.setItems(colorMaps.keySet().toArray(new String[colorMaps.keySet().size()])); addSelectionListener(colorMapCombo); Button defaultButton = new Button(parent, SWT.CHECK); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton); defaultButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { int index = variableCombo.getSelectionIndex(); if (index >= 0) { String key = variableCombo.getItem(index); DynamicColorContribution cont = colorContributions.get(key); minText.setText(Double.toString(cont.getDefaultMin())); minText.setEnabled(!defaultButton.getSelection()); maxText.setText(Double.toString(cont.getDefaultMax())); maxText.setEnabled(!defaultButton.getSelection()); unit.setText(cont.getUnit()); String[] items = colorMapCombo.getItems(); for (int i = 0; i < items.length; i++) { String item = items[i]; if (item.equals(cont.getDefaultColorMap().getLabel())) { colorMapCombo.select(i); break; } } colorMapCombo.setEnabled(!defaultButton.getSelection()); } } }); addSelectionListener(defaultButton); variableCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // handle update for others int index = variableCombo.getSelectionIndex(); if (index >= 0) { String key = variableCombo.getItem(index); DynamicColorContribution cont = colorContributions.get(key); if (minText.getText().isEmpty()) { minText.setText(Double.toString(cont.getDefaultMin())); } if (maxText.getText().isEmpty()) { maxText.setText(Double.toString(cont.getDefaultMax())); } unit.setText(cont.getUnit()); String[] items = colorMapCombo.getItems(); for (int i = 0; i < items.length; i++) { String item = items[i]; if (item.equals(cont.getDefaultColorMap().getLabel())) { colorMapCombo.select(i); break; } } defaultButton.setSelection(true); } } }); addSelectionListener(variableCombo); coloringRows.put(object.getColoringObject().getName(), new ColoringObjectRow(label, usedButton, variableCombo, minText, maxText, unit, colorMapCombo, defaultButton)); return new Supplier>() { @Override public Pair get() { int selectionIndex = variableCombo.getSelectionIndex(); if (selectionIndex >= 0) { String key = variableCombo.getItem(selectionIndex); DynamicColorContribution cont = colorContributions.get(key); if (cont != null) { String label = variableCombo.getItem(variableCombo.getSelectionIndex()); DynamicColorContribution dcc; if (colorMapCombo.getSelectionIndex() > -1) { String colorMap = colorMapCombo.getItem(colorMapCombo.getSelectionIndex()); DynamicColorMap dColorMap = colorMaps.get(colorMap); dcc = new DynamicColorContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText())); } else { dcc = colorContributions.get(label); } dcc.setUsed(usedButton.getSelection()); dcc.setUseDefault(defaultButton.getSelection()); return Pair.make(object.getColoringObject().getName(), dcc); } } 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> createSizingObjectRow(Composite parent, DynamicSizingObject object, Map sizeMaps) { Label label = new Label(parent, SWT.NONE); label.setText(object.getSizingObject().getName()); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label); Map sizeContributions = object.getSizeContributions(); Button usedButton = new Button(parent, SWT.CHECK); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton); addSelectionListener(usedButton); Combo variableCombo = new Combo(parent, SWT.READ_ONLY); variableCombo.setItems(sizeContributions.keySet().toArray(new String[sizeContributions.size()])); GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo); Text minText = new Text(parent, SWT.BORDER); GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(minText); addSelectionListener(minText); Text maxText = new Text(parent, SWT.BORDER); GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(maxText); addSelectionListener(maxText); Label unit = new Label(parent, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).hint(30, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(unit); Combo sizeMapCombo = new Combo(parent, SWT.READ_ONLY); GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(sizeMapCombo); sizeMapCombo.setItems(sizeMaps.keySet().toArray(new String[sizeMaps.keySet().size()])); addSelectionListener(sizeMapCombo); Button defaultButton = new Button(parent, SWT.CHECK); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton); defaultButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { int index = variableCombo.getSelectionIndex(); if (index >= 0) { String key = variableCombo.getItem(index); DynamicSizeContribution cont = sizeContributions.get(key); minText.setText(Double.toString(cont.getDefaultMin())); minText.setEnabled(!defaultButton.getSelection()); maxText.setText(Double.toString(cont.getDefaultMax())); maxText.setEnabled(!defaultButton.getSelection()); unit.setText(cont.getUnit()); String[] items = sizeMapCombo.getItems(); for (int i = 0; i < items.length; i++) { String item = items[i]; if (item.equals(cont.getDefaultSizeMap().getLabel())) { sizeMapCombo.select(i); break; } } sizeMapCombo.setEnabled(!defaultButton.getSelection()); } } }); addSelectionListener(defaultButton); variableCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // handle update for others String key = variableCombo.getItem(variableCombo.getSelectionIndex()); DynamicSizeContribution cont = sizeContributions.get(key); if (minText.getText().isEmpty()) { minText.setText(Double.toString(cont.getDefaultMin())); } if (maxText.getText().isEmpty()) { maxText.setText(Double.toString(cont.getDefaultMax())); } unit.setText(cont.getUnit()); String[] items = sizeMapCombo.getItems(); for (int i = 0; i < items.length; i++) { String item = items[i]; if (item.equals(cont.getDefaultSizeMap().getLabel())) { sizeMapCombo.select(i); break; } } defaultButton.setSelection(true); } }); addSelectionListener(variableCombo); sizingRows.put(object.getSizingObject().getName(), new SizingObjectRow(label, usedButton, variableCombo, minText, maxText, unit, sizeMapCombo, defaultButton)); return new Supplier>() { @Override public Pair get() { int selectionIndex = variableCombo.getSelectionIndex(); if (selectionIndex >= 0) { String key = variableCombo.getItem(selectionIndex); DynamicSizeContribution cont = sizeContributions.get(key); if (cont != null) { String label = variableCombo.getItem(variableCombo.getSelectionIndex()); DynamicSizeContribution dsc; if (sizeMapCombo.getSelectionIndex() > -1) { String sizeMap = sizeMapCombo.getItem(sizeMapCombo.getSelectionIndex()); DynamicSizeMap dSizeMap = sizeMaps.get(sizeMap); dsc = new DynamicSizeContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dSizeMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText())); } else { dsc = sizeContributions.get(label); } dsc.setUsed(usedButton.getSelection()); dsc.setUseDefault(defaultButton.getSelection()); return Pair.make(object.getSizingObject().getName(), dsc); } } 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(8).margins(5, 5).applyTo(group); createColorBars(group); } private void createColorBars(Composite parent) { showColorButton = new Button(parent, SWT.CHECK); showColorButton.setText("Show"); addSelectionListener(showColorButton); colorTicksButton = new Button(parent, SWT.CHECK); colorTicksButton.setText("Ticks"); addSelectionListener(colorTicksButton); colorGradientButton = new Button(parent, SWT.CHECK); colorGradientButton.setText("Gradients"); addSelectionListener(colorGradientButton); Label label = new Label(parent, SWT.NONE); label.setText("Location"); colorLocationCombo = new Combo(parent, SWT.READ_ONLY); String[] colorLocationItems = Stream.of(ColorBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new); colorLocationCombo.setItems(colorLocationItems); if (colorLocationItems.length > 0) { colorLocationCombo.select(0); } addSelectionListener(colorLocationCombo); label = new Label(parent, SWT.NONE); label.setText("Size"); colorSizeCombo = new Combo(parent, SWT.READ_ONLY); String[] colorSizeItems = Stream.of(ColorBarsSize.values()).map(size -> size.toString()).toArray(String[]::new); colorSizeCombo.setItems(colorSizeItems); if (colorSizeItems.length > 0) { colorSizeCombo.select(0); } addSelectionListener(colorSizeCombo); } 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) { sizeSuppliers = new ArrayList<>(); try { Pair, Map> resultSizing = Simantics.getSession().syncRequest(new UniqueRead, Map>>() { @Override public Pair, Map> perform(ReadGraph graph) throws DatabaseException { Map dynamicSizeMaps = DynamicVisualisationsContributions.dynamicSizeMaps(graph); return Pair.make(DynamicVisualisationsContributions.dynamicSizingObjects(graph), dynamicSizeMaps); } }); for (DynamicSizingObject object : resultSizing.first) { sizeSuppliers.add(createSizingObjectRow(parent, object, resultSizing.second)); } } catch (DatabaseException e) { LOGGER.error("Could not create object sizes", e); } } 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(8).margins(5, 5).applyTo(group); createSizeBars(group); } private void createSizeBars(Composite parent) { showSizeButton = new Button(parent, SWT.CHECK); showSizeButton.setText("Show"); addSelectionListener(showSizeButton); sizeTicksButton = new Button(parent, SWT.CHECK); sizeTicksButton.setText("Ticks"); addSelectionListener(sizeTicksButton); sizeGradientButton = new Button(parent, SWT.CHECK); sizeGradientButton.setText("Gradient"); addSelectionListener(sizeGradientButton); Label label = new Label(parent, SWT.NONE); label.setText("Location"); sizeLocationCombo = new Combo(parent, SWT.READ_ONLY); String[] sizeLocationItems = Stream.of(SizeBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new); sizeLocationCombo.setItems(sizeLocationItems); if (sizeLocationItems.length > 0) { sizeLocationCombo.select(0); } addSelectionListener(sizeLocationCombo); label = new Label(parent, SWT.NONE); label.setText("Size"); sizeSizeCombo = new Combo(parent, SWT.READ_ONLY); String[] sizeSizeItems = Stream.of(SizeBarsSize.values()).map(size -> size.toString()).toArray(String[]::new); sizeSizeCombo.setItems(sizeSizeItems); if (sizeSizeItems.length > 0) { sizeSizeCombo.select(0); } addSelectionListener(sizeSizeCombo); } private void addSelectionListener(Widget widget) { if (widget instanceof Button) { ((Button) widget).addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { persistCurrentVisualisationTemplateIfAvailable(); } }); } else if (widget instanceof Combo) { ((Combo) widget).addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { persistCurrentVisualisationTemplateIfAvailable(); } }); } else if (widget instanceof Text) { ((Text) widget).addFocusListener(new FocusAdapter() { @Override public void focusLost(FocusEvent e) { persistCurrentVisualisationTemplateIfAvailable(); } }); ((Text) widget).addKeyListener(new KeyAdapter() { @Override public void keyReleased(KeyEvent e) { if(e.keyCode == SWT.CR || e.keyCode == SWT.LF) { persistCurrentVisualisationTemplateIfAvailable(); } } }); } } public void setParentResource(Resource parentResource) { if (this.parentResource != parentResource) { this.parentResource = parentResource; updateListening(); } saveVisualisationTemplateAsButton.setEnabled(parentResource != null); } private void updateListening() { if (visualisationsListener != null) visualisationsListener.dispose(); if (parentResource != null) { visualisationsListener = new VisualisationsListener(this); Simantics.getSession().asyncRequest(new DynamicVisualisationsRequest(parentResource), visualisationsListener); } if (listener != null) listener.dispose(); if (parentResource != null) { listener = new VisualisationListener(this); Simantics.getSession().asyncRequest(new ActiveDynamicVisualisationsRequest(parentResource), listener); } } private static class VisualisationsListener implements Listener> { private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationsListener.class); private boolean disposed; private DynamicVisualisationsUI ui; public VisualisationsListener(DynamicVisualisationsUI ui) { this.ui = ui; } @Override public void execute(Collection result) { ui.updateVisualisations(result); } @Override public void exception(Throwable t) { LOGGER.error("Could not listen visualisation", t); } @Override public boolean isDisposed() { return disposed || ui.getParent().isDisposed(); } public void dispose() { this.disposed = true; } } private static class VisualisationListener implements Listener { 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.getParent().isDisposed(); } public void dispose() { this.disposed = true; } } public void updateVisualisation(DynamicVisualisation result) { this.visualisation = result; Display.getDefault().asyncExec(() -> { if (getParent().isDisposed()) return; removeVisualisationTemplateButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null); if (visualisation != null) { String[] items = templateSelectionCombo.getItems(); for (int i = 0; i < items.length; i++) { if (visualisation.getName().equals(items[i])) { templateSelectionCombo.select(i); break; } } intervalText.setText(Double.toString(((double)visualisation.getInterval()) / 1000.0)); disableUpdatesButton.setSelection(visualisation.disabledUpdates()); hoveringVertexEnabledButton.setSelection(visualisation.isKeyVariablesVertexHover()); hoveringEdgesEnabledButton.setSelection(visualisation.isKeyVariablesEdgesHover()); hideConsumersButton.setSelection(visualisation.isHideConsumers()); hideEdgesButton.setSelection(visualisation.isHideEdges()); hideProducersButton.setSelection(visualisation.isHideProducers()); hideValvesButton.setSelection(visualisation.isHideValves()); hidePumpingStationsButton.setSelection(visualisation.isHidePumpingStations()); hidePointsButton.setSelection(visualisation.isHidePoints()); Map colorContributions = visualisation.getColorContributions(); for (Entry 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()); colorGradientButton.setSelection(colorOptions.isUseGradients()); 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 sizeContributions = visualisation.getSizeContributions(); for (Entry 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()); sizeGradientButton.setSelection(sizeOptions.isUseGradients()); 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; } } pointsStaticPropertiesButton.setSelection(visualisation.isStaticPropertiesPoints()); networkBranchesStaticPropertiesButton.setSelection(visualisation.isStaticPropertiesNetworkBranches()); consumersStaticPropertiesButton.setSelection(visualisation.isStaticPropertiesConsumers()); } }); } public void updateVisualisations(Collection result) { this.visualisations = result; Display.getDefault().asyncExec(() -> { if (getParent().isDisposed()) return; templateSelectionCombo.setItems(visualisations.stream().map(NamedResource::getName).collect(Collectors.toList()).toArray(new String[visualisations.size()])); if (visualisation != null) { String[] items = templateSelectionCombo.getItems(); for (int i = 0; i < items.length; i++) { if (visualisation.getName().equals(items[i])) { templateSelectionCombo.select(i); break; } } } }); } public Composite getParent() { return parent; } }