]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/SliderClassFactory.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / diagram / SliderClassFactory.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in 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.modeling.ui.diagram;\r
13 \r
14 import java.awt.geom.AffineTransform;\r
15 import java.awt.geom.Rectangle2D;\r
16 \r
17 import org.simantics.databoard.Bindings;\r
18 import org.simantics.db.AsyncReadGraph;\r
19 import org.simantics.db.ReadGraph;\r
20 import org.simantics.db.Resource;\r
21 import org.simantics.db.Session;\r
22 import org.simantics.db.WriteGraph;\r
23 import org.simantics.db.common.primitiverequest.ValueImplied;\r
24 import org.simantics.db.common.request.WriteRequest;\r
25 import org.simantics.db.exception.DatabaseException;\r
26 import org.simantics.db.exception.NoSingleResultException;\r
27 import org.simantics.db.exception.ResourceNotFoundException;\r
28 import org.simantics.db.layer0.adapter.StringModifier;\r
29 import org.simantics.db.layer0.request.PossibleActiveValuation;\r
30 import org.simantics.db.layer0.request.PossibleSessionValuation;\r
31 import org.simantics.db.procedure.AsyncProcedure;\r
32 import org.simantics.db.procedure.Listener;\r
33 import org.simantics.diagram.G2DUtils;\r
34 import org.simantics.diagram.adapter.SyncElementFactory;\r
35 import org.simantics.diagram.elements.MonitorClass;\r
36 import org.simantics.diagram.stubs.DiagramResource;\r
37 import org.simantics.diagram.stubs.G2DResource;\r
38 import org.simantics.diagram.synchronization.CompositeHintSynchronizer;\r
39 import org.simantics.diagram.synchronization.IHintSynchronizer;\r
40 import org.simantics.diagram.synchronization.SynchronizationHints;\r
41 import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
42 import org.simantics.diagram.synchronization.graph.ElementLoader;\r
43 import org.simantics.diagram.synchronization.graph.MonitorSynchronizer;\r
44 import org.simantics.diagram.synchronization.graph.TransformSynchronizer;\r
45 import org.simantics.diagram.ui.DiagramModelHints;\r
46 import org.simantics.g2d.canvas.ICanvasContext;\r
47 import org.simantics.g2d.diagram.IDiagram;\r
48 import org.simantics.g2d.diagram.handler.DataElementMap;\r
49 import org.simantics.g2d.diagram.handler.Relationship;\r
50 import org.simantics.g2d.diagram.handler.RelationshipHandler;\r
51 import org.simantics.g2d.element.ElementClass;\r
52 import org.simantics.g2d.element.ElementHints;\r
53 import org.simantics.g2d.element.ElementUtils;\r
54 import org.simantics.g2d.element.IElement;\r
55 import org.simantics.g2d.element.handler.TextEditor;\r
56 import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
57 import org.simantics.layer0.Layer0;\r
58 import org.simantics.modeling.ModelingResources;\r
59 import org.simantics.modeling.ui.diagram.SliderClass.Range;\r
60 import org.simantics.utils.strings.format.MetricsFormat;\r
61 import org.simantics.utils.strings.format.MetricsFormatList;\r
62 import org.simantics.utils.threads.ThreadUtils;\r
63 \r
64 public class SliderClassFactory extends SyncElementFactory {\r
65 \r
66     private static final IHintSynchronizer HINT_SYNCHRONIZER = new CompositeHintSynchronizer(MonitorSynchronizer.INSTANCE, TransformSynchronizer.INSTANCE);\r
67 \r
68     public static ElementClass createSliderClass(Resource elementClass) {\r
69         // set "default scale" to no scaling, 1.0, 1.0\r
70         return SliderClass.create(null, null, null, null, null, 1.0, 1.0, new StaticObjectAdapter(elementClass));\r
71     }\r
72 \r
73     // staticScale{X,Y} define the scale of the static monitor image\r
74     public static ElementClass createSliderClass(Resource elementClass, IElement parentElement, Range<Double> range, Double value, Object component, String suffix, double staticScaleX, double staticScaleY) {\r
75         return SliderClass.create(parentElement, range, value, component, suffix, staticScaleX, staticScaleY, new StaticObjectAdapter(elementClass));\r
76     }\r
77 \r
78     @Override\r
79     public void load(ReadGraph g, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e) throws DatabaseException {\r
80 \r
81         if(!g.hasStatement(element)) return;\r
82 \r
83         Layer0 l0 = Layer0.getInstance(g);\r
84         final G2DResource g2d = G2DResource.getInstance(g);\r
85         final DiagramResource dr = DiagramResource.getInstance(g);\r
86 \r
87         ElementClass ec = e.getElementClass();\r
88 \r
89         // Must be done here to allow for the relationship manager to work properly.\r
90         e.setHint(ElementHints.KEY_OBJECT, element);\r
91         e.setHint(SynchronizationHints.HINT_SYNCHRONIZER, HINT_SYNCHRONIZER);\r
92         //System.out.println("    ElementClass:" + ec);\r
93         //System.out.println("    Element:" + e);\r
94 \r
95         AffineTransform at = DiagramGraphUtil.getAffineTransform(g, element);\r
96         ElementUtils.setTransform(e, at);\r
97 \r
98         // Load alignments\r
99         MetricsFormat tmpf = null;\r
100         try {\r
101             tmpf = G2DUtils.getMetricsFormat(g, g.getSingleObject(element, dr.HasFormat));\r
102         } catch(NoSingleResultException ex) {\r
103             tmpf = MetricsFormatList.METRICS_GENERIC;\r
104         }\r
105         final MetricsFormat format = tmpf;\r
106         e.setHint(SliderClass.KEY_NUMBER_FORMAT, format);\r
107 \r
108         double bounds[] = DiagramGraphUtil.getPossibleRelatedDoubleArray(g, element, g2d.HasBounds);\r
109         if (bounds!=null) {\r
110             e.setHint(ElementHints.KEY_BOUNDS, new Rectangle2D.Double(bounds[0], bounds[1], bounds[2], bounds[3]));\r
111         }\r
112 \r
113         String label = g.getPossibleRelatedValue(element, l0.HasLabel);\r
114         ElementUtils.setText(e, label);\r
115 \r
116         try {\r
117             final Resource componentToElement = ModelingResources.getInstance(g).ComponentToElement;\r
118             final Resource sliderComponent = g.getPossibleObject(element, dr.HasSliderComponent);\r
119             final String sliderSuffix = g.getPossibleRelatedValue(element, dr.HasSliderSuffix, Bindings.STRING);\r
120             // FIXME: use range instead\r
121             final Double min = g.getPossibleRelatedValue(element, dr.HasSliderMinValue, Bindings.DOUBLE);\r
122             final Double max = g.getPossibleRelatedValue(element, dr.HasSliderMaxValue, Bindings.DOUBLE);\r
123 \r
124             e.setHint(SliderClass.KEY_SLIDER_COMPONENT, sliderComponent);\r
125             e.setHint(SliderClass.KEY_SLIDER_SUFFIX, sliderSuffix);\r
126             e.setHint(SliderClass.KEY_SLIDER_RANGE, new SliderClass.Range<Double>(min, max));\r
127             e.setHint(SliderClass.KEY_SLIDER_VALUE, new Double(0));\r
128 \r
129             final Resource parentDiagramElement = g.getPossibleObject(sliderComponent, componentToElement);\r
130 \r
131             // Load parent relationship now, or it unsuccessful, after all elements have been loaded.\r
132             if (parentDiagramElement != null) {\r
133                 if (!loadRelationships(g, diagram, e, parentDiagramElement)) {\r
134                     e.setHint(DiagramModelHints.KEY_ELEMENT_LOADER, new ElementLoader() {\r
135                         @Override\r
136                         public void load(ReadGraph g, IDiagram diagram, IElement element) {\r
137                             loadRelationships(g, diagram, element, parentDiagramElement);\r
138                         }\r
139                     });\r
140                 }\r
141             }\r
142 \r
143             // create tooltip\r
144             if (sliderSuffix != null) {\r
145                 e.setHint(SliderClass.KEY_TOOLTIP_TEXT, sliderSuffix);\r
146             }\r
147 \r
148             final Session session = g.getSession();\r
149 \r
150             String sessionId = diagram.getHint(DiagramModelHints.KEY_SESSION_ID);\r
151             Resource valuation =\r
152                 sessionId != null ?\r
153                         g.syncRequest(new PossibleSessionValuation(sliderComponent, sessionId, sliderSuffix)) :\r
154                             g.syncRequest(new PossibleActiveValuation(sliderComponent, sliderSuffix));\r
155 \r
156                         if(valuation == null) {\r
157                             return;\r
158                         }\r
159 \r
160                         session.asyncRequest(new ValueImplied<Object>(valuation), new Listener<Object>() {\r
161 \r
162                             @Override\r
163                             public void execute(final Object result) {\r
164                                 final IElement el = ElementUtils.getByData(diagram, element);\r
165                                 if(el != null) {\r
166                                     ThreadUtils.asyncExec(canvas.getThreadAccess(), new Runnable() {\r
167                                         @Override\r
168                                         public void run() {\r
169                                             el.setHint(SliderClass.KEY_SLIDER_VALUE, result);\r
170                                             SliderClass.update(el);\r
171                                         }\r
172                                     });\r
173                                 }\r
174                             }\r
175 \r
176                             @Override\r
177                             public void exception(Throwable t) {\r
178                             }\r
179 \r
180                             @Override\r
181                             public boolean isDisposed() {\r
182                                 return canvas.isDisposed();\r
183                             }\r
184 \r
185                         });\r
186 \r
187                         final StringModifier modifier = g.adapt(valuation, StringModifier.class);\r
188                         TextEditor ed = ec.getAtMostOneItemOfClass(TextEditor.class);\r
189                         ed.setModifier(e, new TextEditor.Modifier() {\r
190 \r
191                             @Override\r
192                             public String getValue(IElement element) {\r
193                                 return MonitorClass.editText(element);\r
194                             }\r
195 \r
196                             @Override\r
197                             public String isValid(IElement element, String text) {\r
198                                 // TODO: implement validation properly\r
199                                 return null;\r
200                             }\r
201 \r
202                             @Override\r
203                             public void modify(final IElement element, final String text) {\r
204                                 session.asyncRequest(new WriteRequest() {\r
205                                     @Override\r
206                                     public void perform(WriteGraph graph) throws DatabaseException {\r
207                                         modifier.modify(graph, text);\r
208                                     }\r
209                                 });\r
210                             }\r
211 \r
212                         });\r
213 \r
214         } catch (ResourceNotFoundException e1) {\r
215             e1.printStackTrace();\r
216         }\r
217     }\r
218 \r
219     boolean loadRelationships(ReadGraph g, IDiagram diagram, IElement element, Resource parentElementResource) {\r
220         // If no relationship handler is available, stop loading.\r
221         RelationshipHandler rh = diagram.getDiagramClass().getAtMostOneItemOfClass(RelationshipHandler.class);\r
222         if (rh == null)\r
223             return true;\r
224 \r
225         DataElementMap map = diagram.getDiagramClass().getSingleItem(DataElementMap.class);\r
226         IElement parentElement = map.getElement(diagram, parentElementResource);\r
227         if (parentElement != null) {\r
228             element.setHint(ElementHints.KEY_PARENT_ELEMENT, parentElement);\r
229             rh.claim(diagram, element, Relationship.CHILD_OF, parentElement);\r
230             return true;\r
231         }\r
232 \r
233         return false;\r
234     }\r
235 \r
236     @Override\r
237     public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType,\r
238             AsyncProcedure<ElementClass> procedure) {\r
239         procedure.execute(graph, createSliderClass(elementType));\r
240     }\r
241 \r
242 }\r