1 package org.simantics.district.network.ui.visualisations;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashMap;
8 import java.util.Map.Entry;
9 import java.util.Objects;
10 import java.util.Optional;
11 import java.util.function.Supplier;
12 import java.util.stream.Collectors;
13 import java.util.stream.Stream;
15 import org.eclipse.jface.dialogs.Dialog;
16 import org.eclipse.jface.dialogs.IInputValidator;
17 import org.eclipse.jface.dialogs.InputDialog;
18 import org.eclipse.jface.layout.GridDataFactory;
19 import org.eclipse.jface.layout.GridLayoutFactory;
20 import org.eclipse.swt.SWT;
21 import org.eclipse.swt.custom.ScrolledComposite;
22 import org.eclipse.swt.events.FocusAdapter;
23 import org.eclipse.swt.events.FocusEvent;
24 import org.eclipse.swt.events.KeyAdapter;
25 import org.eclipse.swt.events.KeyEvent;
26 import org.eclipse.swt.events.SelectionAdapter;
27 import org.eclipse.swt.events.SelectionEvent;
28 import org.eclipse.swt.layout.GridData;
29 import org.eclipse.swt.layout.GridLayout;
30 import org.eclipse.swt.widgets.Button;
31 import org.eclipse.swt.widgets.Combo;
32 import org.eclipse.swt.widgets.Composite;
33 import org.eclipse.swt.widgets.Display;
34 import org.eclipse.swt.widgets.Group;
35 import org.eclipse.swt.widgets.Label;
36 import org.eclipse.swt.widgets.Shell;
37 import org.eclipse.swt.widgets.Text;
38 import org.eclipse.swt.widgets.Widget;
39 import org.simantics.Simantics;
40 import org.simantics.db.ReadGraph;
41 import org.simantics.db.Resource;
42 import org.simantics.db.WriteGraph;
43 import org.simantics.db.common.NamedResource;
44 import org.simantics.db.common.request.UniqueRead;
45 import org.simantics.db.common.request.WriteRequest;
46 import org.simantics.db.exception.DatabaseException;
47 import org.simantics.db.layer0.util.RemoverUtil;
48 import org.simantics.db.procedure.Listener;
49 import org.simantics.district.network.profile.ActiveDynamicVisualisationsRequest;
50 import org.simantics.district.network.profile.DynamicVisualisationsRequest;
51 import org.simantics.district.network.visualisations.DynamicVisualisations;
52 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions;
53 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicArrowObject;
54 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicColoringObject;
55 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicSizingObject;
56 import org.simantics.district.network.visualisations.model.ColorBarOptions;
57 import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsLocation;
58 import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsSize;
59 import org.simantics.district.network.visualisations.model.DynamicArrowContribution;
60 import org.simantics.district.network.visualisations.model.DynamicColorContribution;
61 import org.simantics.district.network.visualisations.model.DynamicColorMap;
62 import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
63 import org.simantics.district.network.visualisations.model.DynamicSizeMap;
64 import org.simantics.district.network.visualisations.model.DynamicVisualisation;
65 import org.simantics.district.network.visualisations.model.SizeBarOptions;
66 import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsLocation;
67 import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsSize;
68 import org.simantics.utils.datastructures.Pair;
69 import org.simantics.utils.ui.dialogs.ShowError;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
73 public class DynamicVisualisationsUI {
75 private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationsUI.class);
77 private Resource parentResource;
78 private VisualisationListener listener;
79 private DynamicVisualisation visualisation;
81 private Button showSizeButton;
82 private Button sizeTicksButton;
83 private Button sizeGradientButton;
84 private Combo sizeLocationCombo;
85 private Combo sizeSizeCombo;
86 private Button showColorButton;
87 private Button colorTicksButton;
88 private Button colorGradientButton;
89 private Combo colorLocationCombo;
90 private Combo colorSizeCombo;
92 private Combo templateSelectionCombo;
94 private List<Supplier<Pair<String, DynamicColorContribution>>> colorSuppliers;
96 private Button removeVisualisationTemplateButton;
98 private Composite parent;
100 private Button disableUpdatesButton;
101 private Button resetVisualisationButton;
102 private Button hoveringVertexEnabledButton;
103 private Button hoveringEdgesEnabledButton;
104 private Button elevationServerEnabledButton;
105 private Button notInSimulationButton;
106 private Button showConnectedComponentsButton;
108 private List<Supplier<Pair<String, DynamicArrowContribution>>> edgeArrowSuppliers;
110 private Button saveVisualisationTemplateAsButton;
112 private Button hideEdgesButton;
113 private Button hidePointsButton;
114 private Button hideConsumersButton;
115 private Button hideProducersButton;
116 private Button hideValvesButton;
117 private Button hidePumpingStationsButton;
119 private Button networkBranchesStaticPropertiesButton;
120 private Button pointsStaticPropertiesButton;
121 private Button consumersStaticPropertiesButton;
123 private Button dynamicSymbolsEdgesButton;
124 private Button dynamicSymbolsProducersButton;
125 private Button dynamicSymbolsValvesButton;
126 private Button dynamicSymbolsPumpingStationsButton;
128 private Text intervalText;
130 public DynamicVisualisationsUI(Composite parent) {
131 this.parent = parent;
132 ScrolledComposite scrolledComposite = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
133 scrolledComposite.setLayout(new GridLayout(1, false));
134 scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
136 Composite firstContent = new Composite(scrolledComposite, SWT.NONE);
137 firstContent.setLayout(new GridLayout(1, false));
138 firstContent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
140 defaultInitializeUI(firstContent);
142 scrolledComposite.setContent(firstContent);
143 scrolledComposite.setExpandHorizontal(true);
144 scrolledComposite.setExpandVertical(true);
145 scrolledComposite.setMinSize(firstContent.computeSize(SWT.DEFAULT, SWT.DEFAULT));
148 private void defaultInitializeUI(Composite parent) {
150 GridDataFactory.fillDefaults().grab(true, true).applyTo(parent);
151 GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5).applyTo(parent);
153 Composite selectionComposite = new Composite(parent, SWT.NONE);
154 GridDataFactory.fillDefaults().grab(true, false).applyTo(selectionComposite);
155 GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(selectionComposite);
157 Label templateNameLabel = new Label(selectionComposite, SWT.NONE);
158 templateNameLabel.setText("Visualisation template");
159 templateSelectionCombo = new Combo(selectionComposite, SWT.READ_ONLY);
160 GridDataFactory.fillDefaults().grab(true, false).applyTo(templateSelectionCombo);
161 templateSelectionCombo.addSelectionListener(new SelectionAdapter() {
164 public void widgetSelected(SelectionEvent e) {
165 String item = templateSelectionCombo.getItem(templateSelectionCombo.getSelectionIndex());
166 for (NamedResource template : visualisations) {
167 if (item.equals(template.getName())) {
168 if (parentResource != null) {
169 Resource res = parentResource;
170 Simantics.getSession().asyncRequest(new WriteRequest() {
173 public void perform(WriteGraph graph) throws DatabaseException {
174 Resource vf = DynamicVisualisations.getVisualisationFolder(graph, res);
175 DynamicVisualisations.setActiveVisualisation(graph, vf, template.getResource());
185 Composite intervalElementsComposite = new Composite(parent, SWT.NONE);
186 GridDataFactory.fillDefaults().grab(true, false).applyTo(intervalElementsComposite);
187 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(intervalElementsComposite);
188 initializeIntervalElements(intervalElementsComposite);
190 Composite hoverElementsComposite = new Composite(parent, SWT.NONE);
191 GridDataFactory.fillDefaults().grab(true, false).applyTo(hoverElementsComposite);
192 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(hoverElementsComposite);
193 initializeHoverElements(hoverElementsComposite);
195 Composite hideElementsComposite = new Composite(parent, SWT.NONE);
196 GridDataFactory.fillDefaults().grab(true, false).applyTo(hideElementsComposite);
197 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(hideElementsComposite);
198 initializeHideElements(hideElementsComposite);
200 Composite staticPropertiesComposite = new Composite(parent, SWT.NONE);
201 GridDataFactory.fillDefaults().grab(true, false).applyTo(staticPropertiesComposite);
202 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(staticPropertiesComposite);
203 initializeStaticProperties(staticPropertiesComposite);
205 Composite dynamicSymbolsComposite = new Composite(parent, SWT.NONE);
206 GridDataFactory.fillDefaults().grab(true, false).applyTo(dynamicSymbolsComposite);
207 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(dynamicSymbolsComposite);
208 initializeDynamicSymbols(dynamicSymbolsComposite);
210 Composite coloringObjectsComposite = new Composite(parent, SWT.NONE);
211 GridDataFactory.fillDefaults().grab(true, false).applyTo(coloringObjectsComposite);
212 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(coloringObjectsComposite);
213 initializeColoringObjects(coloringObjectsComposite);
215 Composite colorBarsComposite = new Composite(parent, SWT.NONE);
216 GridDataFactory.fillDefaults().grab(true, false).applyTo(colorBarsComposite);
217 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(colorBarsComposite);
218 initializeColorBars(colorBarsComposite);
220 Composite objectSizesComposite = new Composite(parent, SWT.NONE);
221 GridDataFactory.fillDefaults().grab(true, false).applyTo(objectSizesComposite);
222 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(objectSizesComposite);
223 initializeObjectSizes(objectSizesComposite);
225 Composite sizeBarsComposite = new Composite(parent, SWT.NONE);
226 GridDataFactory.fillDefaults().grab(true, false).applyTo(sizeBarsComposite);
227 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(sizeBarsComposite);
228 initializeSizeBars(sizeBarsComposite);
230 Composite edgeArrowsComposite = new Composite(parent, SWT.NONE);
231 GridDataFactory.fillDefaults().grab(true, false).applyTo(edgeArrowsComposite);
232 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(edgeArrowsComposite);
233 initializeEdgeArrows(edgeArrowsComposite);
235 Composite buttonBarsComposite = new Composite(parent, SWT.NONE);
236 GridDataFactory.fillDefaults().grab(true, false).applyTo(buttonBarsComposite);
237 GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonBarsComposite);
239 saveVisualisationTemplateAsButton = new Button(buttonBarsComposite, SWT.NONE);
240 saveVisualisationTemplateAsButton.setText("Save as visualisation template");
241 saveVisualisationTemplateAsButton.addSelectionListener(new SelectionAdapter() {
244 public void widgetSelected(SelectionEvent e) {
245 showSaveVisualisationTemplateDialog(e.widget.getDisplay().getActiveShell());
249 removeVisualisationTemplateButton = new Button(buttonBarsComposite, SWT.NONE);
250 removeVisualisationTemplateButton.setText("Remove");
251 removeVisualisationTemplateButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null);
252 removeVisualisationTemplateButton.addSelectionListener(new SelectionAdapter() {
255 public void widgetSelected(SelectionEvent e) {
256 removeVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
261 private void initializeIntervalElements(Composite parent) {
262 Group group = new Group(parent, SWT.NONE);
263 group.setText("Generic");
264 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
265 GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(group);
267 createIntervalElements(group);
270 private void createIntervalElements(Composite parent) {
272 Label label = new Label(parent, SWT.NONE);
273 label.setText("Interval (seconds)");
274 intervalText = new Text(parent, SWT.BORDER);
275 GridDataFactory.fillDefaults().grab(true, false).applyTo(intervalText);
276 addSelectionListener(intervalText);
278 disableUpdatesButton = new Button(parent, SWT.CHECK);
279 disableUpdatesButton.setText("Disable updates");
280 addSelectionListener(disableUpdatesButton);
282 resetVisualisationButton = new Button(parent, SWT.CHECK);
283 resetVisualisationButton.setText("Reset Visualisation");
284 addSelectionListener(resetVisualisationButton);
286 notInSimulationButton = new Button(parent, SWT.CHECK);
287 notInSimulationButton.setText("Not in Simulation");
288 addSelectionListener(notInSimulationButton);
290 elevationServerEnabledButton = new Button(parent, SWT.CHECK);
291 elevationServerEnabledButton.setText("Elevation Server Bounding Box");
292 addSelectionListener(elevationServerEnabledButton);
294 showConnectedComponentsButton = new Button(parent, SWT.CHECK);
295 showConnectedComponentsButton.setText("Show Connected Components");
296 addSelectionListener(showConnectedComponentsButton);
299 private void initializeHoverElements(Composite parent) {
300 Group group = new Group(parent, SWT.NONE);
301 group.setText("Hover");
302 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
303 GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(group);
305 createHoverElements(group);
308 private void createHoverElements(Composite parent) {
309 hoveringVertexEnabledButton = new Button(parent, SWT.CHECK);
310 hoveringVertexEnabledButton.setText("Vertex Key Variables on Hover");
311 addSelectionListener(hoveringVertexEnabledButton);
313 hoveringEdgesEnabledButton = new Button(parent, SWT.CHECK);
314 hoveringEdgesEnabledButton.setText("Edge Key Variables on Hover");
315 addSelectionListener(hoveringEdgesEnabledButton);
318 private void initializeHideElements(Composite parent) {
319 Group group = new Group(parent, SWT.NONE);
320 group.setText("Hide Elements");
321 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
322 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
324 createHideElements(group);
327 private void createHideElements(Composite parent) {
329 hideEdgesButton = new Button(parent, SWT.CHECK);
330 hideEdgesButton.setText("Edges");
331 addSelectionListener(hideEdgesButton);
333 hidePointsButton = new Button(parent, SWT.CHECK);
334 hidePointsButton.setText("Points");
335 addSelectionListener(hidePointsButton);
337 hideConsumersButton = new Button(parent, SWT.CHECK);
338 hideConsumersButton.setText("Consumers");
339 addSelectionListener(hideConsumersButton);
341 hideProducersButton = new Button(parent, SWT.CHECK);
342 hideProducersButton.setText("Producers");
343 addSelectionListener(hideProducersButton);
345 hideValvesButton = new Button(parent, SWT.CHECK);
346 hideValvesButton.setText("Valves");
347 addSelectionListener(hideValvesButton);
349 hidePumpingStationsButton = new Button(parent, SWT.CHECK);
350 hidePumpingStationsButton.setText("Pumping Stations");
351 addSelectionListener(hidePumpingStationsButton);
354 private void initializeStaticProperties(Composite parent) {
355 Group group = new Group(parent, SWT.NONE);
356 group.setText("Static Properties");
357 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
358 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
360 createStaticProperties(group);
363 private void createStaticProperties(Composite parent) {
365 networkBranchesStaticPropertiesButton = new Button(parent, SWT.CHECK);
366 networkBranchesStaticPropertiesButton.setText("Network Branches");
367 addSelectionListener(networkBranchesStaticPropertiesButton);
369 pointsStaticPropertiesButton = new Button(parent, SWT.CHECK);
370 pointsStaticPropertiesButton.setText("Points");
371 addSelectionListener(pointsStaticPropertiesButton);
373 consumersStaticPropertiesButton = new Button(parent, SWT.CHECK);
374 consumersStaticPropertiesButton.setText("Consumers");
375 addSelectionListener(consumersStaticPropertiesButton);
379 private void initializeDynamicSymbols(Composite parent) {
380 Group group = new Group(parent, SWT.NONE);
381 group.setText("Dynamic Symbols");
382 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
383 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
385 createDynamicSymbols(group);
388 private void createDynamicSymbols(Composite parent) {
390 dynamicSymbolsEdgesButton = new Button(parent, SWT.CHECK);
391 dynamicSymbolsEdgesButton.setText("Shutoff Valves in Pipes");
392 addSelectionListener(dynamicSymbolsEdgesButton);
394 dynamicSymbolsProducersButton = new Button(parent, SWT.CHECK);
395 dynamicSymbolsProducersButton.setText("Producers");
396 addSelectionListener(dynamicSymbolsProducersButton);
398 dynamicSymbolsValvesButton = new Button(parent, SWT.CHECK);
399 dynamicSymbolsValvesButton.setText("Valves");
400 addSelectionListener(dynamicSymbolsValvesButton);
402 dynamicSymbolsPumpingStationsButton = new Button(parent, SWT.CHECK);
403 dynamicSymbolsPumpingStationsButton.setText("Pumping Stations");
404 addSelectionListener(dynamicSymbolsPumpingStationsButton);
407 private void initializeEdgeArrows(Composite parent) {
408 Group group = new Group(parent, SWT.NONE);
409 group.setText("Edge Arrows");
410 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
411 GridLayoutFactory.fillDefaults().numColumns(6).margins(5, 5).applyTo(group);
413 createEdgeArrowsHeaderRow(group);
415 edgeArrowSuppliers = new ArrayList<>();
418 Collection<DynamicArrowObject> result = Simantics.getSession().syncRequest(new UniqueRead<Collection<DynamicArrowObject>>() {
421 public Collection<DynamicArrowObject> perform(ReadGraph graph) throws DatabaseException {
422 return DynamicVisualisationsContributions.dynamicEdgeArrowObjects(graph);
426 for (DynamicArrowObject object : result) {
427 edgeArrowSuppliers.add(createEdgeArrowRow(group, object));
429 } catch (DatabaseException e) {
430 LOGGER.error("Could not create coloring objecst", e);
436 private void createEdgeArrowsHeaderRow(Composite parent) {
438 Label label = new Label(parent, SWT.NONE);
439 label.setText("Label");
440 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
442 label = new Label(parent, SWT.NONE);
443 label.setText("Used");
444 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
446 label = new Label(parent, SWT.NONE);
447 label.setText("Variable");
448 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
450 label = new Label(parent, SWT.NONE);
451 label.setText("Gain");
452 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
454 label = new Label(parent, SWT.NONE);
455 label.setText("Bias");
456 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
458 label = new Label(parent, SWT.NONE);
459 label.setText("Default");
460 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
463 private Supplier<Pair<String, DynamicArrowContribution>> createEdgeArrowRow(Composite parent, DynamicArrowObject object) {
465 Map<String, DynamicArrowContribution> arrowContributions = object.getArrowContributions();
466 if (arrowContributions.isEmpty()) {
467 // ok, no point in showing empty combo boxes
471 Label label = new Label(parent, SWT.NONE);
472 label.setText(object.getArrowObject().getName());
473 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
475 Button usedButton = new Button(parent, SWT.CHECK);
476 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
477 addSelectionListener(usedButton);
479 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
480 variableCombo.setItems(arrowContributions.keySet().toArray(new String[arrowContributions.size()]));
481 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
483 Text gainText = new Text(parent, SWT.BORDER);
484 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(gainText);
485 addSelectionListener(gainText);
487 Text biasText = new Text(parent, SWT.BORDER);
488 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(biasText);
489 addSelectionListener(biasText);
491 Button defaultButton = new Button(parent, SWT.CHECK);
492 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
493 defaultButton.addSelectionListener(new SelectionAdapter() {
496 public void widgetSelected(SelectionEvent e) {
497 int index = variableCombo.getSelectionIndex();
499 String key = variableCombo.getItem(index);
500 DynamicArrowContribution cont = arrowContributions.get(key);
502 gainText.setText(Double.toString(cont.getDefaultGain()));
503 gainText.setEnabled(!defaultButton.getSelection());
504 biasText.setText(Double.toString(cont.getDefaultBias()));
505 biasText.setEnabled(!defaultButton.getSelection());
510 addSelectionListener(defaultButton);
512 variableCombo.addSelectionListener(new SelectionAdapter() {
515 public void widgetSelected(SelectionEvent e) {
516 // handle update for others
517 String key = variableCombo.getItem(variableCombo.getSelectionIndex());
518 DynamicArrowContribution cont = arrowContributions.get(key);
520 if (gainText.getText().isEmpty()) {
521 gainText.setText(Double.toString(cont.getDefaultGain()));
523 if (biasText.getText().isEmpty()) {
524 biasText.setText(Double.toString(cont.getDefaultBias()));
527 defaultButton.setSelection(true);
530 addSelectionListener(variableCombo);
532 arrowRows.put(object.getArrowObject().getName(), new ArrowObjectRow(label, usedButton, variableCombo, gainText, biasText, defaultButton));
534 return new Supplier<Pair<String, DynamicArrowContribution>>() {
537 public Pair<String, DynamicArrowContribution> get() {
538 int selectionIndex = variableCombo.getSelectionIndex();
539 if (selectionIndex >= 0) {
540 String key = variableCombo.getItem(selectionIndex);
541 DynamicArrowContribution cont = arrowContributions.get(key);
543 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
545 double gain = cont.getDefaultGain();
546 String gainS = gainText.getText();
547 if (gainS != null && !gainS.isEmpty()) {
548 gain = Double.parseDouble(gainS);
550 double bias = cont.getDefaultBias();
551 String biasS = biasText.getText();
552 if (biasS != null && !biasS.isEmpty()) {
553 bias = Double.parseDouble(biasText.getText());
556 DynamicArrowContribution dsc = new DynamicArrowContribution(label, cont.getModuleName(), cont.getAttributeName(), gain, bias);
557 dsc.setUsed(usedButton.getSelection());
558 dsc.setUseDefault(defaultButton.getSelection());
560 return Pair.make(object.getArrowObject().getName(), dsc);
568 protected void removeVisualisationTemplate(String name, Optional<Resource> of) {
569 if (of.isPresent()) {
570 Resource visualisation = of.get();
571 Simantics.getSession().asyncRequest(new WriteRequest() {
574 public void perform(WriteGraph graph) throws DatabaseException {
575 RemoverUtil.remove(graph, visualisation);
581 private void showSaveVisualisationTemplateDialog(Shell shell) {
583 InputDialog dialog = new InputDialog(shell, "Save visualisation template", "Give template a name", "", new IInputValidator() {
586 public String isValid(String newText) {
587 if (newText == null || newText.isEmpty())
588 return "Name cannot be empty";
593 if (dialog.open() == Dialog.OK) {
594 String name = dialog.getValue();
596 persistVisualisationTemplate(name, Optional.empty());
597 } catch (Exception e) {
598 LOGGER.error("Could not persist visualisation template", e);
599 ShowError.showError("Could not persist visualisation template", e.getMessage(), e);
604 private void persistCurrentVisualisationTemplateIfAvailable() {
605 if (visualisation != null) {
607 persistVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
608 } catch (Exception e1) {
609 LOGGER.error("Could not persist visualisation template", e1);
610 ShowError.showError("Could not persist visualisation template", e1.getMessage(), e1);
613 LOGGER.info("No current visualisation template selected for saving");
617 private void persistVisualisationTemplate(String templateName, Optional<Resource> existing) throws Exception {
619 List<Pair<String, DynamicColorContribution>> colorCollect = colorSuppliers.stream().filter(Objects::nonNull).map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
621 String colorLocation = colorLocationCombo.getItem(colorLocationCombo.getSelectionIndex());
622 String colorSize = colorSizeCombo.getItem(colorSizeCombo.getSelectionIndex());
624 ColorBarOptions colorBarOptions = new ColorBarOptions()
625 .showColorBars(showColorButton.getSelection())
626 .showColorBarsTicks(colorTicksButton.getSelection())
627 .useGradients(colorGradientButton.getSelection())
628 .withLocation(ColorBarsLocation.valueOf(colorLocation))
629 .withSize(ColorBarsSize.valueOf(colorSize));
631 List<Pair<String, DynamicSizeContribution>> sizeCollect = sizeSuppliers.stream().filter(Objects::nonNull).map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
633 String sizeLocation = sizeLocationCombo.getItem(sizeLocationCombo.getSelectionIndex());
634 String sizeSize = sizeSizeCombo.getItem(sizeSizeCombo.getSelectionIndex());
636 final SizeBarOptions sizeBarOptions = new SizeBarOptions()
637 .showSizeBars(showSizeButton.getSelection())
638 .showSizeBarsTicks(sizeTicksButton.getSelection())
639 .useGradients(sizeGradientButton.getSelection())
640 .withLocation(SizeBarsLocation.valueOf(sizeLocation))
641 .withSize(SizeBarsSize.valueOf(sizeSize));
643 List<Pair<String, DynamicArrowContribution>> edgeArrowCollect = edgeArrowSuppliers.stream().filter(Objects::nonNull).map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
645 boolean hideEdges = hideEdgesButton.getSelection();
646 boolean hidePoints = hidePointsButton.getSelection();
647 boolean hideConsumers = hideConsumersButton.getSelection();
648 boolean hideProducers = hideProducersButton.getSelection();
649 boolean hideValves = hideValvesButton.getSelection();
650 boolean hidePumpingStations = hidePumpingStationsButton.getSelection();
652 boolean networkBranchesStaticProperties = networkBranchesStaticPropertiesButton.getSelection();
653 boolean pointsStaticProperties = pointsStaticPropertiesButton.getSelection();
654 boolean consumersStaticProperties = consumersStaticPropertiesButton.getSelection();
656 boolean dynamicSymbolsEdges = dynamicSymbolsEdgesButton.getSelection();
657 boolean dynamicSymbolsProducers = dynamicSymbolsProducersButton.getSelection();
658 boolean dynamicSymbolsValves = dynamicSymbolsValvesButton.getSelection();
659 boolean dynamicSymbolsPumpingStations = dynamicSymbolsPumpingStationsButton.getSelection();
661 boolean disabled = disableUpdatesButton.getSelection();
662 boolean resetVisualisation = resetVisualisationButton.getSelection();
665 // inteval is in milliseconds but shown as seconds
667 interval = (long)(Double.parseDouble(intervalText.getText()) * 1000);
668 } catch (NumberFormatException e) {
672 final long finalInterval = interval;
674 boolean hoverVertex = hoveringVertexEnabledButton.getSelection();
675 boolean hoverEdges = hoveringEdgesEnabledButton.getSelection();
677 boolean elevationServerBoundingBox = elevationServerEnabledButton.getSelection();
678 boolean notInSimulation = notInSimulationButton.getSelection();
679 boolean showConnectedComponents = showConnectedComponentsButton.getSelection();
681 Simantics.getSession().asyncRequest(new WriteRequest() {
684 public void perform(WriteGraph graph) throws DatabaseException {
686 if (existing.isPresent()) {
687 exist = existing.get();
689 exist = DynamicVisualisations.createVisualisation(graph, parentResource, templateName);
691 DynamicVisualisations.setIntervalAndDisabled(graph, exist, finalInterval, disabled, resetVisualisation);
692 DynamicVisualisations.setColorContributions(graph, exist, colorCollect);
693 DynamicVisualisations.setColorBarOptions(graph, exist, colorBarOptions);
694 DynamicVisualisations.setSizeContributions(graph, exist, sizeCollect);
695 DynamicVisualisations.setSizeBarOptions(graph, exist, sizeBarOptions);
696 DynamicVisualisations.setEdgeArrowContributions(graph, exist, edgeArrowCollect);
697 DynamicVisualisations.setHideElements(graph, exist,
706 DynamicVisualisations.setStaticProperties(graph, exist,
707 networkBranchesStaticProperties,
708 pointsStaticProperties,
709 consumersStaticProperties
712 DynamicVisualisations.setDynamicSymbols(graph, exist,
714 dynamicSymbolsProducers,
715 dynamicSymbolsValves,
716 dynamicSymbolsPumpingStations
718 DynamicVisualisations.setKeyVariablesHover(graph, exist, hoverVertex, hoverEdges);
720 DynamicVisualisations.setElevationServerBoundingBox(graph, exist, elevationServerBoundingBox);
721 DynamicVisualisations.setNotInSimulation(graph, exist, notInSimulation);
722 DynamicVisualisations.setShowConnectedComponents(graph, exist, showConnectedComponents);
727 private void initializeColoringObjects(Composite parent) {
728 Group group = new Group(parent, SWT.NONE);
729 group.setText("Coloring Objects");
730 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
731 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
734 createColoringObjectHeaderRow(group);
736 colorSuppliers = new ArrayList<>();
739 Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>> result = Simantics.getSession().syncRequest(new UniqueRead<Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>>>() {
742 public Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>> perform(ReadGraph graph) throws DatabaseException {
743 Map<String, DynamicColorMap> dynamicColorMaps = DynamicVisualisationsContributions.dynamicColorMaps(graph);
744 return Pair.make(DynamicVisualisationsContributions.dynamicColoringObjects(graph), dynamicColorMaps);
748 for (DynamicColoringObject object : result.first) {
749 colorSuppliers.add(createColoringObjectRow(group, object, result.second));
752 } catch (DatabaseException e) {
753 LOGGER.error("Could not create coloring objecst", e);
758 private void createColoringObjectHeaderRow(Composite parent) {
760 Label label = new Label(parent, SWT.NONE);
761 label.setText("Label");
762 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
764 label = new Label(parent, SWT.NONE);
765 label.setText("Used");
766 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
768 label = new Label(parent, SWT.NONE);
769 label.setText("Variable");
770 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
772 label = new Label(parent, SWT.NONE);
773 label.setText("Min");
774 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
776 label = new Label(parent, SWT.NONE);
777 label.setText("Max");
778 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
780 label = new Label(parent, SWT.NONE);
781 label.setText("Unit");
782 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
784 label = new Label(parent, SWT.NONE);
785 label.setText("ColorMap");
786 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
788 label = new Label(parent, SWT.NONE);
789 label.setText("Default");
790 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
793 private Map<String, ColoringObjectRow> coloringRows = new HashMap<>();
794 private Map<String, SizingObjectRow> sizingRows = new HashMap<>();
795 private Map<String, ArrowObjectRow> arrowRows = new HashMap<>();
797 private VisualisationsListener visualisationsListener;
799 private Collection<NamedResource> visualisations;
801 private List<Supplier<Pair<String, DynamicSizeContribution>>> sizeSuppliers;
803 private static class ColoringObjectRow {
805 private final Label label;
806 private final Button usedButton;
807 private final Combo variableCombo;
808 private final Text minText;
809 private final Text maxText;
810 private final Text unit;
811 private final Combo colorMapCombo;
812 private final Button defaultButton;
814 public ColoringObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Text unit,
815 Combo colorMapCombo, Button defaultButton) {
818 this.usedButton = usedButton;
819 this.variableCombo = variableCombo;
820 this.minText = minText;
821 this.maxText = maxText;
823 this.colorMapCombo = colorMapCombo;
824 this.defaultButton = defaultButton;
827 public void update(DynamicColorContribution colorContribution) {
828 String[] items = variableCombo.getItems();
829 for (int i = 0; i < items.length; i++) {
830 if (colorContribution.getLabel().equals(items[i])) {
831 variableCombo.select(i);
835 minText.setText(Double.toString(colorContribution.getDefaultMin()));
836 maxText.setText(Double.toString(colorContribution.getDefaultMax()));
837 unit.setText(colorContribution.getUnit());
839 String[] colorItems = colorMapCombo.getItems();
840 for (int i = 0; i < colorItems.length; i++) {
842 if (colorContribution.getDefaultColorMap().getLabel().equals(colorItems[i])) {
843 colorMapCombo.select(i);
847 usedButton.setSelection(colorContribution.isUsed());
848 defaultButton.setSelection(colorContribution.isUseDefault());
850 minText.setEnabled(!colorContribution.isUseDefault());
851 maxText.setEnabled(!colorContribution.isUseDefault());
852 colorMapCombo.setEnabled(!colorContribution.isUseDefault());
856 private static class SizingObjectRow {
858 private final Label label;
859 private final Button usedButton;
860 private final Combo variableCombo;
861 private final Text minText;
862 private final Text maxText;
863 private final Label unit;
864 private final Combo sizeMapCombo;
865 private final Button defaultButton;
867 public SizingObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Label unit,
868 Combo sizeMapCombo, Button defaultButton) {
871 this.usedButton = usedButton;
872 this.variableCombo = variableCombo;
873 this.minText = minText;
874 this.maxText = maxText;
876 this.sizeMapCombo = sizeMapCombo;
877 this.defaultButton = defaultButton;
880 public void update(DynamicSizeContribution sizeContribution) {
881 String[] items = variableCombo.getItems();
882 for (int i = 0; i < items.length; i++) {
883 if (sizeContribution.getLabel().equals(items[i])) {
884 variableCombo.select(i);
888 minText.setText(Double.toString(sizeContribution.getDefaultMin()));
889 maxText.setText(Double.toString(sizeContribution.getDefaultMax()));
890 unit.setText(sizeContribution.getUnit());
892 String[] sizeItems = sizeMapCombo.getItems();
893 for (int i = 0; i < sizeItems.length; i++) {
894 if (sizeContribution.getDefaultSizeMap().getLabel().equals(sizeItems[i])) {
895 sizeMapCombo.select(i);
899 usedButton.setSelection(sizeContribution.isUsed());
900 defaultButton.setSelection(sizeContribution.isUseDefault());
902 minText.setEnabled(!sizeContribution.isUseDefault());
903 maxText.setEnabled(!sizeContribution.isUseDefault());
904 sizeMapCombo.setEnabled(!sizeContribution.isUseDefault());
908 private static class ArrowObjectRow {
910 private final Label label;
911 private final Button usedButton;
912 private final Combo variableCombo;
913 private final Text gainText;
914 private final Text biasText;
915 private final Button defaultButton;
917 public ArrowObjectRow(Label label, Button usedButton, Combo variableCombo, Text gainText, Text biasText, Button defaultButton) {
919 this.usedButton = usedButton;
920 this.variableCombo = variableCombo;
921 this.gainText = gainText;
922 this.biasText = biasText;
923 this.defaultButton = defaultButton;
926 public void update(DynamicColorContribution colorContribution) {
927 String[] items = variableCombo.getItems();
928 for (int i = 0; i < items.length; i++) {
929 if (colorContribution.getLabel().equals(items[i])) {
930 variableCombo.select(i);
934 gainText.setText(Double.toString(colorContribution.getDefaultMin()));
935 biasText.setText(Double.toString(colorContribution.getDefaultMax()));
937 usedButton.setSelection(colorContribution.isUsed());
938 defaultButton.setSelection(colorContribution.isUseDefault());
940 gainText.setEnabled(!colorContribution.isUseDefault());
941 biasText.setEnabled(!colorContribution.isUseDefault());
945 private Supplier<Pair<String, DynamicColorContribution>> createColoringObjectRow(Composite parent, DynamicColoringObject object, Map<String, DynamicColorMap> colorMaps) {
946 Label label = new Label(parent, SWT.NONE);
947 label.setText(object.getColoringObject().getName());
948 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
950 Map<String, DynamicColorContribution> colorContributions = object.getColorContributions();
952 Button usedButton = new Button(parent, SWT.CHECK);
953 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
954 addSelectionListener(usedButton);
956 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
957 variableCombo.setItems(colorContributions.keySet().toArray(new String[colorContributions.size()]));
959 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
961 Text minText = new Text(parent, SWT.BORDER);
962 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(minText);
963 addSelectionListener(minText);
965 Text maxText = new Text(parent, SWT.BORDER);
966 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
967 addSelectionListener(maxText);
969 Text unit = new Text(parent, SWT.READ_ONLY);
970 GridDataFactory.fillDefaults().grab(true, false).hint(30, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(unit);
972 Combo colorMapCombo = new Combo(parent, SWT.READ_ONLY);
973 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(colorMapCombo);
974 colorMapCombo.setItems(colorMaps.keySet().toArray(new String[colorMaps.keySet().size()]));
975 addSelectionListener(colorMapCombo);
977 Button defaultButton = new Button(parent, SWT.CHECK);
978 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
979 defaultButton.addSelectionListener(new SelectionAdapter() {
982 public void widgetSelected(SelectionEvent e) {
983 int index = variableCombo.getSelectionIndex();
985 String key = variableCombo.getItem(index);
986 DynamicColorContribution cont = colorContributions.get(key);
988 minText.setText(Double.toString(cont.getDefaultMin()));
989 minText.setEnabled(!defaultButton.getSelection());
990 maxText.setText(Double.toString(cont.getDefaultMax()));
991 maxText.setEnabled(!defaultButton.getSelection());
992 unit.setText(cont.getUnit());
994 String[] items = colorMapCombo.getItems();
995 for (int i = 0; i < items.length; i++) {
996 String item = items[i];
997 if (item.equals(cont.getDefaultColorMap().getLabel())) {
998 colorMapCombo.select(i);
1002 colorMapCombo.setEnabled(!defaultButton.getSelection());
1006 addSelectionListener(defaultButton);
1008 variableCombo.addSelectionListener(new SelectionAdapter() {
1011 public void widgetSelected(SelectionEvent e) {
1012 // handle update for others
1013 int index = variableCombo.getSelectionIndex();
1015 String key = variableCombo.getItem(index);
1016 DynamicColorContribution cont = colorContributions.get(key);
1018 if (minText.getText().isEmpty()) {
1019 minText.setText(Double.toString(cont.getDefaultMin()));
1021 if (maxText.getText().isEmpty()) {
1022 maxText.setText(Double.toString(cont.getDefaultMax()));
1024 unit.setText(cont.getUnit());
1026 String[] items = colorMapCombo.getItems();
1027 for (int i = 0; i < items.length; i++) {
1028 String item = items[i];
1029 if (item.equals(cont.getDefaultColorMap().getLabel())) {
1030 colorMapCombo.select(i);
1035 defaultButton.setSelection(true);
1039 addSelectionListener(variableCombo);
1041 coloringRows.put(object.getColoringObject().getName(), new ColoringObjectRow(label, usedButton, variableCombo, minText, maxText, unit, colorMapCombo, defaultButton));
1043 return new Supplier<Pair<String, DynamicColorContribution>>() {
1046 public Pair<String, DynamicColorContribution> get() {
1047 int selectionIndex = variableCombo.getSelectionIndex();
1048 if (selectionIndex >= 0) {
1049 String key = variableCombo.getItem(selectionIndex);
1050 DynamicColorContribution cont = colorContributions.get(key);
1053 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
1054 DynamicColorContribution dcc;
1055 if (colorMapCombo.getSelectionIndex() > -1) {
1056 String colorMap = colorMapCombo.getItem(colorMapCombo.getSelectionIndex());
1057 DynamicColorMap dColorMap = colorMaps.get(colorMap);
1058 dcc = new DynamicColorContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
1060 dcc = colorContributions.get(label);
1062 dcc.setUsed(usedButton.getSelection());
1063 dcc.setUseDefault(defaultButton.getSelection());
1065 return Pair.make(object.getColoringObject().getName(), dcc);
1073 private void createSizingObjectHeaderRow(Composite parent) {
1075 Label label = new Label(parent, SWT.NONE);
1076 label.setText("Label");
1077 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1079 label = new Label(parent, SWT.NONE);
1080 label.setText("Used");
1081 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1083 label = new Label(parent, SWT.NONE);
1084 label.setText("Variable");
1085 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1087 label = new Label(parent, SWT.NONE);
1088 label.setText("Min");
1089 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1091 label = new Label(parent, SWT.NONE);
1092 label.setText("Max");
1093 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1095 label = new Label(parent, SWT.NONE);
1096 label.setText("Unit");
1097 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1099 label = new Label(parent, SWT.NONE);
1100 label.setText("SizeMap");
1101 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1103 label = new Label(parent, SWT.NONE);
1104 label.setText("Default");
1105 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1108 private Supplier<Pair<String, DynamicSizeContribution>> createSizingObjectRow(Composite parent, DynamicSizingObject object, Map<String, DynamicSizeMap> sizeMaps) {
1109 Label label = new Label(parent, SWT.NONE);
1110 label.setText(object.getSizingObject().getName());
1111 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
1113 Map<String, DynamicSizeContribution> sizeContributions = object.getSizeContributions();
1115 Button usedButton = new Button(parent, SWT.CHECK);
1116 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
1117 addSelectionListener(usedButton);
1119 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
1120 variableCombo.setItems(sizeContributions.keySet().toArray(new String[sizeContributions.size()]));
1121 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
1123 Text minText = new Text(parent, SWT.BORDER);
1124 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(minText);
1125 addSelectionListener(minText);
1127 Text maxText = new Text(parent, SWT.BORDER);
1128 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
1129 addSelectionListener(maxText);
1131 Label unit = new Label(parent, SWT.NONE);
1132 GridDataFactory.fillDefaults().grab(true, false).hint(30, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(unit);
1134 Combo sizeMapCombo = new Combo(parent, SWT.READ_ONLY);
1135 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(sizeMapCombo);
1136 sizeMapCombo.setItems(sizeMaps.keySet().toArray(new String[sizeMaps.keySet().size()]));
1137 addSelectionListener(sizeMapCombo);
1139 Button defaultButton = new Button(parent, SWT.CHECK);
1140 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
1141 defaultButton.addSelectionListener(new SelectionAdapter() {
1144 public void widgetSelected(SelectionEvent e) {
1145 int index = variableCombo.getSelectionIndex();
1147 String key = variableCombo.getItem(index);
1148 DynamicSizeContribution cont = sizeContributions.get(key);
1150 minText.setText(Double.toString(cont.getDefaultMin()));
1151 minText.setEnabled(!defaultButton.getSelection());
1152 maxText.setText(Double.toString(cont.getDefaultMax()));
1153 maxText.setEnabled(!defaultButton.getSelection());
1154 unit.setText(cont.getUnit());
1156 String[] items = sizeMapCombo.getItems();
1157 for (int i = 0; i < items.length; i++) {
1158 String item = items[i];
1159 if (item.equals(cont.getDefaultSizeMap().getLabel())) {
1160 sizeMapCombo.select(i);
1164 sizeMapCombo.setEnabled(!defaultButton.getSelection());
1168 addSelectionListener(defaultButton);
1170 variableCombo.addSelectionListener(new SelectionAdapter() {
1173 public void widgetSelected(SelectionEvent e) {
1174 // handle update for others
1175 String key = variableCombo.getItem(variableCombo.getSelectionIndex());
1176 DynamicSizeContribution cont = sizeContributions.get(key);
1178 if (minText.getText().isEmpty()) {
1179 minText.setText(Double.toString(cont.getDefaultMin()));
1181 if (maxText.getText().isEmpty()) {
1182 maxText.setText(Double.toString(cont.getDefaultMax()));
1184 unit.setText(cont.getUnit());
1186 String[] items = sizeMapCombo.getItems();
1187 for (int i = 0; i < items.length; i++) {
1188 String item = items[i];
1189 if (item.equals(cont.getDefaultSizeMap().getLabel())) {
1190 sizeMapCombo.select(i);
1195 defaultButton.setSelection(true);
1198 addSelectionListener(variableCombo);
1200 sizingRows.put(object.getSizingObject().getName(), new SizingObjectRow(label, usedButton, variableCombo, minText, maxText, unit, sizeMapCombo, defaultButton));
1202 return new Supplier<Pair<String, DynamicSizeContribution>>() {
1205 public Pair<String, DynamicSizeContribution> get() {
1206 int selectionIndex = variableCombo.getSelectionIndex();
1207 if (selectionIndex >= 0) {
1208 String key = variableCombo.getItem(selectionIndex);
1209 DynamicSizeContribution cont = sizeContributions.get(key);
1212 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
1213 DynamicSizeContribution dsc;
1214 if (sizeMapCombo.getSelectionIndex() > -1) {
1215 String sizeMap = sizeMapCombo.getItem(sizeMapCombo.getSelectionIndex());
1216 DynamicSizeMap dSizeMap = sizeMaps.get(sizeMap);
1217 dsc = new DynamicSizeContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dSizeMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
1219 dsc = sizeContributions.get(label);
1221 dsc.setUsed(usedButton.getSelection());
1222 dsc.setUseDefault(defaultButton.getSelection());
1224 return Pair.make(object.getSizingObject().getName(), dsc);
1232 private void initializeColorBars(Composite parent) {
1233 Group group = new Group(parent, SWT.NONE);
1234 group.setText("Color Bars");
1235 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
1236 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
1238 createColorBars(group);
1241 private void createColorBars(Composite parent) {
1243 showColorButton = new Button(parent, SWT.CHECK);
1244 showColorButton.setText("Show");
1245 addSelectionListener(showColorButton);
1247 colorTicksButton = new Button(parent, SWT.CHECK);
1248 colorTicksButton.setText("Ticks");
1249 addSelectionListener(colorTicksButton);
1251 colorGradientButton = new Button(parent, SWT.CHECK);
1252 colorGradientButton.setText("Gradients");
1253 addSelectionListener(colorGradientButton);
1255 Label label = new Label(parent, SWT.NONE);
1256 label.setText("Location");
1257 colorLocationCombo = new Combo(parent, SWT.READ_ONLY);
1258 String[] colorLocationItems = Stream.of(ColorBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new);
1259 colorLocationCombo.setItems(colorLocationItems);
1260 if (colorLocationItems.length > 0) {
1261 colorLocationCombo.select(0);
1263 addSelectionListener(colorLocationCombo);
1265 label = new Label(parent, SWT.NONE);
1266 label.setText("Size");
1267 colorSizeCombo = new Combo(parent, SWT.READ_ONLY);
1268 String[] colorSizeItems = Stream.of(ColorBarsSize.values()).map(size -> size.toString()).toArray(String[]::new);
1269 colorSizeCombo.setItems(colorSizeItems);
1270 if (colorSizeItems.length > 0) {
1271 colorSizeCombo.select(0);
1273 addSelectionListener(colorSizeCombo);
1276 private void initializeObjectSizes(Composite parent) {
1277 Group group = new Group(parent, SWT.NONE);
1278 group.setText("Object Sizes");
1279 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
1280 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
1283 createSizingObjectHeaderRow(group);
1284 createObjectSizes(group);
1288 private void createObjectSizes(Composite parent) {
1290 sizeSuppliers = new ArrayList<>();
1292 Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>> resultSizing = Simantics.getSession().syncRequest(new UniqueRead<Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>>>() {
1295 public Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>> perform(ReadGraph graph) throws DatabaseException {
1296 Map<String, DynamicSizeMap> dynamicSizeMaps = DynamicVisualisationsContributions.dynamicSizeMaps(graph);
1297 return Pair.make(DynamicVisualisationsContributions.dynamicSizingObjects(graph), dynamicSizeMaps);
1301 for (DynamicSizingObject object : resultSizing.first) {
1302 sizeSuppliers.add(createSizingObjectRow(parent, object, resultSizing.second));
1304 } catch (DatabaseException e) {
1305 LOGGER.error("Could not create object sizes", e);
1309 private void initializeSizeBars(Composite parent) {
1310 Group group = new Group(parent, SWT.NONE);
1311 group.setText("Size Bars");
1312 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
1313 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
1315 createSizeBars(group);
1318 private void createSizeBars(Composite parent) {
1319 showSizeButton = new Button(parent, SWT.CHECK);
1320 showSizeButton.setText("Show");
1321 addSelectionListener(showSizeButton);
1323 sizeTicksButton = new Button(parent, SWT.CHECK);
1324 sizeTicksButton.setText("Ticks");
1325 addSelectionListener(sizeTicksButton);
1327 sizeGradientButton = new Button(parent, SWT.CHECK);
1328 sizeGradientButton.setText("Gradient");
1329 addSelectionListener(sizeGradientButton);
1331 Label label = new Label(parent, SWT.NONE);
1332 label.setText("Location");
1333 sizeLocationCombo = new Combo(parent, SWT.READ_ONLY);
1334 String[] sizeLocationItems = Stream.of(SizeBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new);
1335 sizeLocationCombo.setItems(sizeLocationItems);
1336 if (sizeLocationItems.length > 0) {
1337 sizeLocationCombo.select(0);
1339 addSelectionListener(sizeLocationCombo);
1341 label = new Label(parent, SWT.NONE);
1342 label.setText("Size");
1343 sizeSizeCombo = new Combo(parent, SWT.READ_ONLY);
1344 String[] sizeSizeItems = Stream.of(SizeBarsSize.values()).map(size -> size.toString()).toArray(String[]::new);
1345 sizeSizeCombo.setItems(sizeSizeItems);
1346 if (sizeSizeItems.length > 0) {
1347 sizeSizeCombo.select(0);
1349 addSelectionListener(sizeSizeCombo);
1352 private void addSelectionListener(Widget widget) {
1353 if (widget instanceof Button) {
1354 ((Button) widget).addSelectionListener(new SelectionAdapter() {
1357 public void widgetSelected(SelectionEvent e) {
1358 persistCurrentVisualisationTemplateIfAvailable();
1361 } else if (widget instanceof Combo) {
1362 ((Combo) widget).addSelectionListener(new SelectionAdapter() {
1365 public void widgetSelected(SelectionEvent e) {
1366 persistCurrentVisualisationTemplateIfAvailable();
1369 } else if (widget instanceof Text) {
1370 ((Text) widget).addFocusListener(new FocusAdapter() {
1373 public void focusLost(FocusEvent e) {
1374 persistCurrentVisualisationTemplateIfAvailable();
1377 ((Text) widget).addKeyListener(new KeyAdapter() {
1380 public void keyReleased(KeyEvent e) {
1381 if(e.keyCode == SWT.CR || e.keyCode == SWT.LF) {
1382 persistCurrentVisualisationTemplateIfAvailable();
1389 public void setParentResource(Resource parentResource) {
1390 if (this.parentResource != parentResource) {
1391 this.parentResource = parentResource;
1394 saveVisualisationTemplateAsButton.setEnabled(parentResource != null);
1397 private void updateListening() {
1398 if (visualisationsListener != null)
1399 visualisationsListener.dispose();
1400 if (parentResource != null) {
1401 visualisationsListener = new VisualisationsListener(this);
1402 Simantics.getSession().asyncRequest(new DynamicVisualisationsRequest(parentResource), visualisationsListener);
1405 if (listener != null)
1407 if (parentResource != null) {
1408 listener = new VisualisationListener(this);
1409 Simantics.getSession().asyncRequest(new ActiveDynamicVisualisationsRequest(parentResource), listener);
1413 private static class VisualisationsListener implements Listener<Collection<NamedResource>> {
1415 private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationsListener.class);
1417 private boolean disposed;
1418 private DynamicVisualisationsUI ui;
1420 public VisualisationsListener(DynamicVisualisationsUI ui) {
1425 public void execute(Collection<NamedResource> result) {
1426 ui.updateVisualisations(result);
1430 public void exception(Throwable t) {
1431 LOGGER.error("Could not listen visualisation", t);
1435 public boolean isDisposed() {
1436 return disposed || ui.getParent().isDisposed();
1439 public void dispose() {
1440 this.disposed = true;
1444 private static class VisualisationListener implements Listener<DynamicVisualisation> {
1446 private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationListener.class);
1448 private boolean disposed;
1449 private DynamicVisualisationsUI ui;
1451 public VisualisationListener(DynamicVisualisationsUI ui) {
1456 public void execute(DynamicVisualisation result) {
1457 ui.updateVisualisation(result);
1461 public void exception(Throwable t) {
1462 LOGGER.error("Could not listen visualisation", t);
1466 public boolean isDisposed() {
1467 return disposed ||ui.getParent().isDisposed();
1470 public void dispose() {
1471 this.disposed = true;
1475 public void updateVisualisation(DynamicVisualisation result) {
1476 this.visualisation = result;
1477 Display.getDefault().asyncExec(() -> {
1478 if (getParent().isDisposed())
1481 removeVisualisationTemplateButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null);
1483 if (visualisation != null) {
1484 String[] items = templateSelectionCombo.getItems();
1485 for (int i = 0; i < items.length; i++) {
1486 if (visualisation.getName().equals(items[i])) {
1487 templateSelectionCombo.select(i);
1492 intervalText.setText(Double.toString(((double)visualisation.getInterval()) / 1000.0));
1493 disableUpdatesButton.setSelection(visualisation.disabledUpdates());
1495 hoveringVertexEnabledButton.setSelection(visualisation.isKeyVariablesVertexHover());
1496 hoveringEdgesEnabledButton.setSelection(visualisation.isKeyVariablesEdgesHover());
1498 showConnectedComponentsButton.setSelection(visualisation.showConnectedComponents());
1499 notInSimulationButton.setSelection(visualisation.isInSimulation());
1500 elevationServerEnabledButton.setSelection(visualisation.isShowElevationServerBoundingBox());
1502 hideConsumersButton.setSelection(visualisation.isHideConsumers());
1503 hideEdgesButton.setSelection(visualisation.isHideEdges());
1504 hideProducersButton.setSelection(visualisation.isHideProducers());
1505 hideValvesButton.setSelection(visualisation.isHideValves());
1506 hidePumpingStationsButton.setSelection(visualisation.isHidePumpingStations());
1507 hidePointsButton.setSelection(visualisation.isHidePoints());
1509 Map<String, DynamicColorContribution> colorContributions = visualisation.getColorContributions();
1510 for (Entry<String, DynamicColorContribution> entry : colorContributions.entrySet()) {
1512 ColoringObjectRow coloringObjectRow = coloringRows.get(entry.getKey());
1513 if (coloringObjectRow != null) {
1515 coloringObjectRow.update(entry.getValue());
1518 LOGGER.info("No coloring object visualisation row for key {}", entry.getKey());
1521 ColorBarOptions colorOptions = visualisation.getColorBarOptions();
1522 showColorButton.setSelection(colorOptions.isShowColorBars());
1523 colorTicksButton.setSelection(colorOptions.isShowColorBarsTicks());
1524 colorGradientButton.setSelection(colorOptions.isUseGradients());
1525 for (int i = 0; i < colorLocationCombo.getItems().length; i++) {
1526 String item = colorLocationCombo.getItem(i);
1527 if (item.equals(colorOptions.getLocation().toString())) {
1528 colorLocationCombo.select(i);
1532 for (int i = 0; i < colorSizeCombo.getItems().length; i++) {
1533 String item = colorSizeCombo.getItem(i);
1534 if (item.equals(colorOptions.getSize().toString())) {
1535 colorSizeCombo.select(i);
1540 Map<String, DynamicSizeContribution> sizeContributions = visualisation.getSizeContributions();
1541 for (Entry<String, DynamicSizeContribution> entry : sizeContributions.entrySet()) {
1543 SizingObjectRow sizingObjectRow = sizingRows.get(entry.getKey());
1544 if (sizingObjectRow != null) {
1546 sizingObjectRow.update(entry.getValue());
1549 LOGGER.info("No sizing object visualisation row for key {}", entry.getKey());
1552 SizeBarOptions sizeOptions = visualisation.getSizeBarOptions();
1553 showSizeButton.setSelection(sizeOptions.isShowSizeBars());
1554 sizeTicksButton.setSelection(sizeOptions.isShowSizeBarsTicks());
1555 sizeGradientButton.setSelection(sizeOptions.isUseGradients());
1556 for (int i = 0; i < sizeLocationCombo.getItems().length; i++) {
1557 String item = sizeLocationCombo.getItem(i);
1558 if (item.equals(sizeOptions.getLocation().toString())) {
1559 sizeLocationCombo.select(i);
1563 for (int i = 0; i < sizeSizeCombo.getItems().length; i++) {
1564 String item = sizeSizeCombo.getItem(i);
1565 if (item.equals(sizeOptions.getSize().toString())) {
1566 sizeSizeCombo.select(i);
1571 pointsStaticPropertiesButton.setSelection(visualisation.isStaticPropertiesPoints());
1572 networkBranchesStaticPropertiesButton.setSelection(visualisation.isStaticPropertiesNetworkBranches());
1573 consumersStaticPropertiesButton.setSelection(visualisation.isStaticPropertiesConsumers());
1578 public void updateVisualisations(Collection<NamedResource> result) {
1579 this.visualisations = result;
1581 Display.getDefault().asyncExec(() -> {
1582 if (getParent().isDisposed())
1584 templateSelectionCombo.setItems(visualisations.stream().map(NamedResource::getName).collect(Collectors.toList()).toArray(new String[visualisations.size()]));
1586 if (visualisation != null) {
1587 String[] items = templateSelectionCombo.getItems();
1588 for (int i = 0; i < items.length; i++) {
1589 if (visualisation.getName().equals(items[i])) {
1590 templateSelectionCombo.select(i);
1599 public Composite getParent() {