X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.district.network.ui%2Fsrc%2Forg%2Fsimantics%2Fdistrict%2Fnetwork%2Fui%2Fvisualisations%2FDynamicVisualisationsUI.java;h=a1b21629d4b21fbd914c90d29efd3797ddd65d5d;hb=2333f640dbaab4148fab8130515374aec9a27d9f;hp=4fe3d591ec9b2dbced9cfeac8084e3b7f5d8212d;hpb=dab24824da1b284b8a4734a069cfba72fb1f05de;p=simantics%2Fdistrict.git diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/visualisations/DynamicVisualisationsUI.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/visualisations/DynamicVisualisationsUI.java index 4fe3d591..a1b21629 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/visualisations/DynamicVisualisationsUI.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/visualisations/DynamicVisualisationsUI.java @@ -7,39 +7,56 @@ 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.ui.IEditorPart; +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.DistrictNetworkUtil; +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; @@ -48,108 +65,654 @@ 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.simantics.utils.ui.dialogs.ShowError; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class DynamicVisualisationsUI extends Composite { +public class DynamicVisualisationsUI { private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationsUI.class); - private Resource diagramResource; + 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; - public DynamicVisualisationsUI(Composite parent, int style) { - super(parent, style); + private Combo templateSelectionCombo; - defaultInitializeUI(); + private List>> colorSuppliers; + + private Button removeVisualisationTemplateButton; + + private Composite parent; + + private Button disableUpdatesButton; + private Button resetVisualisationButton; + private Button hoveringVertexEnabledButton; + private Button hoveringEdgesEnabledButton; + + 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() { - GridDataFactory.fillDefaults().grab(true, true).applyTo(this); - GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5).applyTo(this); + 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); - Composite coloringObjectsComposite = new Composite(this, SWT.NONE); + 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 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(this, SWT.NONE); + 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(this, SWT.NONE); + 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(this, SWT.NONE); + 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("Interval"); + GridDataFactory.fillDefaults().grab(true, false).applyTo(group); + GridLayoutFactory.fillDefaults().numColumns(6).margins(5, 5).applyTo(group); + + createIntervalElements(group); + } + + private void createIntervalElements(Composite parent) { - private void initializeColoringObjects(Composite parent) { + Label label = new Label(parent, SWT.NONE); + label.setText("Generic"); + intervalText = new Text(parent, SWT.BORDER); + 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); + + 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("Coloring Objects"); + group.setText("Hide Elements"); GridDataFactory.fillDefaults().grab(true, false).applyTo(group); GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group); - { - createColoringObjectHeaderRow(group); - } - List>> suppliers = new ArrayList<>(); + 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>() { + Collection result = Simantics.getSession().syncRequest(new UniqueRead>() { @Override - public Collection perform(ReadGraph graph) throws DatabaseException { - return DynamicVisualisationsContributions.dynamicColoringObjects(graph); + public Collection perform(ReadGraph graph) throws DatabaseException { + return DynamicVisualisationsContributions.dynamicEdgeArrowObjects(graph); } }); - for (DynamicColoringObject object : result) { - suppliers.add(createColoringObjectRow(group, object)); + for (DynamicArrowObject object : result) { + edgeArrowSuppliers.add(createEdgeArrowRow(group, object)); } - } catch (DatabaseException e) { - e.printStackTrace(); + LOGGER.error("Could not create coloring objecst", e); } } - { - Button applyButton = new Button(group, SWT.NONE); - applyButton.setText("Apply"); - applyButton.addSelectionListener(new SelectionAdapter() { + } + + + 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().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo); + + Text gainText = new Text(parent, SWT.BORDER); + GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(gainText); + addSelectionListener(gainText); + + Text biasText = new Text(parent, SWT.BORDER); + GridDataFactory.fillDefaults().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); - @Override - public void widgetSelected(SelectionEvent e) { - List> collect = suppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList()); - Simantics.getSession().asyncRequest(new WriteRequest() { + 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()); - @Override - public void perform(WriteGraph graph) throws DatabaseException { - DistrictNetworkUtil.setColorContributions(graph, DynamicVisualisationsUI.this.diagramResource, collect); + 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 { + interval = Long.parseLong(intervalText.getText()); + } catch (NumberFormatException e) { + // ignore + interval = 2000L; + } + final long finalInterval = interval; + + boolean hoverVertex = hoveringVertexEnabledButton.getSelection(); + boolean hoverEdges = hoveringEdgesEnabledButton.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); + } + }); + } + + 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) { @@ -188,6 +751,13 @@ public class DynamicVisualisationsUI extends Composite { 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 { @@ -196,11 +766,11 @@ public class DynamicVisualisationsUI extends Composite { private final Combo variableCombo; private final Text minText; private final Text maxText; - private final Label unit; + private final Text unit; private final Combo colorMapCombo; private final Button defaultButton; - public ColoringObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Label unit, + public ColoringObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Text unit, Combo colorMapCombo, Button defaultButton) { super(); this.label = label; @@ -225,17 +795,20 @@ public class DynamicVisualisationsUI extends Composite { 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; -// } -// } + 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()); } } @@ -275,21 +848,60 @@ public class DynamicVisualisationsUI extends Composite { 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; -// } -// } + 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 Supplier> createColoringObjectRow(Composite parent, DynamicColoringObject object) { + 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); @@ -298,6 +910,7 @@ public class DynamicVisualisationsUI extends Composite { 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()])); @@ -306,70 +919,109 @@ public class DynamicVisualisationsUI extends Composite { Text minText = new Text(parent, SWT.BORDER); GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(minText); + addSelectionListener(minText); Text maxText = new Text(parent, SWT.BORDER); GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(maxText); + addSelectionListener(maxText); - Label unit = new Label(parent, SWT.NONE); - unit.setText(""); - GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(unit); + Text unit = new Text(parent, SWT.READ_ONLY); + GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(unit); Combo colorMapCombo = new Combo(parent, SWT.READ_ONLY); GridDataFactory.fillDefaults().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 - - 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())); + 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); } - unit.setText(cont.getUnit()); - - colorMapCombo.setItems(cont.getDefaultColorMap().getLabel()); - colorMapCombo.select(0); - - 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() { - DynamicColorContribution cont = colorContributions.get(variableCombo.getText()); - if (cont != null) { - String colorMap = colorMapCombo.getItem(colorMapCombo.getSelectionIndex()); - try { - Map colorMaps = Simantics.getSession().syncRequest(new UniqueRead>() { - - @Override - public Map perform(ReadGraph graph) throws DatabaseException { - return DynamicVisualisationsContributions.dynamicColorMaps(graph); - } - }); - DynamicColorMap dColorMap = colorMaps.get(colorMap); - String label = variableCombo.getItem(variableCombo.getSelectionIndex()); + int selectionIndex = variableCombo.getSelectionIndex(); + if (selectionIndex >= 0) { + String key = variableCombo.getItem(selectionIndex); + DynamicColorContribution cont = colorContributions.get(key); + if (cont != null) { - DynamicColorContribution dcc = new DynamicColorContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText())); + 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); - } catch (DatabaseException e) { - LOGGER.error("Could not get DynamicColorContribution", e); } } return null; @@ -412,7 +1064,7 @@ public class DynamicVisualisationsUI extends Composite { GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); } - private Supplier> createSizingObjectRow(Composite parent, DynamicSizingObject object) { + 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); @@ -421,6 +1073,7 @@ public class DynamicVisualisationsUI extends Composite { 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()])); @@ -429,27 +1082,58 @@ public class DynamicVisualisationsUI extends Composite { Text minText = new Text(parent, SWT.BORDER); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(minText); + addSelectionListener(minText); Text maxText = new Text(parent, SWT.BORDER); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(maxText); + addSelectionListener(maxText); Label unit = new Label(parent, SWT.NONE); - unit.setText(""); - GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(unit); + GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(unit); Combo sizeMapCombo = new Combo(parent, SWT.READ_ONLY); GridDataFactory.fillDefaults().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 - - DynamicSizeContribution cont = sizeContributions.get(variableCombo.getText()); + String key = variableCombo.getItem(variableCombo.getSelectionIndex()); + DynamicSizeContribution cont = sizeContributions.get(key); if (minText.getText().isEmpty()) { minText.setText(Double.toString(cont.getDefaultMin())); @@ -459,12 +1143,19 @@ public class DynamicVisualisationsUI extends Composite { } unit.setText(cont.getUnit()); - sizeMapCombo.setItems(cont.getDefaultSizeMap().getLabel()); - sizeMapCombo.select(0); + 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)); @@ -472,27 +1163,25 @@ public class DynamicVisualisationsUI extends Composite { @Override public Pair get() { - DynamicSizeContribution cont = sizeContributions.get(variableCombo.getText()); - if (cont != null) { - String sizeMap = sizeMapCombo.getItem(sizeMapCombo.getSelectionIndex()); - try { - Map sizeMaps = Simantics.getSession().syncRequest(new UniqueRead>() { - - @Override - public Map perform(ReadGraph graph) throws DatabaseException { - return DynamicVisualisationsContributions.dynamicSizeMaps(graph); - } - }); - DynamicSizeMap dColorMap = sizeMaps.get(sizeMap); + 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 = new DynamicSizeContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText())); + 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); - } catch (DatabaseException e) { - LOGGER.error("Could not get DynamicColorContribution", e); } } return null; @@ -504,7 +1193,7 @@ public class DynamicVisualisationsUI extends Composite { 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); + GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group); createColorBars(group); } @@ -513,47 +1202,35 @@ public class DynamicVisualisationsUI extends Composite { 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); - colorLocationCombo.setItems(Stream.of(ColorBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new)); + 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); - 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); - } - }); - } - } - }); + 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) { @@ -570,40 +1247,22 @@ public class DynamicVisualisationsUI extends Composite { private void createObjectSizes(Composite parent) { - List>> suppliers = new ArrayList<>(); + sizeSuppliers = new ArrayList<>(); try { - Collection resultSizing = Simantics.getSession().syncRequest(new UniqueRead>() { + Pair, Map> resultSizing = Simantics.getSession().syncRequest(new UniqueRead, Map>>() { @Override - public Collection perform(ReadGraph graph) throws DatabaseException { - return DynamicVisualisationsContributions.dynamicSizingObjects(graph); + public Pair, Map> perform(ReadGraph graph) throws DatabaseException { + Map dynamicSizeMaps = DynamicVisualisationsContributions.dynamicSizeMaps(graph); + return Pair.make(DynamicVisualisationsContributions.dynamicSizingObjects(graph), dynamicSizeMaps); } }); - for (DynamicSizingObject object : resultSizing) { - suppliers.add(createSizingObjectRow(parent, object)); + for (DynamicSizingObject object : resultSizing.first) { + sizeSuppliers.add(createSizingObjectRow(parent, object, resultSizing.second)); } } 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> 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); - } - }); - } - }); + LOGGER.error("Could not create object sizes", e); } } @@ -611,7 +1270,7 @@ public class DynamicVisualisationsUI extends Composite { 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); + GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group); createSizeBars(group); } @@ -619,64 +1278,129 @@ public class DynamicVisualisationsUI extends Composite { 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); - sizeLocationCombo.setItems(Stream.of(SizeBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new)); + 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.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); - } - }); + 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 setDiagramResource(Resource diagramResource) { - if (this.diagramResource != diagramResource) { - this.diagramResource = diagramResource; + public void setParentResource(Resource parentResource) { + if (this.parentResource != parentResource) { + this.parentResource = parentResource; updateListening(); } + saveVisualisationTemplateAsButton.setEnabled(parentResource != null); } private void updateListening() { - if (listener != null) { + 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); } - listener = new VisualisationListener(this); - Simantics.getSession().asyncRequest(new DynamicVisualisationsRequest(diagramResource), 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); @@ -700,7 +1424,7 @@ public class DynamicVisualisationsUI extends Composite { @Override public boolean isDisposed() { - return disposed || ui.isDisposed(); + return disposed ||ui.getParent().isDisposed(); } public void dispose() { @@ -714,65 +1438,117 @@ public class DynamicVisualisationsUI extends Composite { if (getParent().isDisposed()) return; - Map colorContributions = visualisation.getColorContributions(); - for (Entry entry : colorContributions.entrySet()) { + 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; + } + } - ColoringObjectRow coloringObjectRow = coloringRows.get(entry.getKey()); - if (coloringObjectRow != null) { - - coloringObjectRow.update(entry.getValue()); + intervalText.setText(Long.toString(visualisation.getInterval())); + 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()) { - } else { - LOGGER.info("No coloring object visualisation row for key {}", entry.getKey()); + 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; + 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; + 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) { + Map sizeContributions = visualisation.getSizeContributions(); + for (Entry entry : sizeContributions.entrySet()) { - sizingObjectRow.update(entry.getValue()); - - } else { - LOGGER.info("No sizing object visualisation row for key {}", entry.getKey()); + 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; + 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; + } } } - for (int i = 0; i < sizeSizeCombo.getItems().length; i++) { - String item = sizeSizeCombo.getItem(i); - if (item.equals(sizeOptions.getSize().toString())) { - sizeSizeCombo.select(i); - break; + }); + } + + 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; + } }