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.SelectionAdapter;
22 import org.eclipse.swt.events.SelectionEvent;
23 import org.eclipse.swt.widgets.Button;
24 import org.eclipse.swt.widgets.Combo;
25 import org.eclipse.swt.widgets.Composite;
26 import org.eclipse.swt.widgets.Display;
27 import org.eclipse.swt.widgets.Group;
28 import org.eclipse.swt.widgets.Label;
29 import org.eclipse.swt.widgets.Shell;
30 import org.eclipse.swt.widgets.Text;
31 import org.simantics.Simantics;
32 import org.simantics.db.ReadGraph;
33 import org.simantics.db.Resource;
34 import org.simantics.db.WriteGraph;
35 import org.simantics.db.common.NamedResource;
36 import org.simantics.db.common.request.UniqueRead;
37 import org.simantics.db.common.request.WriteRequest;
38 import org.simantics.db.exception.DatabaseException;
39 import org.simantics.db.layer0.util.RemoverUtil;
40 import org.simantics.db.procedure.Listener;
41 import org.simantics.district.network.DistrictNetworkUtil;
42 import org.simantics.district.network.profile.ActiveDynamicVisualisationsRequest;
43 import org.simantics.district.network.profile.DynamicVisualisationsRequest;
44 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions;
45 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicColoringObject;
46 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicSizingObject;
47 import org.simantics.district.network.visualisations.model.ColorBarOptions;
48 import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsLocation;
49 import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsSize;
50 import org.simantics.district.network.visualisations.model.DynamicColorContribution;
51 import org.simantics.district.network.visualisations.model.DynamicColorMap;
52 import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
53 import org.simantics.district.network.visualisations.model.DynamicSizeMap;
54 import org.simantics.district.network.visualisations.model.DynamicVisualisation;
55 import org.simantics.district.network.visualisations.model.SizeBarOptions;
56 import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsLocation;
57 import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsSize;
58 import org.simantics.utils.datastructures.Pair;
59 import org.simantics.utils.ui.dialogs.ShowError;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
63 public class DynamicVisualisationsUI extends Composite {
65 private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationsUI.class);
67 private Resource parentResource;
68 private VisualisationListener listener;
69 private DynamicVisualisation visualisation;
71 private Button showSizeButton;
72 private Button sizeTicksButton;
73 private Button sizeGradientButton;
74 private Combo sizeLocationCombo;
75 private Combo sizeSizeCombo;
76 private Button showColorButton;
77 private Button colorTicksButton;
78 private Button colorGradientButton;
79 private Combo colorLocationCombo;
80 private Combo colorSizeCombo;
82 private Combo templateSelectionCombo;
84 private List<Supplier<Pair<String, DynamicColorContribution>>> colorSuppliers;
86 private Button removeVisualisationTemplateButton;
88 private Button applyButton;
90 public DynamicVisualisationsUI(Composite parent, int style) {
92 // ScrolledComposite scrolledComposite = new ScrolledComposite(this, SWT.V_SCROLL);
93 // scrolledComposite.setLayout(new GridLayout(1, false));
94 // scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
96 // Composite firstContent = new Composite(scrolledComposite, SWT.NONE);
97 // firstContent.setLayout(new GridLayout(1, false));
98 // firstContent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
100 defaultInitializeUI(this);
102 // scrolledComposite.setContent(firstContent);
103 // scrolledComposite.setExpandHorizontal(true);
104 // scrolledComposite.setExpandVertical(true);
105 // scrolledComposite.setMinSize(firstContent.computeSize(SWT.DEFAULT, SWT.DEFAULT));
109 private void defaultInitializeUI(Composite parent) {
111 GridDataFactory.fillDefaults().grab(true, true).applyTo(parent);
112 GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5).applyTo(parent);
114 Composite selectionComposite = new Composite(parent, SWT.NONE);
115 GridDataFactory.fillDefaults().grab(true, false).applyTo(selectionComposite);
116 GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(selectionComposite);
118 Label templateNameLabel = new Label(selectionComposite, SWT.NONE);
119 templateNameLabel.setText("Visualisation template");
120 templateSelectionCombo = new Combo(selectionComposite, SWT.READ_ONLY);
121 GridDataFactory.fillDefaults().grab(true, false).applyTo(templateSelectionCombo);
122 templateSelectionCombo.addSelectionListener(new SelectionAdapter() {
125 public void widgetSelected(SelectionEvent e) {
126 String item = templateSelectionCombo.getItem(templateSelectionCombo.getSelectionIndex());
127 for (NamedResource template : visualisations) {
128 if (item.equals(template.getName())) {
129 Simantics.getSession().asyncRequest(new WriteRequest() {
132 public void perform(WriteGraph graph) throws DatabaseException {
133 Resource vf = DistrictNetworkUtil.getVisualisationFolder(graph, parentResource);
134 DistrictNetworkUtil.setActiveVisualisation(graph, vf, template.getResource());
143 Composite coloringObjectsComposite = new Composite(parent, SWT.NONE);
144 GridDataFactory.fillDefaults().grab(true, false).applyTo(coloringObjectsComposite);
145 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(coloringObjectsComposite);
146 initializeColoringObjects(coloringObjectsComposite);
148 Composite colorBarsComposite = new Composite(parent, SWT.NONE);
149 GridDataFactory.fillDefaults().grab(true, false).applyTo(colorBarsComposite);
150 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(colorBarsComposite);
151 initializeColorBars(colorBarsComposite);
153 Composite objectSizesComposite = new Composite(parent, SWT.NONE);
154 GridDataFactory.fillDefaults().grab(true, false).applyTo(objectSizesComposite);
155 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(objectSizesComposite);
156 initializeObjectSizes(objectSizesComposite);
158 Composite sizeBarsComposite = new Composite(parent, SWT.NONE);
159 GridDataFactory.fillDefaults().grab(true, false).applyTo(sizeBarsComposite);
160 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(sizeBarsComposite);
161 initializeSizeBars(sizeBarsComposite);
163 Composite buttonBarsComposite = new Composite(parent, SWT.NONE);
164 GridDataFactory.fillDefaults().grab(true, false).applyTo(buttonBarsComposite);
165 GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonBarsComposite);
167 Button saveVisualisationTemplateAsButton = new Button(buttonBarsComposite, SWT.NONE);
168 saveVisualisationTemplateAsButton.setText("Save as visualisation template");
169 saveVisualisationTemplateAsButton.addSelectionListener(new SelectionAdapter() {
172 public void widgetSelected(SelectionEvent e) {
173 showSaveVisualisationTemplateDialog(e.widget.getDisplay().getActiveShell());
177 applyButton = new Button(buttonBarsComposite, SWT.NONE);
178 applyButton.setText("Apply");
179 applyButton.setEnabled(visualisation != null);
180 applyButton.addSelectionListener(new SelectionAdapter() {
183 public void widgetSelected(SelectionEvent e) {
185 persistVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
186 } catch (Exception e1) {
187 LOGGER.error("Could not persist visualisation template", e1);
188 ShowError.showError("Could not persist visualisation template", e1.getMessage(), e1);
193 removeVisualisationTemplateButton = new Button(buttonBarsComposite, SWT.NONE);
194 removeVisualisationTemplateButton.setText("Remove");
195 removeVisualisationTemplateButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null);
196 removeVisualisationTemplateButton.addSelectionListener(new SelectionAdapter() {
199 public void widgetSelected(SelectionEvent e) {
200 removeVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
206 protected void removeVisualisationTemplate(String name, Optional<Resource> of) {
207 if (of.isPresent()) {
208 Resource visualisation = of.get();
209 Simantics.getSession().asyncRequest(new WriteRequest() {
212 public void perform(WriteGraph graph) throws DatabaseException {
213 RemoverUtil.remove(graph, visualisation);
219 private void showSaveVisualisationTemplateDialog(Shell shell) {
221 InputDialog dialog = new InputDialog(shell, "Save visualisation template", "Give template a name", "", new IInputValidator() {
224 public String isValid(String newText) {
225 if (newText == null || newText.isEmpty())
226 return "Name cannot be empty";
231 if (dialog.open() == Dialog.OK) {
232 String name = dialog.getValue();
234 persistVisualisationTemplate(name, Optional.empty());
235 } catch (Exception e) {
236 LOGGER.error("Could not persist visualisation template", e);
237 ShowError.showError("Could not persist visualisation template", e.getMessage(), e);
242 private void persistVisualisationTemplate(String templateName, Optional<Resource> existing) throws Exception {
244 List<Pair<String, DynamicColorContribution>> colorCollect = colorSuppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
246 String colorLocation = colorLocationCombo.getItem(colorLocationCombo.getSelectionIndex());
247 String colorSize = colorSizeCombo.getItem(colorSizeCombo.getSelectionIndex());
249 ColorBarOptions colorBarOptions = new ColorBarOptions()
250 .showColorBars(showColorButton.getSelection())
251 .showColorBarsTicks(colorTicksButton.getSelection())
252 .useGradients(colorGradientButton.getSelection())
253 .withLocation(ColorBarsLocation.valueOf(colorLocation))
254 .withSize(ColorBarsSize.valueOf(colorSize));
256 List<Pair<String, DynamicSizeContribution>> sizeCollect = sizeSuppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
258 String sizeLocation = sizeLocationCombo.getItem(sizeLocationCombo.getSelectionIndex());
259 String sizeSize = sizeSizeCombo.getItem(sizeSizeCombo.getSelectionIndex());
261 SizeBarOptions sizeBarOptions = new SizeBarOptions()
262 .showSizeBars(showSizeButton.getSelection())
263 .showSizeBarsTicks(sizeTicksButton.getSelection())
264 .useGradients(sizeGradientButton.getSelection())
265 .withLocation(SizeBarsLocation.valueOf(sizeLocation))
266 .withSize(SizeBarsSize.valueOf(sizeSize));
268 Simantics.getSession().asyncRequest(new WriteRequest() {
271 public void perform(WriteGraph graph) throws DatabaseException {
273 if (existing.isPresent()) {
274 exist = existing.get();
276 exist = DistrictNetworkUtil.createVisualisation(graph, parentResource, templateName);
279 DistrictNetworkUtil.setColorContributions(graph, exist, colorCollect);
281 DistrictNetworkUtil.setColorBarOptions(graph, exist, colorBarOptions);
282 DistrictNetworkUtil.setSizeContributions(graph, exist, sizeCollect);
283 DistrictNetworkUtil.setSizeBarOptions(graph, exist, sizeBarOptions);
288 private void initializeColoringObjects(Composite parent) {
289 Group group = new Group(parent, SWT.NONE);
290 group.setText("Coloring Objects");
291 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
292 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
295 createColoringObjectHeaderRow(group);
297 colorSuppliers = new ArrayList<>();
300 Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>> result = Simantics.getSession().syncRequest(new UniqueRead<Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>>>() {
303 public Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>> perform(ReadGraph graph) throws DatabaseException {
304 Map<String, DynamicColorMap> dynamicColorMaps = DynamicVisualisationsContributions.dynamicColorMaps(graph);
305 return Pair.make(DynamicVisualisationsContributions.dynamicColoringObjects(graph), dynamicColorMaps);
309 for (DynamicColoringObject object : result.first) {
310 colorSuppliers.add(createColoringObjectRow(group, object, result.second));
313 } catch (DatabaseException e) {
314 LOGGER.error("Could not create coloring objecst", e);
319 private void createColoringObjectHeaderRow(Composite parent) {
321 Label label = new Label(parent, SWT.NONE);
322 label.setText("Label");
323 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
325 label = new Label(parent, SWT.NONE);
326 label.setText("Used");
327 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
329 label = new Label(parent, SWT.NONE);
330 label.setText("Variable");
331 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
333 label = new Label(parent, SWT.NONE);
334 label.setText("Min");
335 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
337 label = new Label(parent, SWT.NONE);
338 label.setText("Max");
339 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
341 label = new Label(parent, SWT.NONE);
342 label.setText("Unit");
343 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
345 label = new Label(parent, SWT.NONE);
346 label.setText("ColorMap");
347 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
349 label = new Label(parent, SWT.NONE);
350 label.setText("Default");
351 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
354 private Map<String, ColoringObjectRow> coloringRows = new HashMap<>();
355 private Map<String, SizingObjectRow> sizingRows = new HashMap<>();
357 private VisualisationsListener visualisationsListener;
359 private Collection<NamedResource> visualisations;
361 private List<Supplier<Pair<String, DynamicSizeContribution>>> sizeSuppliers;
363 private static class ColoringObjectRow {
365 private final Label label;
366 private final Button usedButton;
367 private final Combo variableCombo;
368 private final Text minText;
369 private final Text maxText;
370 private final Text unit;
371 private final Combo colorMapCombo;
372 private final Button defaultButton;
374 public ColoringObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Text unit,
375 Combo colorMapCombo, Button defaultButton) {
378 this.usedButton = usedButton;
379 this.variableCombo = variableCombo;
380 this.minText = minText;
381 this.maxText = maxText;
383 this.colorMapCombo = colorMapCombo;
384 this.defaultButton = defaultButton;
387 public void update(DynamicColorContribution colorContribution) {
388 String[] items = variableCombo.getItems();
389 for (int i = 0; i < items.length; i++) {
390 if (colorContribution.getLabel().equals(items[i])) {
391 variableCombo.select(i);
395 minText.setText(Double.toString(colorContribution.getDefaultMin()));
396 maxText.setText(Double.toString(colorContribution.getDefaultMax()));
397 unit.setText(colorContribution.getUnit());
399 String[] colorItems = colorMapCombo.getItems();
400 for (int i = 0; i < colorItems.length; i++) {
402 if (colorContribution.getDefaultColorMap().getLabel().equals(colorItems[i])) {
403 colorMapCombo.select(i);
407 usedButton.setSelection(colorContribution.isUsed());
408 defaultButton.setSelection(colorContribution.isUseDefault());
410 minText.setEnabled(!colorContribution.isUseDefault());
411 maxText.setEnabled(!colorContribution.isUseDefault());
412 colorMapCombo.setEnabled(!colorContribution.isUseDefault());
416 private static class SizingObjectRow {
418 private final Label label;
419 private final Button usedButton;
420 private final Combo variableCombo;
421 private final Text minText;
422 private final Text maxText;
423 private final Label unit;
424 private final Combo sizeMapCombo;
425 private final Button defaultButton;
427 public SizingObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Label unit,
428 Combo sizeMapCombo, Button defaultButton) {
431 this.usedButton = usedButton;
432 this.variableCombo = variableCombo;
433 this.minText = minText;
434 this.maxText = maxText;
436 this.sizeMapCombo = sizeMapCombo;
437 this.defaultButton = defaultButton;
440 public void update(DynamicSizeContribution sizeContribution) {
441 String[] items = variableCombo.getItems();
442 for (int i = 0; i < items.length; i++) {
443 if (sizeContribution.getLabel().equals(items[i])) {
444 variableCombo.select(i);
448 minText.setText(Double.toString(sizeContribution.getDefaultMin()));
449 maxText.setText(Double.toString(sizeContribution.getDefaultMax()));
450 unit.setText(sizeContribution.getUnit());
452 String[] sizeItems = sizeMapCombo.getItems();
453 for (int i = 0; i < sizeItems.length; i++) {
454 if (sizeContribution.getDefaultSizeMap().getLabel().equals(sizeItems[i])) {
455 sizeMapCombo.select(i);
459 usedButton.setSelection(sizeContribution.isUsed());
460 defaultButton.setSelection(sizeContribution.isUseDefault());
462 minText.setEnabled(!sizeContribution.isUseDefault());
463 maxText.setEnabled(!sizeContribution.isUseDefault());
464 sizeMapCombo.setEnabled(!sizeContribution.isUseDefault());
468 private Supplier<Pair<String, DynamicColorContribution>> createColoringObjectRow(Composite parent, DynamicColoringObject object, Map<String, DynamicColorMap> colorMaps) {
469 Label label = new Label(parent, SWT.NONE);
470 label.setText(object.getColoringObject().getName());
471 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
473 Map<String, DynamicColorContribution> colorContributions = object.getColorContributions();
475 Button usedButton = new Button(parent, SWT.CHECK);
476 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
478 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
479 variableCombo.setItems(colorContributions.keySet().toArray(new String[colorContributions.size()]));
481 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
483 Text minText = new Text(parent, SWT.BORDER);
484 GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(minText);
486 Text maxText = new Text(parent, SWT.BORDER);
487 GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
489 Text unit = new Text(parent, SWT.READ_ONLY);
490 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(unit);
492 Combo colorMapCombo = new Combo(parent, SWT.READ_ONLY);
493 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(colorMapCombo);
494 colorMapCombo.setItems(colorMaps.keySet().toArray(new String[colorMaps.keySet().size()]));
496 Button defaultButton = new Button(parent, SWT.CHECK);
497 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
498 defaultButton.addSelectionListener(new SelectionAdapter() {
501 public void widgetSelected(SelectionEvent e) {
502 int index = variableCombo.getSelectionIndex();
504 String key = variableCombo.getItem(index);
505 DynamicColorContribution cont = colorContributions.get(key);
507 minText.setText(Double.toString(cont.getDefaultMin()));
508 minText.setEnabled(!defaultButton.getSelection());
509 maxText.setText(Double.toString(cont.getDefaultMax()));
510 maxText.setEnabled(!defaultButton.getSelection());
511 unit.setText(cont.getUnit());
513 String[] items = colorMapCombo.getItems();
514 for (int i = 0; i < items.length; i++) {
515 String item = items[i];
516 if (item.equals(cont.getDefaultColorMap().getLabel())) {
517 colorMapCombo.select(i);
521 colorMapCombo.setEnabled(!defaultButton.getSelection());
526 variableCombo.addSelectionListener(new SelectionAdapter() {
529 public void widgetSelected(SelectionEvent e) {
530 // handle update for others
531 int index = variableCombo.getSelectionIndex();
533 String key = variableCombo.getItem(index);
534 DynamicColorContribution cont = colorContributions.get(key);
536 if (minText.getText().isEmpty()) {
537 minText.setText(Double.toString(cont.getDefaultMin()));
539 if (maxText.getText().isEmpty()) {
540 maxText.setText(Double.toString(cont.getDefaultMax()));
542 unit.setText(cont.getUnit());
544 String[] items = colorMapCombo.getItems();
545 for (int i = 0; i < items.length; i++) {
546 String item = items[i];
547 if (item.equals(cont.getDefaultColorMap().getLabel())) {
548 colorMapCombo.select(i);
553 defaultButton.setSelection(true);
558 coloringRows.put(object.getColoringObject().getName(), new ColoringObjectRow(label, usedButton, variableCombo, minText, maxText, unit, colorMapCombo, defaultButton));
560 return new Supplier<Pair<String, DynamicColorContribution>>() {
563 public Pair<String, DynamicColorContribution> get() {
564 int selectionIndex = variableCombo.getSelectionIndex();
565 if (selectionIndex >= 0) {
566 String key = variableCombo.getItem(selectionIndex);
567 DynamicColorContribution cont = colorContributions.get(key);
569 String colorMap = colorMapCombo.getItem(colorMapCombo.getSelectionIndex());
571 Map<String, DynamicColorMap> colorMaps = Simantics.getSession().syncRequest(new UniqueRead<Map<String, DynamicColorMap>>() {
574 public Map<String, DynamicColorMap> perform(ReadGraph graph) throws DatabaseException {
575 return DynamicVisualisationsContributions.dynamicColorMaps(graph);
578 DynamicColorMap dColorMap = colorMaps.get(colorMap);
579 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
581 DynamicColorContribution dcc = new DynamicColorContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
582 dcc.setUsed(usedButton.getSelection());
583 dcc.setUseDefault(defaultButton.getSelection());
585 return Pair.make(object.getColoringObject().getName(), dcc);
586 } catch (DatabaseException e) {
587 LOGGER.error("Could not get DynamicColorContribution", e);
596 private void createSizingObjectHeaderRow(Composite parent) {
598 Label label = new Label(parent, SWT.NONE);
599 label.setText("Label");
600 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
602 label = new Label(parent, SWT.NONE);
603 label.setText("Used");
604 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
606 label = new Label(parent, SWT.NONE);
607 label.setText("Variable");
608 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
610 label = new Label(parent, SWT.NONE);
611 label.setText("Min");
612 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
614 label = new Label(parent, SWT.NONE);
615 label.setText("Max");
616 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
618 label = new Label(parent, SWT.NONE);
619 label.setText("Unit");
620 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
622 label = new Label(parent, SWT.NONE);
623 label.setText("SizeMap");
624 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
626 label = new Label(parent, SWT.NONE);
627 label.setText("Default");
628 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
631 private Supplier<Pair<String, DynamicSizeContribution>> createSizingObjectRow(Composite parent, DynamicSizingObject object, Map<String, DynamicSizeMap> sizeMaps) {
632 Label label = new Label(parent, SWT.NONE);
633 label.setText(object.getSizingObject().getName());
634 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
636 Map<String, DynamicSizeContribution> sizeContributions = object.getSizeContributions();
638 Button usedButton = new Button(parent, SWT.CHECK);
639 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
641 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
642 variableCombo.setItems(sizeContributions.keySet().toArray(new String[sizeContributions.size()]));
644 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
646 Text minText = new Text(parent, SWT.BORDER);
647 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(minText);
649 Text maxText = new Text(parent, SWT.BORDER);
650 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
652 Label unit = new Label(parent, SWT.NONE);
653 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(unit);
655 Combo sizeMapCombo = new Combo(parent, SWT.READ_ONLY);
656 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(sizeMapCombo);
657 sizeMapCombo.setItems(sizeMaps.keySet().toArray(new String[sizeMaps.keySet().size()]));
659 Button defaultButton = new Button(parent, SWT.CHECK);
660 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
661 defaultButton.addSelectionListener(new SelectionAdapter() {
664 public void widgetSelected(SelectionEvent e) {
665 int index = variableCombo.getSelectionIndex();
667 String key = variableCombo.getItem(index);
668 DynamicSizeContribution cont = sizeContributions.get(key);
670 minText.setText(Double.toString(cont.getDefaultMin()));
671 minText.setEnabled(!defaultButton.getSelection());
672 maxText.setText(Double.toString(cont.getDefaultMax()));
673 maxText.setEnabled(!defaultButton.getSelection());
674 unit.setText(cont.getUnit());
676 String[] items = sizeMapCombo.getItems();
677 for (int i = 0; i < items.length; i++) {
678 String item = items[i];
679 if (item.equals(cont.getDefaultSizeMap().getLabel())) {
680 sizeMapCombo.select(i);
684 sizeMapCombo.setEnabled(!defaultButton.getSelection());
689 variableCombo.addSelectionListener(new SelectionAdapter() {
692 public void widgetSelected(SelectionEvent e) {
693 // handle update for others
694 String key = variableCombo.getItem(variableCombo.getSelectionIndex());
695 DynamicSizeContribution cont = sizeContributions.get(key);
697 if (minText.getText().isEmpty()) {
698 minText.setText(Double.toString(cont.getDefaultMin()));
700 if (maxText.getText().isEmpty()) {
701 maxText.setText(Double.toString(cont.getDefaultMax()));
703 unit.setText(cont.getUnit());
705 String[] items = sizeMapCombo.getItems();
706 for (int i = 0; i < items.length; i++) {
707 String item = items[i];
708 if (item.equals(cont.getDefaultSizeMap().getLabel())) {
709 sizeMapCombo.select(i);
714 defaultButton.setSelection(true);
718 sizingRows.put(object.getSizingObject().getName(), new SizingObjectRow(label, usedButton, variableCombo, minText, maxText, unit, sizeMapCombo, defaultButton));
720 return new Supplier<Pair<String, DynamicSizeContribution>>() {
723 public Pair<String, DynamicSizeContribution> get() {
724 int selectionIndex = variableCombo.getSelectionIndex();
725 if (selectionIndex >= 0) {
726 String key = variableCombo.getItem(selectionIndex);
727 DynamicSizeContribution cont = sizeContributions.get(key);
729 String sizeMap = sizeMapCombo.getItem(sizeMapCombo.getSelectionIndex());
731 Map<String, DynamicSizeMap> sizeMaps = Simantics.getSession().syncRequest(new UniqueRead<Map<String, DynamicSizeMap>>() {
734 public Map<String, DynamicSizeMap> perform(ReadGraph graph) throws DatabaseException {
735 return DynamicVisualisationsContributions.dynamicSizeMaps(graph);
738 DynamicSizeMap dColorMap = sizeMaps.get(sizeMap);
739 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
741 DynamicSizeContribution dsc = new DynamicSizeContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
742 dsc.setUsed(usedButton.getSelection());
743 dsc.setUseDefault(defaultButton.getSelection());
745 return Pair.make(object.getSizingObject().getName(), dsc);
746 } catch (DatabaseException e) {
747 LOGGER.error("Could not get DynamicColorContribution", e);
756 private void initializeColorBars(Composite parent) {
757 Group group = new Group(parent, SWT.NONE);
758 group.setText("Color Bars");
759 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
760 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
762 createColorBars(group);
765 private void createColorBars(Composite parent) {
767 showColorButton = new Button(parent, SWT.CHECK);
768 showColorButton.setText("Show");
770 colorTicksButton = new Button(parent, SWT.CHECK);
771 colorTicksButton.setText("Ticks");
773 colorGradientButton = new Button(parent, SWT.CHECK);
774 colorGradientButton.setText("Gradients");
776 Label label = new Label(parent, SWT.NONE);
777 label.setText("Location");
778 colorLocationCombo = new Combo(parent, SWT.READ_ONLY);
779 String[] colorLocationItems = Stream.of(ColorBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new);
780 colorLocationCombo.setItems(colorLocationItems);
781 if (colorLocationItems.length > 0) {
782 colorLocationCombo.select(0);
785 label = new Label(parent, SWT.NONE);
786 label.setText("Size");
787 colorSizeCombo = new Combo(parent, SWT.READ_ONLY);
788 String[] colorSizeItems = Stream.of(ColorBarsSize.values()).map(size -> size.toString()).toArray(String[]::new);
789 colorSizeCombo.setItems(colorSizeItems);
790 if (colorSizeItems.length > 0) {
791 colorSizeCombo.select(0);
795 private void initializeObjectSizes(Composite parent) {
796 Group group = new Group(parent, SWT.NONE);
797 group.setText("Object Sizes");
798 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
799 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
802 createSizingObjectHeaderRow(group);
803 createObjectSizes(group);
807 private void createObjectSizes(Composite parent) {
809 sizeSuppliers = new ArrayList<>();
811 Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>> resultSizing = Simantics.getSession().syncRequest(new UniqueRead<Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>>>() {
814 public Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>> perform(ReadGraph graph) throws DatabaseException {
815 Map<String, DynamicSizeMap> dynamicSizeMaps = DynamicVisualisationsContributions.dynamicSizeMaps(graph);
816 return Pair.make(DynamicVisualisationsContributions.dynamicSizingObjects(graph), dynamicSizeMaps);
820 for (DynamicSizingObject object : resultSizing.first) {
821 sizeSuppliers.add(createSizingObjectRow(parent, object, resultSizing.second));
823 } catch (DatabaseException e) {
824 LOGGER.error("Could not create object sizes", e);
828 private void initializeSizeBars(Composite parent) {
829 Group group = new Group(parent, SWT.NONE);
830 group.setText("Size Bars");
831 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
832 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
834 createSizeBars(group);
837 private void createSizeBars(Composite parent) {
838 showSizeButton = new Button(parent, SWT.CHECK);
839 showSizeButton.setText("Show");
841 sizeTicksButton = new Button(parent, SWT.CHECK);
842 sizeTicksButton.setText("Ticks");
844 sizeGradientButton = new Button(parent, SWT.CHECK);
845 sizeGradientButton.setText("Gradient");
847 Label label = new Label(parent, SWT.NONE);
848 label.setText("Location");
849 sizeLocationCombo = new Combo(parent, SWT.READ_ONLY);
850 String[] sizeLocationItems = Stream.of(SizeBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new);
851 sizeLocationCombo.setItems(sizeLocationItems);
852 if (sizeLocationItems.length > 0) {
853 sizeLocationCombo.select(0);
856 label = new Label(parent, SWT.NONE);
857 label.setText("Size");
858 sizeSizeCombo = new Combo(parent, SWT.READ_ONLY);
859 String[] sizeSizeItems = Stream.of(SizeBarsSize.values()).map(size -> size.toString()).toArray(String[]::new);
860 sizeSizeCombo.setItems(sizeSizeItems);
861 if (sizeSizeItems.length > 0) {
862 sizeSizeCombo.select(0);
866 public void setParentResource(Resource parentResource) {
867 if (this.parentResource != parentResource) {
868 this.parentResource = parentResource;
873 private void updateListening() {
874 if (visualisationsListener != null)
875 visualisationsListener.dispose();
876 visualisationsListener = new VisualisationsListener(this);
877 Simantics.getSession().asyncRequest(new DynamicVisualisationsRequest(parentResource), visualisationsListener);
879 if (listener != null)
881 listener = new VisualisationListener(this);
882 Simantics.getSession().asyncRequest(new ActiveDynamicVisualisationsRequest(parentResource), listener);
885 private static class VisualisationsListener implements Listener<Collection<NamedResource>> {
887 private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationsListener.class);
889 private boolean disposed;
890 private DynamicVisualisationsUI ui;
892 public VisualisationsListener(DynamicVisualisationsUI ui) {
897 public void execute(Collection<NamedResource> result) {
898 ui.updateVisualisations(result);
902 public void exception(Throwable t) {
903 LOGGER.error("Could not listen visualisation", t);
907 public boolean isDisposed() {
908 return disposed || ui.isDisposed();
911 public void dispose() {
912 this.disposed = true;
916 private static class VisualisationListener implements Listener<DynamicVisualisation> {
918 private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationListener.class);
920 private boolean disposed;
921 private DynamicVisualisationsUI ui;
923 public VisualisationListener(DynamicVisualisationsUI ui) {
928 public void execute(DynamicVisualisation result) {
929 ui.updateVisualisation(result);
933 public void exception(Throwable t) {
934 LOGGER.error("Could not listen visualisation", t);
938 public boolean isDisposed() {
939 return disposed || ui.isDisposed();
942 public void dispose() {
943 this.disposed = true;
947 public void updateVisualisation(DynamicVisualisation result) {
948 this.visualisation = result;
949 Display.getDefault().asyncExec(() -> {
950 if (getParent().isDisposed())
953 applyButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null);
954 removeVisualisationTemplateButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null);
956 if (visualisation != null) {
957 String[] items = templateSelectionCombo.getItems();
958 for (int i = 0; i < items.length; i++) {
959 if (visualisation.getName().equals(items[i])) {
960 templateSelectionCombo.select(i);
965 Map<String, DynamicColorContribution> colorContributions = visualisation.getColorContributions();
966 for (Entry<String, DynamicColorContribution> entry : colorContributions.entrySet()) {
968 ColoringObjectRow coloringObjectRow = coloringRows.get(entry.getKey());
969 if (coloringObjectRow != null) {
971 coloringObjectRow.update(entry.getValue());
974 LOGGER.info("No coloring object visualisation row for key {}", entry.getKey());
977 ColorBarOptions colorOptions = visualisation.getColorBarOptions();
978 showColorButton.setSelection(colorOptions.isShowColorBars());
979 colorTicksButton.setSelection(colorOptions.isShowColorBarsTicks());
980 colorGradientButton.setSelection(colorOptions.isUseGradients());
981 for (int i = 0; i < colorLocationCombo.getItems().length; i++) {
982 String item = colorLocationCombo.getItem(i);
983 if (item.equals(colorOptions.getLocation().toString())) {
984 colorLocationCombo.select(i);
988 for (int i = 0; i < colorSizeCombo.getItems().length; i++) {
989 String item = colorSizeCombo.getItem(i);
990 if (item.equals(colorOptions.getSize().toString())) {
991 colorSizeCombo.select(i);
996 Map<String, DynamicSizeContribution> sizeContributions = visualisation.getSizeContributions();
997 for (Entry<String, DynamicSizeContribution> entry : sizeContributions.entrySet()) {
999 SizingObjectRow sizingObjectRow = sizingRows.get(entry.getKey());
1000 if (sizingObjectRow != null) {
1002 sizingObjectRow.update(entry.getValue());
1005 LOGGER.info("No sizing object visualisation row for key {}", entry.getKey());
1008 SizeBarOptions sizeOptions = visualisation.getSizeBarOptions();
1009 showSizeButton.setSelection(sizeOptions.isShowSizeBars());
1010 sizeTicksButton.setSelection(sizeOptions.isShowSizeBarsTicks());
1011 sizeGradientButton.setSelection(sizeOptions.isUseGradients());
1012 for (int i = 0; i < sizeLocationCombo.getItems().length; i++) {
1013 String item = sizeLocationCombo.getItem(i);
1014 if (item.equals(sizeOptions.getLocation().toString())) {
1015 sizeLocationCombo.select(i);
1019 for (int i = 0; i < sizeSizeCombo.getItems().length; i++) {
1020 String item = sizeSizeCombo.getItem(i);
1021 if (item.equals(sizeOptions.getSize().toString())) {
1022 sizeSizeCombo.select(i);
1030 public void updateVisualisations(Collection<NamedResource> result) {
1031 this.visualisations = result;
1033 Display.getDefault().asyncExec(() -> {
1034 if (getParent().isDisposed())
1036 templateSelectionCombo.setItems(visualisations.stream().map(NamedResource::getName).collect(Collectors.toList()).toArray(new String[visualisations.size()]));
1038 if (visualisation != null) {
1039 String[] items = templateSelectionCombo.getItems();
1040 for (int i = 0; i < items.length; i++) {
1041 if (visualisation.getName().equals(items[i])) {
1042 templateSelectionCombo.select(i);