1 /*******************************************************************************
\r
2 * Copyright (c) 2010, 2011 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.layer0.Layer0;
\r
49 import org.simantics.modeling.ModelingResources;
\r
50 import org.simantics.sysdyn.SysdynResource;
\r
51 import org.simantics.sysdyn.ui.properties.widgets.CustomFontDialog;
\r
52 import org.simantics.sysdyn.ui.properties.widgets.ValveOrientationGroup;
\r
53 import org.simantics.sysdyn.ui.properties.widgets.ValveTextLocationGroup;
\r
54 import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;
\r
55 import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier;
\r
56 import org.simantics.ui.SimanticsUI;
\r
57 import org.simantics.utils.datastructures.Pair;
\r
58 import org.simantics.utils.datastructures.Triple;
\r
59 import org.simantics.utils.ui.AdaptionUtils;
\r
60 import org.simantics.utils.ui.ISelectionUtils;
\r
61 import org.simantics.utils.ui.validators.DoubleValidator;
\r
64 * Information tab for additional information of variables.
\r
65 * @author Teemu Lempinen
\r
68 public class VariableInformationTab extends LabelPropertyTabContributor implements Widget {
\r
69 private Composite orientationComposite;
\r
70 private WidgetSupport support;
\r
71 private Resource component;
\r
72 private org.simantics.browsing.ui.swt.widgets.Label sample;
\r
73 private LocalResourceManager resourceManager;
\r
77 public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {
\r
78 this.support = support;
\r
79 support.register(this);
\r
81 // Create a ResourceManager to dispose images when the widget is disposed.
\r
82 this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), body);
\r
85 final Composite composite = new Composite(body, SWT.NONE);
\r
86 GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);
\r
87 GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite);
\r
89 Group informationGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);
\r
90 informationGroup.setText("Information");
\r
91 GridDataFactory.fillDefaults().grab(false, true).applyTo(informationGroup);
\r
92 GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(informationGroup);
\r
94 // Textual format documentation
\r
95 TrackedText information = new TrackedText(informationGroup, support, SWT.MULTI | SWT.BORDER);
\r
96 information.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasDescription));
\r
97 information.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasDescription));
\r
98 GridDataFactory.fillDefaults().grab(true, true).applyTo(information.getWidget());
\r
100 // Orientation information for valves
\r
101 orientationComposite = new Composite(composite, SWT.NONE);
\r
102 GridDataFactory.fillDefaults().span(1, 2).applyTo(orientationComposite);
\r
103 GridLayoutFactory.fillDefaults().margins(3,3).applyTo(orientationComposite);
\r
105 // 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
106 Group rangeGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);
\r
107 rangeGroup.setText("Range");
\r
108 GridDataFactory.fillDefaults().applyTo(rangeGroup);
\r
109 GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(6).applyTo(rangeGroup);
\r
111 Label label = new Label(rangeGroup, SWT.NONE);
\r
112 label.setText("Start");
\r
114 TrackedText rangeStart = new TrackedText(rangeGroup, support, SWT.RIGHT | SWT.BORDER);
\r
115 rangeStart.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasRangeStart));
\r
116 rangeStart.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasRangeStart));
\r
117 rangeStart.setInputValidator(new DoubleValidator());
\r
118 GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStart.getWidget());
\r
121 label = new Label(rangeGroup, SWT.NONE);
\r
122 label.setText("End");
\r
125 TrackedText rangeEnd = new TrackedText(rangeGroup, support, SWT.RIGHT | SWT.BORDER);
\r
126 rangeEnd.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasRangeEnd));
\r
127 rangeEnd.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasRangeEnd));
\r
128 rangeEnd.setInputValidator(new DoubleValidator());
\r
129 GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeEnd.getWidget());
\r
131 label = new Label(rangeGroup, SWT.NONE);
\r
132 label.setText("Step");
\r
134 TrackedText rangeStep = new TrackedText(rangeGroup, support, SWT.RIGHT | SWT.BORDER);
\r
135 rangeStep.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasRangeStep));
\r
136 rangeStep.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasRangeStep));
\r
137 rangeStep.setInputValidator(new DoubleValidator());
\r
138 GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStep.getWidget());
\r
141 // Font options. FIXME: very bad appearance right now
\r
143 final Composite fontComposite = new Composite(composite, SWT.NONE);
\r
144 GridDataFactory.fillDefaults().applyTo(fontComposite);
\r
145 GridLayoutFactory.fillDefaults().numColumns(2).applyTo(fontComposite);
\r
146 Button b = new Button(fontComposite, support, SWT.PUSH);
\r
147 b.setText("Choose Font");
\r
149 // Sample text with selected font
\r
150 sample = new org.simantics.browsing.ui.swt.widgets.Label(fontComposite, support, SWT.NONE);
\r
151 sample.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName, "Sample"));
\r
153 b.addSelectionListener(new SelectionListenerImpl<Resource>(context) {
\r
160 public void beforeApply() {
\r
162 Triple<Font, Color, String> result = null;
\r
165 result = SimanticsUI.getSession().syncRequest(new Read<Triple<Font, Color, String>>(){
\r
168 public Triple<Font, Color, String> perform(ReadGraph graph) throws DatabaseException {
\r
169 Resource component = ISelectionUtils.filterSingleSelection(input, Resource.class);
\r
170 String name = NameUtils.getSafeName(graph, component);
\r
172 Resource element = graph.getPossibleObject(component, ModelingResources.getInstance(graph).ComponentToElement);
\r
173 if(element != null) {
\r
174 G2DResource g2d = G2DResource.getInstance(graph);
\r
175 Resource fontResource = graph.getPossibleObject(element, g2d.HasFont);
\r
176 Resource colorResource = graph.getPossibleObject(element, g2d.HasColor);
\r
179 if(fontResource != null)
\r
180 font = G2DUtils.getFont(graph, fontResource);
\r
181 Color color = null;
\r
182 if(colorResource != null)
\r
183 color = G2DUtils.getColor(graph, colorResource);
\r
185 return new Triple<Font, Color, String>(font, color, name);
\r
192 } catch (DatabaseException e) {
\r
196 CustomFontDialog dialog = new CustomFontDialog(composite.getShell(), (result != null ? result.third : null));
\r
198 if(result != null) {
\r
199 if(result.first != null) {
\r
200 dialog.setAWTFont(result.first);
\r
203 if(result.second != null) {
\r
204 dialog.setColor(result.second);
\r
205 color = result.second;
\r
210 if(dialog.getAWTFont() != null)
\r
211 f = dialog.getAWTFont();
\r
212 if(dialog.getAWTColor() != null) {
\r
213 color = dialog.getAWTColor();
\r
216 FontData fd = dialog.getSWTFontData();
\r
218 sample.setFont(resourceManager.createFont(FontDescriptor.createFrom(fd)));
\r
219 RGB rgb = dialog.getRGB();
\r
221 sample.setForeground(resourceManager.createColor(rgb));
\r
222 fontComposite.layout();
\r
226 public void apply(WriteGraph graph, Resource input) throws DatabaseException {
\r
227 Resource element = graph.getPossibleObject(input, ModelingResources.getInstance(graph).ComponentToElement);
\r
228 if(element != null) {
\r
229 G2DResource g2d = G2DResource.getInstance(graph);
\r
230 graph.deny(element, g2d.HasFont);
\r
232 graph.claim(element, g2d.HasFont, G2DUtils.createFont(graph, f));
\r
233 graph.deny(element, g2d.HasColor);
\r
235 graph.claim(element, g2d.HasColor, G2DUtils.createColor(graph, color));
\r
240 public void setInput(ISessionContext context, Object parameter) {
\r
241 super.setInput(context, parameter);
\r
251 private Read<Pair<Font, Color>> fontAndColorRead;
\r
254 public void setInput(ISessionContext context, Object input) {
\r
255 component = AdaptionUtils.adaptToSingle(input, Resource.class);
\r
256 // is the displayed variable a valve?
\r
257 Boolean isValve = false;
\r
259 isValve = context.getSession().syncRequest(new Read<Boolean>() {
\r
262 public Boolean perform(ReadGraph graph) throws DatabaseException {
\r
263 SysdynResource sr = SysdynResource.getInstance(graph);
\r
264 return graph.isInstanceOf(component, sr.Valve);
\r
268 } catch (DatabaseException e) {
\r
269 e.printStackTrace();
\r
271 // if it is a valve, display the orientation information
\r
273 ValveOrientationGroup vog = new ValveOrientationGroup(orientationComposite, context, support, SWT.NONE);
\r
274 vog.setInput(context, input);
\r
275 ValveTextLocationGroup vtlg = new ValveTextLocationGroup(orientationComposite, context, support, SWT.NONE);
\r
276 vtlg.setInput(context, input);
\r
277 orientationComposite.getParent().layout();
\r
280 // Read font and color information for sample text
\r
281 if(fontAndColorRead == null) {
\r
282 fontAndColorRead = new Read<Pair<Font, Color>>() {
\r
285 public Pair<Font, Color> perform(ReadGraph graph) throws DatabaseException {
\r
287 Color color = null;
\r
288 if(component != null) {
\r
289 Resource element = graph.getPossibleObject(component, ModelingResources.getInstance(graph).ComponentToElement);
\r
290 if(element != null) {
\r
291 G2DResource g2d = G2DResource.getInstance(graph);
\r
292 Resource fontResource = graph.getPossibleObject(element, g2d.HasFont);
\r
293 if(fontResource != null)
\r
294 font = G2DUtils.getFont(graph, fontResource);
\r
295 Resource colorResource = graph.getPossibleObject(element, g2d.HasColor);
\r
296 if(colorResource != null)
\r
297 color = G2DUtils.getColor(graph, colorResource);
\r
300 return new Pair<Font, Color>(font, color);
\r
304 SimanticsUI.getSession().asyncRequest(fontAndColorRead, new Listener<Pair<Font, Color>>() {
\r
307 public void execute(final Pair<Font, Color> result) {
\r
308 final Display device;
\r
310 device = sample.getWidget().getDisplay();
\r
311 } catch (SWTException e) {
\r
312 // Widget is disposed, the GUI probably did'n function as fast as the user commanded.
\r
313 // Thus do nothing.
\r
317 device.asyncExec(new Runnable() {
\r
320 public void run() {
\r
322 if(sample.getWidget().isDisposed())
\r
324 } catch (SWTException e) {
\r
325 // Widget is disposed, the GUI probably did'n function as fast as the user commanded.
\r
326 // Thus do nothing.
\r
329 if(result.first != null) {
\r
330 FontData fd = toSwtFontData(result.first);
\r
331 sample.setFont(resourceManager.createFont(FontDescriptor.createFrom(fd)));
\r
333 if(result.second != null) {
\r
334 RGB rgb = new RGB(result.second.getRed(), result.second.getGreen(),
\r
335 result.second.getBlue());
\r
336 sample.setForeground(resourceManager.createColor(rgb));
\r
339 sample.getWidget().getParent().getParent().layout();
\r
340 } catch (SWTException e) {
\r
349 public void exception(Throwable t) {
\r
350 t.printStackTrace();
\r
354 public boolean isDisposed() {
\r
355 return sample == null || sample.getWidget().isDisposed();
\r
363 * Create SWT FontData based on AWT Font
\r
364 * @param font AWT Font
\r
365 * @return SWT FontData based on AWT Font
\r
367 private static FontData toSwtFontData(Font font) {
\r
368 FontData fontData = new FontData();
\r
369 fontData.setName(font.getFamily());
\r
370 fontData.setStyle(font.getStyle());
\r
371 fontData.setHeight(font.getSize());
\r