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.ontology.DistrictNetworkResource;
43 import org.simantics.district.network.profile.ActiveDynamicVisualisationsRequest;
44 import org.simantics.district.network.profile.DynamicVisualisationsRequest;
45 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions;
46 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicColoringObject;
47 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicSizingObject;
48 import org.simantics.district.network.visualisations.model.ColorBarOptions;
49 import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsLocation;
50 import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsSize;
51 import org.simantics.district.network.visualisations.model.DynamicColorContribution;
52 import org.simantics.district.network.visualisations.model.DynamicColorMap;
53 import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
54 import org.simantics.district.network.visualisations.model.DynamicSizeMap;
55 import org.simantics.district.network.visualisations.model.DynamicVisualisation;
56 import org.simantics.district.network.visualisations.model.SizeBarOptions;
57 import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsLocation;
58 import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsSize;
59 import org.simantics.utils.datastructures.Pair;
60 import org.simantics.utils.ui.dialogs.ShowError;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
64 public class DynamicVisualisationsUI extends Composite {
66 private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationsUI.class);
68 private Resource diagramResource;
69 private VisualisationListener listener;
70 private DynamicVisualisation visualisation;
72 private Button showSizeButton;
73 private Button sizeTicksButton;
74 private Button sizeGradientButton;
75 private Combo sizeLocationCombo;
76 private Combo sizeSizeCombo;
77 private Button showColorButton;
78 private Button colorTicksButton;
79 private Button colorGradientButton;
80 private Combo colorLocationCombo;
81 private Combo colorSizeCombo;
83 private Combo templateSelectionCombo;
85 private List<Supplier<Pair<String, DynamicColorContribution>>> colorSuppliers;
87 private Button removeVisualisationTemplateButton;
89 private Button applyButton;
91 public DynamicVisualisationsUI(Composite parent, int style) {
93 // ScrolledComposite scrolledComposite = new ScrolledComposite(this, SWT.V_SCROLL);
94 // scrolledComposite.setLayout(new GridLayout(1, false));
95 // scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
97 // Composite firstContent = new Composite(scrolledComposite, SWT.NONE);
98 // firstContent.setLayout(new GridLayout(1, false));
99 // firstContent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
101 defaultInitializeUI(this);
103 // scrolledComposite.setContent(firstContent);
104 // scrolledComposite.setExpandHorizontal(true);
105 // scrolledComposite.setExpandVertical(true);
106 // scrolledComposite.setMinSize(firstContent.computeSize(SWT.DEFAULT, SWT.DEFAULT));
110 private void defaultInitializeUI(Composite parent) {
112 GridDataFactory.fillDefaults().grab(true, true).applyTo(parent);
113 GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5).applyTo(parent);
115 Composite selectionComposite = new Composite(parent, SWT.NONE);
116 GridDataFactory.fillDefaults().grab(true, false).applyTo(selectionComposite);
117 GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(selectionComposite);
119 Label templateNameLabel = new Label(selectionComposite, SWT.NONE);
120 templateNameLabel.setText("Visualisation template");
121 templateSelectionCombo = new Combo(selectionComposite, SWT.READ_ONLY);
122 GridDataFactory.fillDefaults().grab(true, false).applyTo(templateSelectionCombo);
123 templateSelectionCombo.addSelectionListener(new SelectionAdapter() {
126 public void widgetSelected(SelectionEvent e) {
127 String item = templateSelectionCombo.getItem(templateSelectionCombo.getSelectionIndex());
128 for (NamedResource template : visualisations) {
129 if (item.equals(template.getName())) {
130 Simantics.getSession().asyncRequest(new WriteRequest() {
133 public void perform(WriteGraph graph) throws DatabaseException {
134 DistrictNetworkUtil.setActiveVisualisation(graph, diagramResource, 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 {
272 DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
274 if (existing.isPresent()) {
275 exist = existing.get();
277 exist = DistrictNetworkUtil.createVisualisation(graph, diagramResource, templateName);
280 DistrictNetworkUtil.setColorContributions(graph, exist, colorCollect);
282 DistrictNetworkUtil.setColorBarOptions(graph, exist, colorBarOptions);
283 DistrictNetworkUtil.setSizeContributions(graph, exist, sizeCollect);
284 DistrictNetworkUtil.setSizeBarOptions(graph, exist, sizeBarOptions);
289 private void initializeColoringObjects(Composite parent) {
290 Group group = new Group(parent, SWT.NONE);
291 group.setText("Coloring Objects");
292 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
293 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
296 createColoringObjectHeaderRow(group);
298 colorSuppliers = new ArrayList<>();
301 Collection<DynamicColoringObject> result = Simantics.getSession().syncRequest(new UniqueRead<Collection<DynamicColoringObject>>() {
304 public Collection<DynamicColoringObject> perform(ReadGraph graph) throws DatabaseException {
305 return DynamicVisualisationsContributions.dynamicColoringObjects(graph);
309 for (DynamicColoringObject object : result) {
310 colorSuppliers.add(createColoringObjectRow(group, object));
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 Label unit;
371 private final Combo colorMapCombo;
372 private final Button defaultButton;
374 public ColoringObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Label 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 // color map only supports single for now
400 colorMapCombo.setItems(colorContribution.getDefaultColorMap().getLabel());
401 colorMapCombo.select(0);
402 // String[] colorItems = colorMapCombo.getItems();
403 // for (int i = 0; i < colorItems.length; i++) {
405 // if (colorContribution.getDefaultColorMap().getLabel().equals(colorItems[i])) {
406 // colorMapCombo.select(i);
410 usedButton.setSelection(colorContribution.isUsed());
411 defaultButton.setSelection(colorContribution.isUseDefault());
413 minText.setEnabled(!colorContribution.isUseDefault());
414 maxText.setEnabled(!colorContribution.isUseDefault());
415 colorMapCombo.setEnabled(!colorContribution.isUseDefault());
419 private static class SizingObjectRow {
421 private final Label label;
422 private final Button usedButton;
423 private final Combo variableCombo;
424 private final Text minText;
425 private final Text maxText;
426 private final Label unit;
427 private final Combo sizeMapCombo;
428 private final Button defaultButton;
430 public SizingObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Label unit,
431 Combo sizeMapCombo, Button defaultButton) {
434 this.usedButton = usedButton;
435 this.variableCombo = variableCombo;
436 this.minText = minText;
437 this.maxText = maxText;
439 this.sizeMapCombo = sizeMapCombo;
440 this.defaultButton = defaultButton;
443 public void update(DynamicSizeContribution sizeContribution) {
444 String[] items = variableCombo.getItems();
445 for (int i = 0; i < items.length; i++) {
446 if (sizeContribution.getLabel().equals(items[i])) {
447 variableCombo.select(i);
451 minText.setText(Double.toString(sizeContribution.getDefaultMin()));
452 maxText.setText(Double.toString(sizeContribution.getDefaultMax()));
453 unit.setText(sizeContribution.getUnit());
455 // color map only supports single for now
456 sizeMapCombo.setItems(sizeContribution.getDefaultSizeMap().getLabel());
457 sizeMapCombo.select(0);
458 // String[] colorItems = colorMapCombo.getItems();
459 // for (int i = 0; i < colorItems.length; i++) {
461 // if (colorContribution.getDefaultColorMap().getLabel().equals(colorItems[i])) {
462 // colorMapCombo.select(i);
466 usedButton.setSelection(sizeContribution.isUsed());
467 defaultButton.setSelection(sizeContribution.isUseDefault());
469 minText.setEnabled(!sizeContribution.isUseDefault());
470 maxText.setEnabled(!sizeContribution.isUseDefault());
471 sizeMapCombo.setEnabled(!sizeContribution.isUseDefault());
475 private Supplier<Pair<String, DynamicColorContribution>> createColoringObjectRow(Composite parent, DynamicColoringObject object) {
476 Label label = new Label(parent, SWT.NONE);
477 label.setText(object.getColoringObject().getName());
478 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
480 Map<String, DynamicColorContribution> colorContributions = object.getColorContributions();
482 Button usedButton = new Button(parent, SWT.CHECK);
483 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
485 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
486 variableCombo.setItems(colorContributions.keySet().toArray(new String[colorContributions.size()]));
488 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
490 Text minText = new Text(parent, SWT.BORDER);
491 GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(minText);
493 Text maxText = new Text(parent, SWT.BORDER);
494 GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
496 Label unit = new Label(parent, SWT.NONE);
498 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(unit);
500 Combo colorMapCombo = new Combo(parent, SWT.READ_ONLY);
501 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(colorMapCombo);
503 Button defaultButton = new Button(parent, SWT.CHECK);
504 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
505 defaultButton.addSelectionListener(new SelectionAdapter() {
508 public void widgetSelected(SelectionEvent e) {
509 int index = variableCombo.getSelectionIndex();
511 String key = variableCombo.getItem(index);
512 DynamicColorContribution cont = colorContributions.get(key);
514 minText.setText(Double.toString(cont.getDefaultMin()));
515 minText.setEnabled(!defaultButton.getSelection());
516 maxText.setText(Double.toString(cont.getDefaultMax()));
517 maxText.setEnabled(!defaultButton.getSelection());
518 unit.setText(cont.getUnit());
520 colorMapCombo.setItems(cont.getDefaultColorMap().getLabel());
521 colorMapCombo.select(0);
522 colorMapCombo.setEnabled(!defaultButton.getSelection());
527 variableCombo.addSelectionListener(new SelectionAdapter() {
530 public void widgetSelected(SelectionEvent e) {
531 // handle update for others
532 int index = variableCombo.getSelectionIndex();
534 String key = variableCombo.getItem(index);
535 DynamicColorContribution cont = colorContributions.get(key);
537 if (minText.getText().isEmpty()) {
538 minText.setText(Double.toString(cont.getDefaultMin()));
540 if (maxText.getText().isEmpty()) {
541 maxText.setText(Double.toString(cont.getDefaultMax()));
543 unit.setText(cont.getUnit());
545 colorMapCombo.setItems(cont.getDefaultColorMap().getLabel());
546 colorMapCombo.select(0);
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) {
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);
636 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
637 variableCombo.setItems(sizeContributions.keySet().toArray(new String[sizeContributions.size()]));
639 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
641 Text minText = new Text(parent, SWT.BORDER);
642 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(minText);
644 Text maxText = new Text(parent, SWT.BORDER);
645 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
647 Label unit = new Label(parent, SWT.NONE);
649 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(unit);
651 Combo sizeMapCombo = new Combo(parent, SWT.READ_ONLY);
652 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(sizeMapCombo);
654 Button defaultButton = new Button(parent, SWT.CHECK);
655 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
657 variableCombo.addSelectionListener(new SelectionAdapter() {
660 public void widgetSelected(SelectionEvent e) {
661 // handle update for others
662 String key = variableCombo.getItem(variableCombo.getSelectionIndex());
663 DynamicSizeContribution cont = sizeContributions.get(key);
665 if (minText.getText().isEmpty()) {
666 minText.setText(Double.toString(cont.getDefaultMin()));
668 if (maxText.getText().isEmpty()) {
669 maxText.setText(Double.toString(cont.getDefaultMax()));
671 unit.setText(cont.getUnit());
673 sizeMapCombo.setItems(cont.getDefaultSizeMap().getLabel());
674 sizeMapCombo.select(0);
676 defaultButton.setSelection(true);
680 sizingRows.put(object.getSizingObject().getName(), new SizingObjectRow(label, usedButton, variableCombo, minText, maxText, unit, sizeMapCombo, defaultButton));
682 return new Supplier<Pair<String, DynamicSizeContribution>>() {
685 public Pair<String, DynamicSizeContribution> get() {
686 int selectionIndex = variableCombo.getSelectionIndex();
687 if (selectionIndex >= 0) {
688 String key = variableCombo.getItem(selectionIndex);
689 DynamicSizeContribution cont = sizeContributions.get(key);
691 String sizeMap = sizeMapCombo.getItem(sizeMapCombo.getSelectionIndex());
693 Map<String, DynamicSizeMap> sizeMaps = Simantics.getSession().syncRequest(new UniqueRead<Map<String, DynamicSizeMap>>() {
696 public Map<String, DynamicSizeMap> perform(ReadGraph graph) throws DatabaseException {
697 return DynamicVisualisationsContributions.dynamicSizeMaps(graph);
700 DynamicSizeMap dColorMap = sizeMaps.get(sizeMap);
701 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
703 DynamicSizeContribution dsc = new DynamicSizeContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
704 dsc.setUsed(usedButton.getSelection());
705 dsc.setUseDefault(defaultButton.getSelection());
707 return Pair.make(object.getSizingObject().getName(), dsc);
708 } catch (DatabaseException e) {
709 LOGGER.error("Could not get DynamicColorContribution", e);
718 private void initializeColorBars(Composite parent) {
719 Group group = new Group(parent, SWT.NONE);
720 group.setText("Color Bars");
721 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
722 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
724 createColorBars(group);
727 private void createColorBars(Composite parent) {
729 showColorButton = new Button(parent, SWT.CHECK);
730 showColorButton.setText("Show");
732 colorTicksButton = new Button(parent, SWT.CHECK);
733 colorTicksButton.setText("Ticks");
735 colorGradientButton = new Button(parent, SWT.CHECK);
736 colorGradientButton.setText("Gradients");
738 Label label = new Label(parent, SWT.NONE);
739 label.setText("Location");
740 colorLocationCombo = new Combo(parent, SWT.READ_ONLY);
741 String[] colorLocationItems = Stream.of(ColorBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new);
742 colorLocationCombo.setItems(colorLocationItems);
743 if (colorLocationItems.length > 0) {
744 colorLocationCombo.select(0);
747 label = new Label(parent, SWT.NONE);
748 label.setText("Size");
749 colorSizeCombo = new Combo(parent, SWT.READ_ONLY);
750 String[] colorSizeItems = Stream.of(ColorBarsSize.values()).map(size -> size.toString()).toArray(String[]::new);
751 colorSizeCombo.setItems(colorSizeItems);
752 if (colorSizeItems.length > 0) {
753 colorSizeCombo.select(0);
757 private void initializeObjectSizes(Composite parent) {
758 Group group = new Group(parent, SWT.NONE);
759 group.setText("Object Sizes");
760 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
761 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
764 createSizingObjectHeaderRow(group);
765 createObjectSizes(group);
769 private void createObjectSizes(Composite parent) {
771 sizeSuppliers = new ArrayList<>();
773 Collection<DynamicSizingObject> resultSizing = Simantics.getSession().syncRequest(new UniqueRead<Collection<DynamicSizingObject>>() {
776 public Collection<DynamicSizingObject> perform(ReadGraph graph) throws DatabaseException {
777 return DynamicVisualisationsContributions.dynamicSizingObjects(graph);
781 for (DynamicSizingObject object : resultSizing) {
782 sizeSuppliers.add(createSizingObjectRow(parent, object));
784 } catch (DatabaseException e) {
785 LOGGER.error("Could not create object sizes", e);
789 private void initializeSizeBars(Composite parent) {
790 Group group = new Group(parent, SWT.NONE);
791 group.setText("Size Bars");
792 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
793 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
795 createSizeBars(group);
798 private void createSizeBars(Composite parent) {
799 showSizeButton = new Button(parent, SWT.CHECK);
800 showSizeButton.setText("Show");
802 sizeTicksButton = new Button(parent, SWT.CHECK);
803 sizeTicksButton.setText("Ticks");
805 sizeGradientButton = new Button(parent, SWT.CHECK);
806 sizeGradientButton.setText("Gradient");
808 Label label = new Label(parent, SWT.NONE);
809 label.setText("Location");
810 sizeLocationCombo = new Combo(parent, SWT.READ_ONLY);
811 String[] sizeLocationItems = Stream.of(SizeBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new);
812 sizeLocationCombo.setItems(sizeLocationItems);
813 if (sizeLocationItems.length > 0) {
814 sizeLocationCombo.select(0);
817 label = new Label(parent, SWT.NONE);
818 label.setText("Size");
819 sizeSizeCombo = new Combo(parent, SWT.READ_ONLY);
820 String[] sizeSizeItems = Stream.of(SizeBarsSize.values()).map(size -> size.toString()).toArray(String[]::new);
821 sizeSizeCombo.setItems(sizeSizeItems);
822 if (sizeSizeItems.length > 0) {
823 sizeSizeCombo.select(0);
827 public void setDiagramResource(Resource diagramResource) {
828 if (this.diagramResource != diagramResource) {
829 this.diagramResource = diagramResource;
834 private void updateListening() {
835 if (visualisationsListener != null)
836 visualisationsListener.dispose();
837 visualisationsListener = new VisualisationsListener(this);
838 Simantics.getSession().asyncRequest(new DynamicVisualisationsRequest(diagramResource), visualisationsListener);
840 if (listener != null)
842 listener = new VisualisationListener(this);
843 Simantics.getSession().asyncRequest(new ActiveDynamicVisualisationsRequest(diagramResource), listener);
846 private static class VisualisationsListener implements Listener<Collection<NamedResource>> {
848 private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationsListener.class);
850 private boolean disposed;
851 private DynamicVisualisationsUI ui;
853 public VisualisationsListener(DynamicVisualisationsUI ui) {
858 public void execute(Collection<NamedResource> result) {
859 ui.updateVisualisations(result);
863 public void exception(Throwable t) {
864 LOGGER.error("Could not listen visualisation", t);
868 public boolean isDisposed() {
869 return disposed || ui.isDisposed();
872 public void dispose() {
873 this.disposed = true;
877 private static class VisualisationListener implements Listener<DynamicVisualisation> {
879 private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationListener.class);
881 private boolean disposed;
882 private DynamicVisualisationsUI ui;
884 public VisualisationListener(DynamicVisualisationsUI ui) {
889 public void execute(DynamicVisualisation result) {
890 ui.updateVisualisation(result);
894 public void exception(Throwable t) {
895 LOGGER.error("Could not listen visualisation", t);
899 public boolean isDisposed() {
900 return disposed || ui.isDisposed();
903 public void dispose() {
904 this.disposed = true;
908 public void updateVisualisation(DynamicVisualisation result) {
909 this.visualisation = result;
910 Display.getDefault().asyncExec(() -> {
911 if (getParent().isDisposed())
914 applyButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null);
915 removeVisualisationTemplateButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null);
917 if (visualisation != null) {
918 String[] items = templateSelectionCombo.getItems();
919 for (int i = 0; i < items.length; i++) {
920 if (visualisation.getName().equals(items[i])) {
921 templateSelectionCombo.select(i);
926 Map<String, DynamicColorContribution> colorContributions = visualisation.getColorContributions();
927 for (Entry<String, DynamicColorContribution> entry : colorContributions.entrySet()) {
929 ColoringObjectRow coloringObjectRow = coloringRows.get(entry.getKey());
930 if (coloringObjectRow != null) {
932 coloringObjectRow.update(entry.getValue());
935 LOGGER.info("No coloring object visualisation row for key {}", entry.getKey());
938 ColorBarOptions colorOptions = visualisation.getColorBarOptions();
939 showColorButton.setSelection(colorOptions.isShowColorBars());
940 colorTicksButton.setSelection(colorOptions.isShowColorBarsTicks());
941 for (int i = 0; i < colorLocationCombo.getItems().length; i++) {
942 String item = colorLocationCombo.getItem(i);
943 if (item.equals(colorOptions.getLocation().toString())) {
944 colorLocationCombo.select(i);
948 for (int i = 0; i < colorSizeCombo.getItems().length; i++) {
949 String item = colorSizeCombo.getItem(i);
950 if (item.equals(colorOptions.getSize().toString())) {
951 colorSizeCombo.select(i);
956 Map<String, DynamicSizeContribution> sizeContributions = visualisation.getSizeContributions();
957 for (Entry<String, DynamicSizeContribution> entry : sizeContributions.entrySet()) {
959 SizingObjectRow sizingObjectRow = sizingRows.get(entry.getKey());
960 if (sizingObjectRow != null) {
962 sizingObjectRow.update(entry.getValue());
965 LOGGER.info("No sizing object visualisation row for key {}", entry.getKey());
968 SizeBarOptions sizeOptions = visualisation.getSizeBarOptions();
969 showSizeButton.setSelection(sizeOptions.isShowSizeBars());
970 sizeTicksButton.setSelection(sizeOptions.isShowSizeBarsTicks());
971 for (int i = 0; i < sizeLocationCombo.getItems().length; i++) {
972 String item = sizeLocationCombo.getItem(i);
973 if (item.equals(sizeOptions.getLocation().toString())) {
974 sizeLocationCombo.select(i);
978 for (int i = 0; i < sizeSizeCombo.getItems().length; i++) {
979 String item = sizeSizeCombo.getItem(i);
980 if (item.equals(sizeOptions.getSize().toString())) {
981 sizeSizeCombo.select(i);
989 public void updateVisualisations(Collection<NamedResource> result) {
990 this.visualisations = result;
992 Display.getDefault().asyncExec(() -> {
993 if (getParent().isDisposed())
995 templateSelectionCombo.setItems(visualisations.stream().map(NamedResource::getName).collect(Collectors.toList()).toArray(new String[visualisations.size()]));
997 if (visualisation != null) {
998 String[] items = templateSelectionCombo.getItems();
999 for (int i = 0; i < items.length; i++) {
1000 if (visualisation.getName().equals(items[i])) {
1001 templateSelectionCombo.select(i);