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.events.FocusAdapter;
22 import org.eclipse.swt.events.FocusEvent;
23 import org.eclipse.swt.events.KeyAdapter;
24 import org.eclipse.swt.events.KeyEvent;
25 import org.eclipse.swt.events.ModifyEvent;
26 import org.eclipse.swt.events.ModifyListener;
27 import org.eclipse.swt.events.SelectionAdapter;
28 import org.eclipse.swt.events.SelectionEvent;
29 import org.eclipse.swt.widgets.Button;
30 import org.eclipse.swt.widgets.Combo;
31 import org.eclipse.swt.widgets.Composite;
32 import org.eclipse.swt.widgets.Display;
33 import org.eclipse.swt.widgets.Group;
34 import org.eclipse.swt.widgets.Label;
35 import org.eclipse.swt.widgets.Shell;
36 import org.eclipse.swt.widgets.Text;
37 import org.eclipse.swt.widgets.Widget;
38 import org.simantics.Simantics;
39 import org.simantics.db.ReadGraph;
40 import org.simantics.db.Resource;
41 import org.simantics.db.WriteGraph;
42 import org.simantics.db.common.NamedResource;
43 import org.simantics.db.common.request.UniqueRead;
44 import org.simantics.db.common.request.WriteRequest;
45 import org.simantics.db.exception.DatabaseException;
46 import org.simantics.db.layer0.util.RemoverUtil;
47 import org.simantics.db.procedure.Listener;
48 import org.simantics.district.network.DistrictNetworkUtil;
49 import org.simantics.district.network.profile.ActiveDynamicVisualisationsRequest;
50 import org.simantics.district.network.profile.DynamicVisualisationsRequest;
51 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions;
52 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicColoringObject;
53 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicSizingObject;
54 import org.simantics.district.network.visualisations.model.ColorBarOptions;
55 import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsLocation;
56 import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsSize;
57 import org.simantics.district.network.visualisations.model.DynamicColorContribution;
58 import org.simantics.district.network.visualisations.model.DynamicColorMap;
59 import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
60 import org.simantics.district.network.visualisations.model.DynamicSizeMap;
61 import org.simantics.district.network.visualisations.model.DynamicVisualisation;
62 import org.simantics.district.network.visualisations.model.SizeBarOptions;
63 import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsLocation;
64 import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsSize;
65 import org.simantics.utils.datastructures.Pair;
66 import org.simantics.utils.ui.dialogs.ShowError;
67 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory;
70 public class DynamicVisualisationsUI extends Composite {
72 private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationsUI.class);
74 private Resource parentResource;
75 private VisualisationListener listener;
76 private DynamicVisualisation visualisation;
78 private Button showSizeButton;
79 private Button sizeTicksButton;
80 private Button sizeGradientButton;
81 private Combo sizeLocationCombo;
82 private Combo sizeSizeCombo;
83 private Button showColorButton;
84 private Button colorTicksButton;
85 private Button colorGradientButton;
86 private Combo colorLocationCombo;
87 private Combo colorSizeCombo;
89 private Combo templateSelectionCombo;
91 private List<Supplier<Pair<String, DynamicColorContribution>>> colorSuppliers;
93 private Button removeVisualisationTemplateButton;
95 public DynamicVisualisationsUI(Composite parent, int style) {
97 // ScrolledComposite scrolledComposite = new ScrolledComposite(this, SWT.V_SCROLL);
98 // scrolledComposite.setLayout(new GridLayout(1, false));
99 // scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
101 // Composite firstContent = new Composite(scrolledComposite, SWT.NONE);
102 // firstContent.setLayout(new GridLayout(1, false));
103 // firstContent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
105 defaultInitializeUI(this);
107 // scrolledComposite.setContent(firstContent);
108 // scrolledComposite.setExpandHorizontal(true);
109 // scrolledComposite.setExpandVertical(true);
110 // scrolledComposite.setMinSize(firstContent.computeSize(SWT.DEFAULT, SWT.DEFAULT));
114 private void defaultInitializeUI(Composite parent) {
116 GridDataFactory.fillDefaults().grab(true, true).applyTo(parent);
117 GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5).applyTo(parent);
119 Composite selectionComposite = new Composite(parent, SWT.NONE);
120 GridDataFactory.fillDefaults().grab(true, false).applyTo(selectionComposite);
121 GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(selectionComposite);
123 Label templateNameLabel = new Label(selectionComposite, SWT.NONE);
124 templateNameLabel.setText("Visualisation template");
125 templateSelectionCombo = new Combo(selectionComposite, SWT.READ_ONLY);
126 GridDataFactory.fillDefaults().grab(true, false).applyTo(templateSelectionCombo);
127 templateSelectionCombo.addSelectionListener(new SelectionAdapter() {
130 public void widgetSelected(SelectionEvent e) {
131 String item = templateSelectionCombo.getItem(templateSelectionCombo.getSelectionIndex());
132 for (NamedResource template : visualisations) {
133 if (item.equals(template.getName())) {
134 Simantics.getSession().asyncRequest(new WriteRequest() {
137 public void perform(WriteGraph graph) throws DatabaseException {
138 Resource vf = DistrictNetworkUtil.getVisualisationFolder(graph, parentResource);
139 DistrictNetworkUtil.setActiveVisualisation(graph, vf, template.getResource());
148 Composite coloringObjectsComposite = new Composite(parent, SWT.NONE);
149 GridDataFactory.fillDefaults().grab(true, false).applyTo(coloringObjectsComposite);
150 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(coloringObjectsComposite);
151 initializeColoringObjects(coloringObjectsComposite);
153 Composite colorBarsComposite = new Composite(parent, SWT.NONE);
154 GridDataFactory.fillDefaults().grab(true, false).applyTo(colorBarsComposite);
155 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(colorBarsComposite);
156 initializeColorBars(colorBarsComposite);
158 Composite objectSizesComposite = new Composite(parent, SWT.NONE);
159 GridDataFactory.fillDefaults().grab(true, false).applyTo(objectSizesComposite);
160 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(objectSizesComposite);
161 initializeObjectSizes(objectSizesComposite);
163 Composite sizeBarsComposite = new Composite(parent, SWT.NONE);
164 GridDataFactory.fillDefaults().grab(true, false).applyTo(sizeBarsComposite);
165 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(sizeBarsComposite);
166 initializeSizeBars(sizeBarsComposite);
168 Composite buttonBarsComposite = new Composite(parent, SWT.NONE);
169 GridDataFactory.fillDefaults().grab(true, false).applyTo(buttonBarsComposite);
170 GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonBarsComposite);
172 Button saveVisualisationTemplateAsButton = new Button(buttonBarsComposite, SWT.NONE);
173 saveVisualisationTemplateAsButton.setText("Save as visualisation template");
174 saveVisualisationTemplateAsButton.addSelectionListener(new SelectionAdapter() {
177 public void widgetSelected(SelectionEvent e) {
178 showSaveVisualisationTemplateDialog(e.widget.getDisplay().getActiveShell());
182 removeVisualisationTemplateButton = new Button(buttonBarsComposite, SWT.NONE);
183 removeVisualisationTemplateButton.setText("Remove");
184 removeVisualisationTemplateButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null);
185 removeVisualisationTemplateButton.addSelectionListener(new SelectionAdapter() {
188 public void widgetSelected(SelectionEvent e) {
189 removeVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
195 protected void removeVisualisationTemplate(String name, Optional<Resource> of) {
196 if (of.isPresent()) {
197 Resource visualisation = of.get();
198 Simantics.getSession().asyncRequest(new WriteRequest() {
201 public void perform(WriteGraph graph) throws DatabaseException {
202 RemoverUtil.remove(graph, visualisation);
208 private void showSaveVisualisationTemplateDialog(Shell shell) {
210 InputDialog dialog = new InputDialog(shell, "Save visualisation template", "Give template a name", "", new IInputValidator() {
213 public String isValid(String newText) {
214 if (newText == null || newText.isEmpty())
215 return "Name cannot be empty";
220 if (dialog.open() == Dialog.OK) {
221 String name = dialog.getValue();
223 persistVisualisationTemplate(name, Optional.empty());
224 } catch (Exception e) {
225 LOGGER.error("Could not persist visualisation template", e);
226 ShowError.showError("Could not persist visualisation template", e.getMessage(), e);
231 private void persistVisualisationTemplate(String templateName, Optional<Resource> existing) throws Exception {
233 List<Pair<String, DynamicColorContribution>> colorCollect = colorSuppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
235 String colorLocation = colorLocationCombo.getItem(colorLocationCombo.getSelectionIndex());
236 String colorSize = colorSizeCombo.getItem(colorSizeCombo.getSelectionIndex());
238 ColorBarOptions colorBarOptions = new ColorBarOptions()
239 .showColorBars(showColorButton.getSelection())
240 .showColorBarsTicks(colorTicksButton.getSelection())
241 .useGradients(colorGradientButton.getSelection())
242 .withLocation(ColorBarsLocation.valueOf(colorLocation))
243 .withSize(ColorBarsSize.valueOf(colorSize));
245 List<Pair<String, DynamicSizeContribution>> sizeCollect = sizeSuppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
247 String sizeLocation = sizeLocationCombo.getItem(sizeLocationCombo.getSelectionIndex());
248 String sizeSize = sizeSizeCombo.getItem(sizeSizeCombo.getSelectionIndex());
250 SizeBarOptions sizeBarOptions = new SizeBarOptions()
251 .showSizeBars(showSizeButton.getSelection())
252 .showSizeBarsTicks(sizeTicksButton.getSelection())
253 .useGradients(sizeGradientButton.getSelection())
254 .withLocation(SizeBarsLocation.valueOf(sizeLocation))
255 .withSize(SizeBarsSize.valueOf(sizeSize));
257 Simantics.getSession().asyncRequest(new WriteRequest() {
260 public void perform(WriteGraph graph) throws DatabaseException {
262 if (existing.isPresent()) {
263 exist = existing.get();
265 exist = DistrictNetworkUtil.createVisualisation(graph, parentResource, templateName);
268 DistrictNetworkUtil.setColorContributions(graph, exist, colorCollect);
270 DistrictNetworkUtil.setColorBarOptions(graph, exist, colorBarOptions);
271 DistrictNetworkUtil.setSizeContributions(graph, exist, sizeCollect);
272 DistrictNetworkUtil.setSizeBarOptions(graph, exist, sizeBarOptions);
277 private void initializeColoringObjects(Composite parent) {
278 Group group = new Group(parent, SWT.NONE);
279 group.setText("Coloring Objects");
280 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
281 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
284 createColoringObjectHeaderRow(group);
286 colorSuppliers = new ArrayList<>();
289 Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>> result = Simantics.getSession().syncRequest(new UniqueRead<Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>>>() {
292 public Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>> perform(ReadGraph graph) throws DatabaseException {
293 Map<String, DynamicColorMap> dynamicColorMaps = DynamicVisualisationsContributions.dynamicColorMaps(graph);
294 return Pair.make(DynamicVisualisationsContributions.dynamicColoringObjects(graph), dynamicColorMaps);
298 for (DynamicColoringObject object : result.first) {
299 colorSuppliers.add(createColoringObjectRow(group, object, result.second));
302 } catch (DatabaseException e) {
303 LOGGER.error("Could not create coloring objecst", e);
308 private void createColoringObjectHeaderRow(Composite parent) {
310 Label label = new Label(parent, SWT.NONE);
311 label.setText("Label");
312 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
314 label = new Label(parent, SWT.NONE);
315 label.setText("Used");
316 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
318 label = new Label(parent, SWT.NONE);
319 label.setText("Variable");
320 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
322 label = new Label(parent, SWT.NONE);
323 label.setText("Min");
324 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
326 label = new Label(parent, SWT.NONE);
327 label.setText("Max");
328 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
330 label = new Label(parent, SWT.NONE);
331 label.setText("Unit");
332 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
334 label = new Label(parent, SWT.NONE);
335 label.setText("ColorMap");
336 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
338 label = new Label(parent, SWT.NONE);
339 label.setText("Default");
340 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
343 private Map<String, ColoringObjectRow> coloringRows = new HashMap<>();
344 private Map<String, SizingObjectRow> sizingRows = new HashMap<>();
346 private VisualisationsListener visualisationsListener;
348 private Collection<NamedResource> visualisations;
350 private List<Supplier<Pair<String, DynamicSizeContribution>>> sizeSuppliers;
352 private static class ColoringObjectRow {
354 private final Label label;
355 private final Button usedButton;
356 private final Combo variableCombo;
357 private final Text minText;
358 private final Text maxText;
359 private final Text unit;
360 private final Combo colorMapCombo;
361 private final Button defaultButton;
363 public ColoringObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Text unit,
364 Combo colorMapCombo, Button defaultButton) {
367 this.usedButton = usedButton;
368 this.variableCombo = variableCombo;
369 this.minText = minText;
370 this.maxText = maxText;
372 this.colorMapCombo = colorMapCombo;
373 this.defaultButton = defaultButton;
376 public void update(DynamicColorContribution colorContribution) {
377 String[] items = variableCombo.getItems();
378 for (int i = 0; i < items.length; i++) {
379 if (colorContribution.getLabel().equals(items[i])) {
380 variableCombo.select(i);
384 minText.setText(Double.toString(colorContribution.getDefaultMin()));
385 maxText.setText(Double.toString(colorContribution.getDefaultMax()));
386 unit.setText(colorContribution.getUnit());
388 String[] colorItems = colorMapCombo.getItems();
389 for (int i = 0; i < colorItems.length; i++) {
391 if (colorContribution.getDefaultColorMap().getLabel().equals(colorItems[i])) {
392 colorMapCombo.select(i);
396 usedButton.setSelection(colorContribution.isUsed());
397 defaultButton.setSelection(colorContribution.isUseDefault());
399 minText.setEnabled(!colorContribution.isUseDefault());
400 maxText.setEnabled(!colorContribution.isUseDefault());
401 colorMapCombo.setEnabled(!colorContribution.isUseDefault());
405 private static class SizingObjectRow {
407 private final Label label;
408 private final Button usedButton;
409 private final Combo variableCombo;
410 private final Text minText;
411 private final Text maxText;
412 private final Label unit;
413 private final Combo sizeMapCombo;
414 private final Button defaultButton;
416 public SizingObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Label unit,
417 Combo sizeMapCombo, Button defaultButton) {
420 this.usedButton = usedButton;
421 this.variableCombo = variableCombo;
422 this.minText = minText;
423 this.maxText = maxText;
425 this.sizeMapCombo = sizeMapCombo;
426 this.defaultButton = defaultButton;
429 public void update(DynamicSizeContribution sizeContribution) {
430 String[] items = variableCombo.getItems();
431 for (int i = 0; i < items.length; i++) {
432 if (sizeContribution.getLabel().equals(items[i])) {
433 variableCombo.select(i);
437 minText.setText(Double.toString(sizeContribution.getDefaultMin()));
438 maxText.setText(Double.toString(sizeContribution.getDefaultMax()));
439 unit.setText(sizeContribution.getUnit());
441 String[] sizeItems = sizeMapCombo.getItems();
442 for (int i = 0; i < sizeItems.length; i++) {
443 if (sizeContribution.getDefaultSizeMap().getLabel().equals(sizeItems[i])) {
444 sizeMapCombo.select(i);
448 usedButton.setSelection(sizeContribution.isUsed());
449 defaultButton.setSelection(sizeContribution.isUseDefault());
451 minText.setEnabled(!sizeContribution.isUseDefault());
452 maxText.setEnabled(!sizeContribution.isUseDefault());
453 sizeMapCombo.setEnabled(!sizeContribution.isUseDefault());
457 private Supplier<Pair<String, DynamicColorContribution>> createColoringObjectRow(Composite parent, DynamicColoringObject object, Map<String, DynamicColorMap> colorMaps) {
458 Label label = new Label(parent, SWT.NONE);
459 label.setText(object.getColoringObject().getName());
460 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
462 Map<String, DynamicColorContribution> colorContributions = object.getColorContributions();
464 Button usedButton = new Button(parent, SWT.CHECK);
465 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
466 addSelectionListener(usedButton);
468 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
469 variableCombo.setItems(colorContributions.keySet().toArray(new String[colorContributions.size()]));
470 addSelectionListener(variableCombo);
472 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
474 Text minText = new Text(parent, SWT.BORDER);
475 GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(minText);
476 addSelectionListener(minText);
478 Text maxText = new Text(parent, SWT.BORDER);
479 GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
480 addSelectionListener(maxText);
482 Text unit = new Text(parent, SWT.READ_ONLY);
483 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(unit);
485 Combo colorMapCombo = new Combo(parent, SWT.READ_ONLY);
486 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(colorMapCombo);
487 colorMapCombo.setItems(colorMaps.keySet().toArray(new String[colorMaps.keySet().size()]));
488 addSelectionListener(colorMapCombo);
490 Button defaultButton = new Button(parent, SWT.CHECK);
491 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
492 addSelectionListener(defaultButton);
493 defaultButton.addSelectionListener(new SelectionAdapter() {
496 public void widgetSelected(SelectionEvent e) {
497 int index = variableCombo.getSelectionIndex();
499 String key = variableCombo.getItem(index);
500 DynamicColorContribution cont = colorContributions.get(key);
502 minText.setText(Double.toString(cont.getDefaultMin()));
503 minText.setEnabled(!defaultButton.getSelection());
504 maxText.setText(Double.toString(cont.getDefaultMax()));
505 maxText.setEnabled(!defaultButton.getSelection());
506 unit.setText(cont.getUnit());
508 String[] items = colorMapCombo.getItems();
509 for (int i = 0; i < items.length; i++) {
510 String item = items[i];
511 if (item.equals(cont.getDefaultColorMap().getLabel())) {
512 colorMapCombo.select(i);
516 colorMapCombo.setEnabled(!defaultButton.getSelection());
521 variableCombo.addSelectionListener(new SelectionAdapter() {
524 public void widgetSelected(SelectionEvent e) {
525 // handle update for others
526 int index = variableCombo.getSelectionIndex();
528 String key = variableCombo.getItem(index);
529 DynamicColorContribution cont = colorContributions.get(key);
531 if (minText.getText().isEmpty()) {
532 minText.setText(Double.toString(cont.getDefaultMin()));
534 if (maxText.getText().isEmpty()) {
535 maxText.setText(Double.toString(cont.getDefaultMax()));
537 unit.setText(cont.getUnit());
539 String[] items = colorMapCombo.getItems();
540 for (int i = 0; i < items.length; i++) {
541 String item = items[i];
542 if (item.equals(cont.getDefaultColorMap().getLabel())) {
543 colorMapCombo.select(i);
548 defaultButton.setSelection(true);
553 coloringRows.put(object.getColoringObject().getName(), new ColoringObjectRow(label, usedButton, variableCombo, minText, maxText, unit, colorMapCombo, defaultButton));
555 return new Supplier<Pair<String, DynamicColorContribution>>() {
558 public Pair<String, DynamicColorContribution> get() {
559 int selectionIndex = variableCombo.getSelectionIndex();
560 if (selectionIndex >= 0) {
561 String key = variableCombo.getItem(selectionIndex);
562 DynamicColorContribution cont = colorContributions.get(key);
564 String colorMap = colorMapCombo.getItem(colorMapCombo.getSelectionIndex());
566 Map<String, DynamicColorMap> colorMaps = Simantics.getSession().syncRequest(new UniqueRead<Map<String, DynamicColorMap>>() {
569 public Map<String, DynamicColorMap> perform(ReadGraph graph) throws DatabaseException {
570 return DynamicVisualisationsContributions.dynamicColorMaps(graph);
573 DynamicColorMap dColorMap = colorMaps.get(colorMap);
574 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
576 DynamicColorContribution dcc = new DynamicColorContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
577 dcc.setUsed(usedButton.getSelection());
578 dcc.setUseDefault(defaultButton.getSelection());
580 return Pair.make(object.getColoringObject().getName(), dcc);
581 } catch (DatabaseException e) {
582 LOGGER.error("Could not get DynamicColorContribution", e);
591 private void createSizingObjectHeaderRow(Composite parent) {
593 Label label = new Label(parent, SWT.NONE);
594 label.setText("Label");
595 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
597 label = new Label(parent, SWT.NONE);
598 label.setText("Used");
599 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
601 label = new Label(parent, SWT.NONE);
602 label.setText("Variable");
603 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
605 label = new Label(parent, SWT.NONE);
606 label.setText("Min");
607 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
609 label = new Label(parent, SWT.NONE);
610 label.setText("Max");
611 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
613 label = new Label(parent, SWT.NONE);
614 label.setText("Unit");
615 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
617 label = new Label(parent, SWT.NONE);
618 label.setText("SizeMap");
619 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
621 label = new Label(parent, SWT.NONE);
622 label.setText("Default");
623 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
626 private Supplier<Pair<String, DynamicSizeContribution>> createSizingObjectRow(Composite parent, DynamicSizingObject object, Map<String, DynamicSizeMap> sizeMaps) {
627 Label label = new Label(parent, SWT.NONE);
628 label.setText(object.getSizingObject().getName());
629 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
631 Map<String, DynamicSizeContribution> sizeContributions = object.getSizeContributions();
633 Button usedButton = new Button(parent, SWT.CHECK);
634 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
635 addSelectionListener(usedButton);
637 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
638 variableCombo.setItems(sizeContributions.keySet().toArray(new String[sizeContributions.size()]));
639 addSelectionListener(variableCombo);
641 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
643 Text minText = new Text(parent, SWT.BORDER);
644 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(minText);
645 addSelectionListener(minText);
647 Text maxText = new Text(parent, SWT.BORDER);
648 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
649 addSelectionListener(maxText);
651 Label unit = new Label(parent, SWT.NONE);
652 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(unit);
654 Combo sizeMapCombo = new Combo(parent, SWT.READ_ONLY);
655 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(sizeMapCombo);
656 sizeMapCombo.setItems(sizeMaps.keySet().toArray(new String[sizeMaps.keySet().size()]));
657 addSelectionListener(sizeMapCombo);
659 Button defaultButton = new Button(parent, SWT.CHECK);
660 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
661 addSelectionListener(defaultButton);
662 defaultButton.addSelectionListener(new SelectionAdapter() {
665 public void widgetSelected(SelectionEvent e) {
666 int index = variableCombo.getSelectionIndex();
668 String key = variableCombo.getItem(index);
669 DynamicSizeContribution cont = sizeContributions.get(key);
671 minText.setText(Double.toString(cont.getDefaultMin()));
672 minText.setEnabled(!defaultButton.getSelection());
673 maxText.setText(Double.toString(cont.getDefaultMax()));
674 maxText.setEnabled(!defaultButton.getSelection());
675 unit.setText(cont.getUnit());
677 String[] items = sizeMapCombo.getItems();
678 for (int i = 0; i < items.length; i++) {
679 String item = items[i];
680 if (item.equals(cont.getDefaultSizeMap().getLabel())) {
681 sizeMapCombo.select(i);
685 sizeMapCombo.setEnabled(!defaultButton.getSelection());
690 variableCombo.addSelectionListener(new SelectionAdapter() {
693 public void widgetSelected(SelectionEvent e) {
694 // handle update for others
695 String key = variableCombo.getItem(variableCombo.getSelectionIndex());
696 DynamicSizeContribution cont = sizeContributions.get(key);
698 if (minText.getText().isEmpty()) {
699 minText.setText(Double.toString(cont.getDefaultMin()));
701 if (maxText.getText().isEmpty()) {
702 maxText.setText(Double.toString(cont.getDefaultMax()));
704 unit.setText(cont.getUnit());
706 String[] items = sizeMapCombo.getItems();
707 for (int i = 0; i < items.length; i++) {
708 String item = items[i];
709 if (item.equals(cont.getDefaultSizeMap().getLabel())) {
710 sizeMapCombo.select(i);
715 defaultButton.setSelection(true);
719 sizingRows.put(object.getSizingObject().getName(), new SizingObjectRow(label, usedButton, variableCombo, minText, maxText, unit, sizeMapCombo, defaultButton));
721 return new Supplier<Pair<String, DynamicSizeContribution>>() {
724 public Pair<String, DynamicSizeContribution> get() {
725 int selectionIndex = variableCombo.getSelectionIndex();
726 if (selectionIndex >= 0) {
727 String key = variableCombo.getItem(selectionIndex);
728 DynamicSizeContribution cont = sizeContributions.get(key);
730 String sizeMap = sizeMapCombo.getItem(sizeMapCombo.getSelectionIndex());
732 Map<String, DynamicSizeMap> sizeMaps = Simantics.getSession().syncRequest(new UniqueRead<Map<String, DynamicSizeMap>>() {
735 public Map<String, DynamicSizeMap> perform(ReadGraph graph) throws DatabaseException {
736 return DynamicVisualisationsContributions.dynamicSizeMaps(graph);
739 DynamicSizeMap dColorMap = sizeMaps.get(sizeMap);
740 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
742 DynamicSizeContribution dsc = new DynamicSizeContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
743 dsc.setUsed(usedButton.getSelection());
744 dsc.setUseDefault(defaultButton.getSelection());
746 return Pair.make(object.getSizingObject().getName(), dsc);
747 } catch (DatabaseException e) {
748 LOGGER.error("Could not get DynamicColorContribution", e);
757 private void initializeColorBars(Composite parent) {
758 Group group = new Group(parent, SWT.NONE);
759 group.setText("Color Bars");
760 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
761 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
763 createColorBars(group);
766 private void createColorBars(Composite parent) {
768 showColorButton = new Button(parent, SWT.CHECK);
769 showColorButton.setText("Show");
770 addSelectionListener(showColorButton);
772 colorTicksButton = new Button(parent, SWT.CHECK);
773 colorTicksButton.setText("Ticks");
774 addSelectionListener(colorTicksButton);
776 colorGradientButton = new Button(parent, SWT.CHECK);
777 colorGradientButton.setText("Gradients");
778 addSelectionListener(colorGradientButton);
780 Label label = new Label(parent, SWT.NONE);
781 label.setText("Location");
782 colorLocationCombo = new Combo(parent, SWT.READ_ONLY);
783 String[] colorLocationItems = Stream.of(ColorBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new);
784 colorLocationCombo.setItems(colorLocationItems);
785 if (colorLocationItems.length > 0) {
786 colorLocationCombo.select(0);
788 addSelectionListener(colorLocationCombo);
790 label = new Label(parent, SWT.NONE);
791 label.setText("Size");
792 colorSizeCombo = new Combo(parent, SWT.READ_ONLY);
793 String[] colorSizeItems = Stream.of(ColorBarsSize.values()).map(size -> size.toString()).toArray(String[]::new);
794 colorSizeCombo.setItems(colorSizeItems);
795 if (colorSizeItems.length > 0) {
796 colorSizeCombo.select(0);
798 addSelectionListener(colorSizeCombo);
801 private void initializeObjectSizes(Composite parent) {
802 Group group = new Group(parent, SWT.NONE);
803 group.setText("Object Sizes");
804 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
805 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
808 createSizingObjectHeaderRow(group);
809 createObjectSizes(group);
813 private void createObjectSizes(Composite parent) {
815 sizeSuppliers = new ArrayList<>();
817 Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>> resultSizing = Simantics.getSession().syncRequest(new UniqueRead<Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>>>() {
820 public Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>> perform(ReadGraph graph) throws DatabaseException {
821 Map<String, DynamicSizeMap> dynamicSizeMaps = DynamicVisualisationsContributions.dynamicSizeMaps(graph);
822 return Pair.make(DynamicVisualisationsContributions.dynamicSizingObjects(graph), dynamicSizeMaps);
826 for (DynamicSizingObject object : resultSizing.first) {
827 sizeSuppliers.add(createSizingObjectRow(parent, object, resultSizing.second));
829 } catch (DatabaseException e) {
830 LOGGER.error("Could not create object sizes", e);
834 private void initializeSizeBars(Composite parent) {
835 Group group = new Group(parent, SWT.NONE);
836 group.setText("Size Bars");
837 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
838 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
840 createSizeBars(group);
843 private void createSizeBars(Composite parent) {
844 showSizeButton = new Button(parent, SWT.CHECK);
845 showSizeButton.setText("Show");
846 addSelectionListener(showSizeButton);
848 sizeTicksButton = new Button(parent, SWT.CHECK);
849 sizeTicksButton.setText("Ticks");
850 addSelectionListener(sizeTicksButton);
852 sizeGradientButton = new Button(parent, SWT.CHECK);
853 sizeGradientButton.setText("Gradient");
854 addSelectionListener(sizeGradientButton);
856 Label label = new Label(parent, SWT.NONE);
857 label.setText("Location");
858 sizeLocationCombo = new Combo(parent, SWT.READ_ONLY);
859 String[] sizeLocationItems = Stream.of(SizeBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new);
860 sizeLocationCombo.setItems(sizeLocationItems);
861 if (sizeLocationItems.length > 0) {
862 sizeLocationCombo.select(0);
864 addSelectionListener(sizeLocationCombo);
866 label = new Label(parent, SWT.NONE);
867 label.setText("Size");
868 sizeSizeCombo = new Combo(parent, SWT.READ_ONLY);
869 String[] sizeSizeItems = Stream.of(SizeBarsSize.values()).map(size -> size.toString()).toArray(String[]::new);
870 sizeSizeCombo.setItems(sizeSizeItems);
871 if (sizeSizeItems.length > 0) {
872 sizeSizeCombo.select(0);
874 addSelectionListener(sizeSizeCombo);
877 private void addSelectionListener(Widget widget) {
878 if (widget instanceof Button) {
879 ((Button) widget).addSelectionListener(new SelectionAdapter() {
882 public void widgetSelected(SelectionEvent e) {
884 persistVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
885 } catch (Exception e1) {
886 LOGGER.error("Could not persist visualisation template", e1);
887 ShowError.showError("Could not persist visualisation template", e1.getMessage(), e1);
891 } else if (widget instanceof Combo) {
892 ((Combo) widget).addSelectionListener(new SelectionAdapter() {
895 public void widgetSelected(SelectionEvent e) {
897 persistVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
898 } catch (Exception e1) {
899 LOGGER.error("Could not persist visualisation template", e1);
900 ShowError.showError("Could not persist visualisation template", e1.getMessage(), e1);
904 } else if (widget instanceof Text) {
905 ((Text) widget).addFocusListener(new FocusAdapter() {
908 public void focusLost(FocusEvent e) {
910 persistVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
911 } catch (Exception e1) {
912 LOGGER.error("Could not persist visualisation template", e1);
913 ShowError.showError("Could not persist visualisation template", e1.getMessage(), e1);
917 ((Text) widget).addKeyListener(new KeyAdapter() {
920 public void keyReleased(KeyEvent e) {
921 if(e.keyCode == SWT.CR || e.keyCode == SWT.LF) {
923 persistVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
924 } catch (Exception e1) {
925 LOGGER.error("Could not persist visualisation template", e1);
926 ShowError.showError("Could not persist visualisation template", e1.getMessage(), e1);
934 public void setParentResource(Resource parentResource) {
935 if (this.parentResource != parentResource) {
936 this.parentResource = parentResource;
941 private void updateListening() {
942 if (visualisationsListener != null)
943 visualisationsListener.dispose();
944 visualisationsListener = new VisualisationsListener(this);
945 Simantics.getSession().asyncRequest(new DynamicVisualisationsRequest(parentResource), visualisationsListener);
947 if (listener != null)
949 listener = new VisualisationListener(this);
950 Simantics.getSession().asyncRequest(new ActiveDynamicVisualisationsRequest(parentResource), listener);
953 private static class VisualisationsListener implements Listener<Collection<NamedResource>> {
955 private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationsListener.class);
957 private boolean disposed;
958 private DynamicVisualisationsUI ui;
960 public VisualisationsListener(DynamicVisualisationsUI ui) {
965 public void execute(Collection<NamedResource> result) {
966 ui.updateVisualisations(result);
970 public void exception(Throwable t) {
971 LOGGER.error("Could not listen visualisation", t);
975 public boolean isDisposed() {
976 return disposed || ui.isDisposed();
979 public void dispose() {
980 this.disposed = true;
984 private static class VisualisationListener implements Listener<DynamicVisualisation> {
986 private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationListener.class);
988 private boolean disposed;
989 private DynamicVisualisationsUI ui;
991 public VisualisationListener(DynamicVisualisationsUI ui) {
996 public void execute(DynamicVisualisation result) {
997 ui.updateVisualisation(result);
1001 public void exception(Throwable t) {
1002 LOGGER.error("Could not listen visualisation", t);
1006 public boolean isDisposed() {
1007 return disposed || ui.isDisposed();
1010 public void dispose() {
1011 this.disposed = true;
1015 public void updateVisualisation(DynamicVisualisation result) {
1016 this.visualisation = result;
1017 Display.getDefault().asyncExec(() -> {
1018 if (getParent().isDisposed())
1021 removeVisualisationTemplateButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null);
1023 if (visualisation != null) {
1024 String[] items = templateSelectionCombo.getItems();
1025 for (int i = 0; i < items.length; i++) {
1026 if (visualisation.getName().equals(items[i])) {
1027 templateSelectionCombo.select(i);
1032 Map<String, DynamicColorContribution> colorContributions = visualisation.getColorContributions();
1033 for (Entry<String, DynamicColorContribution> entry : colorContributions.entrySet()) {
1035 ColoringObjectRow coloringObjectRow = coloringRows.get(entry.getKey());
1036 if (coloringObjectRow != null) {
1038 coloringObjectRow.update(entry.getValue());
1041 LOGGER.info("No coloring object visualisation row for key {}", entry.getKey());
1044 ColorBarOptions colorOptions = visualisation.getColorBarOptions();
1045 showColorButton.setSelection(colorOptions.isShowColorBars());
1046 colorTicksButton.setSelection(colorOptions.isShowColorBarsTicks());
1047 colorGradientButton.setSelection(colorOptions.isUseGradients());
1048 for (int i = 0; i < colorLocationCombo.getItems().length; i++) {
1049 String item = colorLocationCombo.getItem(i);
1050 if (item.equals(colorOptions.getLocation().toString())) {
1051 colorLocationCombo.select(i);
1055 for (int i = 0; i < colorSizeCombo.getItems().length; i++) {
1056 String item = colorSizeCombo.getItem(i);
1057 if (item.equals(colorOptions.getSize().toString())) {
1058 colorSizeCombo.select(i);
1063 Map<String, DynamicSizeContribution> sizeContributions = visualisation.getSizeContributions();
1064 for (Entry<String, DynamicSizeContribution> entry : sizeContributions.entrySet()) {
1066 SizingObjectRow sizingObjectRow = sizingRows.get(entry.getKey());
1067 if (sizingObjectRow != null) {
1069 sizingObjectRow.update(entry.getValue());
1072 LOGGER.info("No sizing object visualisation row for key {}", entry.getKey());
1075 SizeBarOptions sizeOptions = visualisation.getSizeBarOptions();
1076 showSizeButton.setSelection(sizeOptions.isShowSizeBars());
1077 sizeTicksButton.setSelection(sizeOptions.isShowSizeBarsTicks());
1078 sizeGradientButton.setSelection(sizeOptions.isUseGradients());
1079 for (int i = 0; i < sizeLocationCombo.getItems().length; i++) {
1080 String item = sizeLocationCombo.getItem(i);
1081 if (item.equals(sizeOptions.getLocation().toString())) {
1082 sizeLocationCombo.select(i);
1086 for (int i = 0; i < sizeSizeCombo.getItems().length; i++) {
1087 String item = sizeSizeCombo.getItem(i);
1088 if (item.equals(sizeOptions.getSize().toString())) {
1089 sizeSizeCombo.select(i);
1097 public void updateVisualisations(Collection<NamedResource> result) {
1098 this.visualisations = result;
1100 Display.getDefault().asyncExec(() -> {
1101 if (getParent().isDisposed())
1103 templateSelectionCombo.setItems(visualisations.stream().map(NamedResource::getName).collect(Collectors.toList()).toArray(new String[visualisations.size()]));
1105 if (visualisation != null) {
1106 String[] items = templateSelectionCombo.getItems();
1107 for (int i = 0; i < items.length; i++) {
1108 if (visualisation.getName().equals(items[i])) {
1109 templateSelectionCombo.select(i);