]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
c5b1851648a7b6a122fc17fc81b9616ec9476176
[simantics/sysdyn.git] /
1 /*******************************************************************************\r
2  * Copyright (c) 2010, 2011, 2014 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\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
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.sysdyn.ui.properties;\r
13 \r
14 import java.awt.Color;\r
15 import java.awt.Font;\r
16 \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
63 \r
64 /**\r
65  * Information tab for additional information of variables. \r
66  * @author Teemu Lempinen\r
67  * @author Tuomas Miettinen\r
68  *\r
69  */\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
76 \r
77     @Override\r
78     public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
79         this.support = support;\r
80         support.register(this);\r
81         \r
82         // Create a ResourceManager to dispose images when the widget is disposed.\r
83         this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), body);\r
84         \r
85         super.createControls(body, site, context, support);\r
86     }\r
87 \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
98         private Button b;\r
99 \r
100     @Override\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
105         try {\r
106             isValve = context.getSession().syncRequest(new Read<Boolean>() {\r
107 \r
108                 @Override\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
112                 }\r
113 \r
114             });\r
115         } catch (DatabaseException e) {\r
116             e.printStackTrace();\r
117         }\r
118         // if it is a valve, display the orientation information\r
119         if(isValve) {\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
125         }\r
126 \r
127         // Read font and color information for sample text\r
128         if(fontAndColorRead == null) {\r
129             fontAndColorRead = new Read<Pair<Font, Color>>() {\r
130 \r
131                 @Override\r
132                 public Pair<Font, Color> perform(ReadGraph graph) throws DatabaseException {\r
133                     Font font = null;\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
145                         }\r
146                     }\r
147                     return new Pair<Font, Color>(font, color);\r
148                 }\r
149             };\r
150 \r
151             SimanticsUI.getSession().asyncRequest(fontAndColorRead, new Listener<Pair<Font, Color>>() {\r
152 \r
153                 @Override\r
154                 public void execute(final Pair<Font, Color> result) {\r
155                     final Display device;\r
156                     try {\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
161                         return;\r
162                     }\r
163                     \r
164                     device.asyncExec(new Runnable() {\r
165                         \r
166                         @Override\r
167                         public void run() {\r
168                             try {\r
169                                 if(sample.getWidget().isDisposed())\r
170                                     return;\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
174                                 return;\r
175                             }\r
176                             if(result.first != null) {\r
177                                 FontData fd = toSwtFontData(result.first);\r
178                                 sample.setFont(resourceManager.createFont(FontDescriptor.createFrom(fd)));\r
179                             }\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
184                             }\r
185                             try {\r
186                                 sample.getWidget().getParent().getParent().layout();\r
187                             } catch (SWTException e) {\r
188 \r
189                             }\r
190                         }\r
191                     });\r
192 \r
193                 }\r
194 \r
195                 @Override\r
196                 public void exception(Throwable t) {\r
197                     t.printStackTrace();\r
198                 }\r
199 \r
200                 @Override\r
201                 public boolean isDisposed() {\r
202                     return sample == null || sample.getWidget().isDisposed();\r
203                 }\r
204 \r
205             });\r
206         }\r
207     }\r
208 \r
209     /**\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
213      */\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
219         return fontData;\r
220     }\r
221 \r
222         @Override\r
223         protected void createAndAddControls(Composite body, IWorkbenchSite site,\r
224                         ISessionContext context, WidgetSupport _support) {\r
225 \r
226         composite = new Composite(body, SWT.NONE);\r
227 \r
228         informationGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);\r
229         informationGroup.setText("Information");\r
230 \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
235 \r
236         // Orientation information for valves\r
237         orientationComposite = new Composite(composite, SWT.NONE);\r
238 \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
242 \r
243         label = new Label(rangeGroup, SWT.NONE);\r
244         label.setText("Start");\r
245 \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
250 \r
251         label = new Label(rangeGroup, SWT.NONE);\r
252         label.setText("End");\r
253 \r
254 \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
259 \r
260         label = new Label(rangeGroup, SWT.NONE);\r
261         label.setText("Step");\r
262 \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
267 \r
268         \r
269         // Font options. FIXME: very bad appearance right now\r
270         \r
271         fontComposite = new Composite(composite, SWT.NONE);\r
272         b = new Button(fontComposite, support, SWT.PUSH);\r
273         b.setText("Choose Font");\r
274 \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
278 \r
279         b.addSelectionListener(new SelectionListenerImpl<Resource>(context) {\r
280 \r
281             Font f;\r
282             Color color;\r
283             Object input;\r
284 \r
285             @Override\r
286             public void beforeApply() {\r
287 \r
288                 Triple<Font, Color, String> result = null;\r
289 \r
290                 try {\r
291                     result = SimanticsUI.getSession().syncRequest(new Read<Triple<Font, Color, String>>(){\r
292 \r
293                         @Override\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
297 \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
303 \r
304                                 Font font = null;\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
310 \r
311                                 return new Triple<Font, Color, String>(font, color, name);\r
312                             }\r
313 \r
314                             return null;\r
315                         }\r
316 \r
317                     });\r
318                 } catch (DatabaseException e) {\r
319                 }\r
320 \r
321 \r
322                 CustomFontDialog dialog = new CustomFontDialog(composite.getShell(), (result != null ? result.third : null));\r
323 \r
324                 if(result != null) {\r
325                     if(result.first != null) {\r
326                         dialog.setAWTFont(result.first);\r
327                         f = result.first;\r
328                     }\r
329                     if(result.second != null) {\r
330                         dialog.setColor(result.second);\r
331                         color = result.second;\r
332                     }\r
333                 }\r
334 \r
335                 dialog.open();\r
336                 if(dialog.getAWTFont() != null)\r
337                     f = dialog.getAWTFont();\r
338                 if(dialog.getAWTColor() != null) {\r
339                     color = dialog.getAWTColor();\r
340                 }\r
341 \r
342                 FontData fd = dialog.getSWTFontData();\r
343                 if(fd != null)\r
344                     sample.setFont(resourceManager.createFont(FontDescriptor.createFrom(fd)));\r
345                 RGB rgb = dialog.getRGB(); \r
346                 if(rgb != null)\r
347                     sample.setForeground(resourceManager.createColor(rgb));\r
348                 fontComposite.layout();\r
349             }\r
350 \r
351             @Override\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
357                     if(f != null)\r
358                         graph.claim(element, g2d.HasFont, G2DUtils.createFont(graph, f));\r
359                     graph.deny(element, g2d.HasColor);\r
360                     if(color != null)\r
361                         graph.claim(element,  g2d.HasColor, G2DUtils.createColor(graph, color));\r
362                 }\r
363             }\r
364 \r
365             @Override\r
366             public void setInput(ISessionContext context, Object parameter) {\r
367                 super.setInput(context, parameter);\r
368                 input = parameter;\r
369             }\r
370 \r
371         });\r
372         }\r
373 \r
374         @Override\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
378 \r
379         GridDataFactory.fillDefaults().grab(true, true).applyTo(informationGroup);\r
380         GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(informationGroup);\r
381 \r
382         // Textual format documentation\r
383         GridDataFactory.fillDefaults().grab(true, true).applyTo(information.getWidget());\r
384 \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
388 \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
392 \r
393         GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStart.getWidget());\r
394 \r
395         GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeEnd.getWidget());\r
396 \r
397         GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStep.getWidget());\r
398 \r
399         GridDataFactory.fillDefaults().applyTo(fontComposite);\r
400         GridLayoutFactory.fillDefaults().numColumns(1).applyTo(fontComposite);\r
401         }\r
402 \r
403         @Override\r
404         protected void createControlLayoutHorizontal(boolean wideScreen) {\r
405 \r
406         GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
407         GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite);\r
408 \r
409         GridDataFactory.fillDefaults().grab(true, true).applyTo(informationGroup);\r
410         GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(informationGroup);\r
411 \r
412         // Textual format documentation\r
413         GridDataFactory.fillDefaults().grab(true, true).applyTo(information.getWidget());\r
414 \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
418 \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
422 \r
423         GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStart.getWidget());\r
424 \r
425         GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeEnd.getWidget());\r
426 \r
427         GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStep.getWidget());\r
428 \r
429         GridDataFactory.fillDefaults().applyTo(fontComposite);\r
430         GridLayoutFactory.fillDefaults().numColumns(2).applyTo(fontComposite);\r
431         }\r
432 \r
433 }\r