1 /*******************************************************************************
\r
2 * Copyright (c) 2010, 2011, 2014 Association for Decentralized Information Management in
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.sysdyn.ui.properties;
\r
14 import java.awt.Color;
\r
15 import java.awt.Font;
\r
17 import org.eclipse.jface.layout.GridDataFactory;
\r
18 import org.eclipse.jface.layout.GridLayoutFactory;
\r
19 import org.eclipse.jface.resource.FontDescriptor;
\r
20 import org.eclipse.jface.resource.JFaceResources;
\r
21 import org.eclipse.jface.resource.LocalResourceManager;
\r
22 import org.eclipse.swt.SWT;
\r
23 import org.eclipse.swt.SWTException;
\r
24 import org.eclipse.swt.graphics.FontData;
\r
25 import org.eclipse.swt.graphics.RGB;
\r
26 import org.eclipse.swt.widgets.Composite;
\r
27 import org.eclipse.swt.widgets.Display;
\r
28 import org.eclipse.swt.widgets.Group;
\r
29 import org.eclipse.swt.widgets.Label;
\r
30 import org.eclipse.ui.IWorkbenchSite;
\r
31 import org.simantics.browsing.ui.swt.widgets.Button;
\r
32 import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;
\r
33 import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier;
\r
34 import org.simantics.browsing.ui.swt.widgets.TrackedText;
\r
35 import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;
\r
36 import org.simantics.browsing.ui.swt.widgets.impl.Widget;
\r
37 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;
\r
38 import org.simantics.db.ReadGraph;
\r
39 import org.simantics.db.Resource;
\r
40 import org.simantics.db.WriteGraph;
\r
41 import org.simantics.db.common.utils.NameUtils;
\r
42 import org.simantics.db.exception.DatabaseException;
\r
43 import org.simantics.db.management.ISessionContext;
\r
44 import org.simantics.db.procedure.Listener;
\r
45 import org.simantics.db.request.Read;
\r
46 import org.simantics.diagram.G2DUtils;
\r
47 import org.simantics.diagram.stubs.G2DResource;
\r
48 import org.simantics.jfreechart.chart.properties.AdjustableTab;
\r
49 import org.simantics.layer0.Layer0;
\r
50 import org.simantics.modeling.ModelingResources;
\r
51 import org.simantics.sysdyn.SysdynResource;
\r
52 import org.simantics.sysdyn.ui.properties.widgets.CustomFontDialog;
\r
53 import org.simantics.sysdyn.ui.properties.widgets.ValveOrientationGroup;
\r
54 import org.simantics.sysdyn.ui.properties.widgets.ValveTextLocationGroup;
\r
55 import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;
\r
56 import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier;
\r
57 import org.simantics.ui.SimanticsUI;
\r
58 import org.simantics.utils.datastructures.Pair;
\r
59 import org.simantics.utils.datastructures.Triple;
\r
60 import org.simantics.utils.ui.AdaptionUtils;
\r
61 import org.simantics.utils.ui.ISelectionUtils;
\r
62 import org.simantics.utils.ui.validators.DoubleValidator;
\r
65 * Information tab for additional information of variables.
\r
66 * @author Teemu Lempinen
\r
67 * @author Tuomas Miettinen
\r
70 public class VariableInformationTab extends AdjustableTab implements Widget {
\r
71 private Composite orientationComposite;
\r
72 private WidgetSupport support;
\r
73 private Resource component;
\r
74 private org.simantics.browsing.ui.swt.widgets.Label sample;
\r
75 private LocalResourceManager resourceManager;
\r
78 public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {
\r
79 this.support = support;
\r
80 support.register(this);
\r
82 // Create a ResourceManager to dispose images when the widget is disposed.
\r
83 this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), body);
\r
85 super.createControls(body, site, context, support);
\r
88 private Read<Pair<Font, Color>> fontAndColorRead;
\r
89 private Composite composite;
\r
90 private Group informationGroup;
\r
91 private TrackedText information;
\r
92 private Group rangeGroup;
\r
93 private Label label;
\r
94 private TrackedText rangeStart;
\r
95 private TrackedText rangeEnd;
\r
96 private TrackedText rangeStep;
\r
97 private Composite fontComposite;
\r
101 public void setInput(ISessionContext context, Object input) {
\r
102 component = AdaptionUtils.adaptToSingle(input, Resource.class);
\r
103 // is the displayed variable a valve?
\r
104 Boolean isValve = false;
\r
106 isValve = context.getSession().syncRequest(new Read<Boolean>() {
\r
109 public Boolean perform(ReadGraph graph) throws DatabaseException {
\r
110 SysdynResource sr = SysdynResource.getInstance(graph);
\r
111 return graph.isInstanceOf(component, sr.Valve);
\r
115 } catch (DatabaseException e) {
\r
116 e.printStackTrace();
\r
118 // if it is a valve, display the orientation information
\r
120 ValveOrientationGroup vog = new ValveOrientationGroup(orientationComposite, context, support, SWT.NONE);
\r
121 vog.setInput(context, input);
\r
122 ValveTextLocationGroup vtlg = new ValveTextLocationGroup(orientationComposite, context, support, SWT.NONE);
\r
123 vtlg.setInput(context, input);
\r
124 orientationComposite.getParent().layout();
\r
127 // Read font and color information for sample text
\r
128 if(fontAndColorRead == null) {
\r
129 fontAndColorRead = new Read<Pair<Font, Color>>() {
\r
132 public Pair<Font, Color> perform(ReadGraph graph) throws DatabaseException {
\r
134 Color color = null;
\r
135 if(component != null) {
\r
136 Resource element = graph.getPossibleObject(component, ModelingResources.getInstance(graph).ComponentToElement);
\r
137 if(element != null) {
\r
138 G2DResource g2d = G2DResource.getInstance(graph);
\r
139 Resource fontResource = graph.getPossibleObject(element, g2d.HasFont);
\r
140 if(fontResource != null)
\r
141 font = G2DUtils.getFont(graph, fontResource);
\r
142 Resource colorResource = graph.getPossibleObject(element, g2d.HasColor);
\r
143 if(colorResource != null)
\r
144 color = G2DUtils.getColor(graph, colorResource);
\r
147 return new Pair<Font, Color>(font, color);
\r
151 SimanticsUI.getSession().asyncRequest(fontAndColorRead, new Listener<Pair<Font, Color>>() {
\r
154 public void execute(final Pair<Font, Color> result) {
\r
155 final Display device;
\r
157 device = sample.getWidget().getDisplay();
\r
158 } catch (SWTException e) {
\r
159 // Widget is disposed, the GUI probably did'n function as fast as the user commanded.
\r
160 // Thus do nothing.
\r
164 device.asyncExec(new Runnable() {
\r
167 public void run() {
\r
169 if(sample.getWidget().isDisposed())
\r
171 } catch (SWTException e) {
\r
172 // Widget is disposed, the GUI probably did'n function as fast as the user commanded.
\r
173 // Thus do nothing.
\r
176 if(result.first != null) {
\r
177 FontData fd = toSwtFontData(result.first);
\r
178 sample.setFont(resourceManager.createFont(FontDescriptor.createFrom(fd)));
\r
180 if(result.second != null) {
\r
181 RGB rgb = new RGB(result.second.getRed(), result.second.getGreen(),
\r
182 result.second.getBlue());
\r
183 sample.setForeground(resourceManager.createColor(rgb));
\r
186 sample.getWidget().getParent().getParent().layout();
\r
187 } catch (SWTException e) {
\r
196 public void exception(Throwable t) {
\r
197 t.printStackTrace();
\r
201 public boolean isDisposed() {
\r
202 return sample == null || sample.getWidget().isDisposed();
\r
210 * Create SWT FontData based on AWT Font
\r
211 * @param font AWT Font
\r
212 * @return SWT FontData based on AWT Font
\r
214 private static FontData toSwtFontData(Font font) {
\r
215 FontData fontData = new FontData();
\r
216 fontData.setName(font.getFamily());
\r
217 fontData.setStyle(font.getStyle());
\r
218 fontData.setHeight(font.getSize());
\r
223 protected void createAndAddControls(Composite body, IWorkbenchSite site,
\r
224 ISessionContext context, WidgetSupport _support) {
\r
226 composite = new Composite(body, SWT.NONE);
\r
228 informationGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);
\r
229 informationGroup.setText("Information");
\r
231 // Textual format documentation
\r
232 information = new TrackedText(informationGroup, support, SWT.MULTI | SWT.BORDER);
\r
233 information.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasDescription));
\r
234 information.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasDescription));
\r
236 // Orientation information for valves
\r
237 orientationComposite = new Composite(composite, SWT.NONE);
\r
239 // Range of a variable (e.g. from 0 to 10). Does not affect simulation, but the infor can be used for example in charts
\r
240 rangeGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);
\r
241 rangeGroup.setText("Range");
\r
243 label = new Label(rangeGroup, SWT.NONE);
\r
244 label.setText("Start");
\r
246 rangeStart = new TrackedText(rangeGroup, support, SWT.RIGHT | SWT.BORDER);
\r
247 rangeStart.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasRangeStart));
\r
248 rangeStart.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasRangeStart));
\r
249 rangeStart.setInputValidator(new DoubleValidator());
\r
251 label = new Label(rangeGroup, SWT.NONE);
\r
252 label.setText("End");
\r
255 rangeEnd = new TrackedText(rangeGroup, support, SWT.RIGHT | SWT.BORDER);
\r
256 rangeEnd.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasRangeEnd));
\r
257 rangeEnd.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasRangeEnd));
\r
258 rangeEnd.setInputValidator(new DoubleValidator());
\r
260 label = new Label(rangeGroup, SWT.NONE);
\r
261 label.setText("Step");
\r
263 rangeStep = new TrackedText(rangeGroup, support, SWT.RIGHT | SWT.BORDER);
\r
264 rangeStep.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasRangeStep));
\r
265 rangeStep.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasRangeStep));
\r
266 rangeStep.setInputValidator(new DoubleValidator());
\r
269 // Font options. FIXME: very bad appearance right now
\r
271 fontComposite = new Composite(composite, SWT.NONE);
\r
272 b = new Button(fontComposite, support, SWT.PUSH);
\r
273 b.setText("Choose Font");
\r
275 // Sample text with selected font
\r
276 sample = new org.simantics.browsing.ui.swt.widgets.Label(fontComposite, support, SWT.NONE);
\r
277 sample.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName, "Sample"));
\r
279 b.addSelectionListener(new SelectionListenerImpl<Resource>(context) {
\r
286 public void beforeApply() {
\r
288 Triple<Font, Color, String> result = null;
\r
291 result = SimanticsUI.getSession().syncRequest(new Read<Triple<Font, Color, String>>(){
\r
294 public Triple<Font, Color, String> perform(ReadGraph graph) throws DatabaseException {
\r
295 Resource component = ISelectionUtils.filterSingleSelection(input, Resource.class);
\r
296 String name = NameUtils.getSafeName(graph, component);
\r
298 Resource element = graph.getPossibleObject(component, ModelingResources.getInstance(graph).ComponentToElement);
\r
299 if(element != null) {
\r
300 G2DResource g2d = G2DResource.getInstance(graph);
\r
301 Resource fontResource = graph.getPossibleObject(element, g2d.HasFont);
\r
302 Resource colorResource = graph.getPossibleObject(element, g2d.HasColor);
\r
305 if(fontResource != null)
\r
306 font = G2DUtils.getFont(graph, fontResource);
\r
307 Color color = null;
\r
308 if(colorResource != null)
\r
309 color = G2DUtils.getColor(graph, colorResource);
\r
311 return new Triple<Font, Color, String>(font, color, name);
\r
318 } catch (DatabaseException e) {
\r
322 CustomFontDialog dialog = new CustomFontDialog(composite.getShell(), (result != null ? result.third : null));
\r
324 if(result != null) {
\r
325 if(result.first != null) {
\r
326 dialog.setAWTFont(result.first);
\r
329 if(result.second != null) {
\r
330 dialog.setColor(result.second);
\r
331 color = result.second;
\r
336 if(dialog.getAWTFont() != null)
\r
337 f = dialog.getAWTFont();
\r
338 if(dialog.getAWTColor() != null) {
\r
339 color = dialog.getAWTColor();
\r
342 FontData fd = dialog.getSWTFontData();
\r
344 sample.setFont(resourceManager.createFont(FontDescriptor.createFrom(fd)));
\r
345 RGB rgb = dialog.getRGB();
\r
347 sample.setForeground(resourceManager.createColor(rgb));
\r
348 fontComposite.layout();
\r
352 public void apply(WriteGraph graph, Resource input) throws DatabaseException {
\r
353 Resource element = graph.getPossibleObject(input, ModelingResources.getInstance(graph).ComponentToElement);
\r
354 if(element != null) {
\r
355 G2DResource g2d = G2DResource.getInstance(graph);
\r
356 graph.deny(element, g2d.HasFont);
\r
358 graph.claim(element, g2d.HasFont, G2DUtils.createFont(graph, f));
\r
359 graph.deny(element, g2d.HasColor);
\r
361 graph.claim(element, g2d.HasColor, G2DUtils.createColor(graph, color));
\r
366 public void setInput(ISessionContext context, Object parameter) {
\r
367 super.setInput(context, parameter);
\r
375 protected void createControlLayoutVertical() {
\r
376 GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);
\r
377 GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite);
\r
379 GridDataFactory.fillDefaults().grab(true, true).applyTo(informationGroup);
\r
380 GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(informationGroup);
\r
382 // Textual format documentation
\r
383 GridDataFactory.fillDefaults().grab(true, true).applyTo(information.getWidget());
\r
385 // Orientation information for valves
\r
386 GridDataFactory.fillDefaults().span(1, 2).applyTo(orientationComposite);
\r
387 GridLayoutFactory.fillDefaults().margins(3,3).applyTo(orientationComposite);
\r
389 // Range of a variable (e.g. from 0 to 10). Does not affect simulation, but the infor can be used for example in charts
\r
390 GridDataFactory.fillDefaults().applyTo(rangeGroup);
\r
391 GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(rangeGroup);
\r
393 GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStart.getWidget());
\r
395 GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeEnd.getWidget());
\r
397 GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStep.getWidget());
\r
399 GridDataFactory.fillDefaults().applyTo(fontComposite);
\r
400 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(fontComposite);
\r
404 protected void createControlLayoutHorizontal(boolean wideScreen) {
\r
406 GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);
\r
407 GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite);
\r
409 GridDataFactory.fillDefaults().grab(true, true).applyTo(informationGroup);
\r
410 GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(informationGroup);
\r
412 // Textual format documentation
\r
413 GridDataFactory.fillDefaults().grab(true, true).applyTo(information.getWidget());
\r
415 // Orientation information for valves
\r
416 GridDataFactory.fillDefaults().span(1, 2).applyTo(orientationComposite);
\r
417 GridLayoutFactory.fillDefaults().margins(3,3).applyTo(orientationComposite);
\r
419 // Range of a variable (e.g. from 0 to 10). Does not affect simulation, but the infor can be used for example in charts
\r
420 GridDataFactory.fillDefaults().applyTo(rangeGroup);
\r
421 GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(6).applyTo(rangeGroup);
\r
423 GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStart.getWidget());
\r
425 GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeEnd.getWidget());
\r
427 GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStep.getWidget());
\r
429 GridDataFactory.fillDefaults().applyTo(fontComposite);
\r
430 GridLayoutFactory.fillDefaults().numColumns(2).applyTo(fontComposite);
\r