]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.proconf.g3d/src/org/simantics/proconf/g3d/base/ThreeDimensionalEditorBase.java
0a04a229081b9ff81185f9b60d9be4acbd29a05d
[simantics/3d.git] / org.simantics.proconf.g3d / src / org / simantics / proconf / g3d / base / ThreeDimensionalEditorBase.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
3  * All rights reserved. This program and the accompanying materials\r
4  * are made available under the terms of the Eclipse Public License v1.0\r
5  * which accompanies this distribution, and is available at\r
6  * http://www.eclipse.org/legal/epl-v10.html\r
7  *\r
8  * Contributors:\r
9  *     VTT Technical Research Centre of Finland - initial API and implementation\r
10  *******************************************************************************/\r
11 package org.simantics.proconf.g3d.base;\r
12 \r
13 import java.awt.event.MouseEvent;\r
14 import java.util.ArrayList;\r
15 import java.util.HashMap;\r
16 import java.util.List;\r
17 import java.util.Map;\r
18 import java.util.Stack;\r
19 \r
20 import javax.vecmath.Tuple3d;\r
21 import javax.vecmath.Vector3d;\r
22 \r
23 import org.eclipse.jface.action.Action;\r
24 import org.eclipse.jface.action.IContributionItem;\r
25 import org.eclipse.jface.action.IMenuListener;\r
26 import org.eclipse.jface.action.IMenuManager;\r
27 import org.eclipse.jface.action.IToolBarManager;\r
28 import org.eclipse.jface.action.MenuManager;\r
29 import org.eclipse.jface.action.Separator;\r
30 import org.eclipse.jface.dialogs.MessageDialog;\r
31 import org.eclipse.jface.viewers.ISelection;\r
32 import org.eclipse.jface.viewers.ISelectionChangedListener;\r
33 import org.eclipse.jface.viewers.SelectionChangedEvent;\r
34 import org.eclipse.swt.events.PaintEvent;\r
35 import org.eclipse.swt.events.PaintListener;\r
36 import org.eclipse.swt.graphics.Point;\r
37 import org.eclipse.swt.widgets.Composite;\r
38 import org.eclipse.swt.widgets.Menu;\r
39 import org.eclipse.ui.IActionBars;\r
40 import org.eclipse.ui.IEditorActionBarContributor;\r
41 import org.eclipse.ui.ISharedImages;\r
42 import org.eclipse.ui.IWorkbenchActionConstants;\r
43 import org.eclipse.ui.IWorkbenchPart;\r
44 import org.eclipse.ui.PlatformUI;\r
45 import org.eclipse.ui.commands.ICommandService;\r
46 import org.eclipse.ui.internal.WorkbenchWindow;\r
47 import org.simantics.db.Graph;\r
48 import org.simantics.db.GraphRequestAdapter;\r
49 import org.simantics.db.GraphRequestStatus;\r
50 import org.simantics.db.Resource;\r
51 import org.simantics.db.Session;\r
52 import org.simantics.db.events.GraphChangeEvent;\r
53 import org.simantics.db.management.ISessionContext;\r
54 import org.simantics.layer0.utils.EntityFactory;\r
55 import org.simantics.layer0.utils.IEntity;\r
56 import org.simantics.proconf.g3d.Activator;\r
57 import org.simantics.proconf.g3d.actions.CameraAction;\r
58 import org.simantics.proconf.g3d.actions.ContextAction;\r
59 import org.simantics.proconf.g3d.actions.InteractiveAction;\r
60 import org.simantics.proconf.g3d.base.SelectionAdapter.SelectionType;\r
61 import org.simantics.proconf.g3d.common.JmeComposite;\r
62 import org.simantics.proconf.g3d.common.JmeSinglePassRenderingComponent;\r
63 import org.simantics.proconf.g3d.common.OrbitalCamera;\r
64 import org.simantics.proconf.g3d.dialogs.JMEDialog;\r
65 import org.simantics.proconf.g3d.dnd.ShapeDropTarget;\r
66 import org.simantics.proconf.g3d.gizmo.Gizmo;\r
67 import org.simantics.proconf.g3d.input.InputProvider;\r
68 import org.simantics.proconf.g3d.input.SWTInputProvider;\r
69 import org.simantics.proconf.g3d.scenegraph.IGeometryNode;\r
70 import org.simantics.proconf.g3d.scenegraph.IGraphicsNode;\r
71 import org.simantics.proconf.g3d.tools.ScenegraphLockTraverser;\r
72 import org.simantics.utils.ErrorLogger;\r
73 import org.simantics.utils.ui.jface.MenuTools;\r
74 \r
75 import com.jme.math.Ray;\r
76 import com.jme.math.Vector2f;\r
77 import com.jme.math.Vector3f;\r
78 import com.jme.renderer.ColorRGBA;\r
79 \r
80 \r
81 public abstract class ThreeDimensionalEditorBase implements  Runnable {\r
82 \r
83         private Resource inputResource;\r
84         \r
85         private List<EditorContribution> editorContributions = new ArrayList<EditorContribution>();\r
86         \r
87         private EditorContribution currentEditorContribution;\r
88         \r
89     protected List<ContextAction> actions = new ArrayList<ContextAction>();\r
90     \r
91     private List<Action> contributionSelectionActions = new ArrayList<Action>();\r
92       \r
93     protected Composite parent;\r
94     \r
95     protected ISessionContext sessionContext;\r
96     \r
97     protected Session session;\r
98     \r
99     protected ScenegraphAdapter adapter;\r
100     \r
101     protected SelectionAdapter selectionAdapter;\r
102     \r
103     protected Action refreshAction;\r
104     \r
105     protected Action configureJMEAction;\r
106     \r
107     private Action lockScenegraphAction;\r
108 \r
109     protected Menu contextMenu;\r
110 \r
111     private JmeComposite renderingComposite = null;  \r
112 \r
113     protected OrbitalCamera camera = new OrbitalCamera();\r
114 \r
115     protected boolean viewChanged = true;\r
116 \r
117     private InteractiveAction currentAction = null;\r
118     \r
119     private Gizmo currentGizmo = null;\r
120     \r
121     private InteractiveAction cameraAction = null;\r
122     \r
123     private JmeRenderingComponent component = null;\r
124     \r
125     protected InputProvider input = null;\r
126     \r
127     protected ShapeDropTarget dropTarget;\r
128 \r
129 //    protected IEditorActionBarContributor actionBarContributor;\r
130     protected IActionBars actionBars;\r
131     protected IToolBarManager toolBarManager;\r
132     protected IMenuManager menuManager;\r
133     \r
134     public ThreeDimensionalEditorBase(ISessionContext session) {\r
135         this.sessionContext = session;\r
136         this.session = session.getSession();\r
137         component = new JmeSinglePassRenderingComponent();\r
138     }\r
139 \r
140     public ThreeDimensionalEditorBase(ISessionContext session, JmeRenderingComponent component) {\r
141         this.sessionContext = session;\r
142         this.session = session.getSession();\r
143         this.component = component;\r
144     }\r
145     \r
146 //    public void setActionBarContributor(IEditorActionBarContributor contributor) {\r
147 //      actionBarContributor = contributor;\r
148 //    }\r
149     \r
150     public void setActionBars(IActionBars actionBars) {\r
151         this.actionBars = actionBars;\r
152         this.menuManager = actionBars.getMenuManager();\r
153         this.toolBarManager = actionBars.getToolBarManager();\r
154     }\r
155     \r
156    \r
157     \r
158     \r
159     public ISessionContext getSessionContext() {\r
160         return sessionContext;\r
161     }\r
162     \r
163     public Session getSession() {\r
164         return session;\r
165     }\r
166     \r
167     /**\r
168      * Creates basic UI for ThreeDimenionalEditors.\r
169      * Note : inputResource has not been set at this point.\r
170      * \r
171      * @param graph\r
172      * @param parent\r
173      */\r
174     public void createControl(Graph graph, Composite parent) {\r
175         this.parent = parent;\r
176         renderingComposite = new JmeComposite(parent,component);\r
177         // add listeners to force repaint on size changes\r
178         renderingComposite.getCanvas().addPaintListener(new PaintListener() {\r
179                 public void paintControl(PaintEvent e) {\r
180                         viewChanged = true;     \r
181                 }\r
182         });\r
183 \r
184         \r
185         input = new SWTInputProvider();\r
186         \r
187         renderingComposite.initGL();\r
188         camera.setCamera(component.getCamera());\r
189         camera.updateCamera();  \r
190         makeActions(graph);\r
191         hookContextMenu();\r
192 \r
193         // provide selection events for properies view\r
194         this.adapter = createScenegraphAdapter();\r
195         this.selectionAdapter = createSelectionAdapter();\r
196         \r
197         this.selectionAdapter.addSelectionChangedListener(new ISelectionChangedListener() {\r
198                 public void selectionChanged(SelectionChangedEvent event) {\r
199                         setCurrentAction(getDefaultAction());   \r
200                 }\r
201         });\r
202         hookDragAndDrop();      \r
203         hookInput();\r
204         VisualizationScheduler.getInstance().addVisualization(this);\r
205         \r
206         if (editorContributions.size() > 0) {\r
207             //  setActiveEditorContribution(editorContributions.get(0));\r
208            // } else if (editorContributions.size() > 1) {\r
209                 // create actions for selecting contribution\r
210                 for (EditorContribution ec : editorContributions) {\r
211                         final EditorContribution e = ec;\r
212                         Action a = new Action(e.getName(),Action.AS_RADIO_BUTTON) {\r
213                                 @Override\r
214                                 public void run() {\r
215                                         \r
216                                         setActiveEditorContribution(e);\r
217                                 }\r
218                         };\r
219                         contributionSelectionActions.add(a);\r
220                         \r
221                 }\r
222          }\r
223        \r
224     }\r
225     \r
226     public void addEditorContribution(EditorContribution e) {\r
227         if (parent != null)\r
228                 throw new RuntimeException("Editor contributions must be added before editor is created.");\r
229         editorContributions.add(e);\r
230     }\r
231     \r
232     private void initializeEditorContributions(Graph graph) {\r
233          for (EditorContribution e : editorContributions) {\r
234                 e.initialize(graph);\r
235          }\r
236          if (editorContributions.size() > 0)\r
237                  parent.getDisplay().asyncExec(new Runnable() {\r
238                          @Override\r
239                         public void run() {\r
240                                  setActiveEditorContribution(editorContributions.get(0));\r
241                         }\r
242                  });     \r
243     }\r
244     \r
245     \r
246     private void hookInput() {\r
247         renderingComposite.getCanvas().addKeyListener((SWTInputProvider) input);\r
248         renderingComposite.getCanvas().addMouseListener((SWTInputProvider) input);\r
249         renderingComposite.getCanvas().addMouseMoveListener((SWTInputProvider) input);\r
250         renderingComposite.getCanvas().addMouseTrackListener((SWTInputProvider) input);\r
251         renderingComposite.getCanvas().addFocusListener((SWTInputProvider) input);\r
252     }\r
253     \r
254     protected abstract ScenegraphAdapter createScenegraphAdapter();\r
255     protected abstract SelectionAdapter createSelectionAdapter();\r
256 \r
257     \r
258     public JmeComposite getRenderingComposite() {\r
259         return renderingComposite;\r
260    }\r
261     \r
262     public JmeRenderingComponent getRenderingComponent() {\r
263       return component;\r
264     }\r
265 \r
266     public ScenegraphAdapter getScenegraphAdapter() {\r
267         return adapter;\r
268     }\r
269     \r
270     public SelectionAdapter getSelectionAdapter() {\r
271         return selectionAdapter;\r
272     }\r
273 \r
274     public OrbitalCamera getCamera() {\r
275         return camera;\r
276     }\r
277     \r
278     public void setViewChanged(boolean b) {\r
279         viewChanged = b;\r
280     }\r
281 \r
282     protected void hookContextMenu() {\r
283         MenuManager menuMgr = new MenuManager("#PopupMenu");\r
284         menuMgr.setRemoveAllWhenShown(true);\r
285         menuMgr.addMenuListener(new IMenuListener() {\r
286             public void menuAboutToShow(IMenuManager manager) {\r
287                 final IMenuManager m = manager;\r
288                 GraphRequestAdapter r = new GraphRequestAdapter() {\r
289                         @Override\r
290                         public GraphRequestStatus perform(Graph g) throws Exception {\r
291                                 ThreeDimensionalEditorBase.this.fillContextMenu(g,m);\r
292                                 return GraphRequestStatus.transactionComplete();\r
293                         }\r
294                 };\r
295                 \r
296                 session.syncRead(r);\r
297                 \r
298             }\r
299         });\r
300 \r
301         contextMenu = menuMgr.createContextMenu(renderingComposite);\r
302     }\r
303 \r
304     \r
305 \r
306     protected void fillContextMenu(Graph graph,IMenuManager manager) {\r
307         manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));\r
308         \r
309         List<Resource> selected = selectionAdapter.getSelectedResources();\r
310         for (ContextAction action : actions) {\r
311             if(action.usable(graph,selected)) {\r
312                 manager.add(action);\r
313             }\r
314         }\r
315         if (currentEditorContribution != null) {\r
316                 currentEditorContribution.fillContextMenu(graph, manager, selectionAdapter.getCurrentSelection());\r
317                 for (ContextAction action : currentEditorContribution.getActions()) {\r
318                         if(action.usable(graph,selected)) {\r
319                                 manager.add(action);\r
320                 }\r
321             }\r
322         }\r
323 \r
324     }\r
325 \r
326     protected void fillLocalToolBar() {\r
327 \r
328         if (currentEditorContribution != null)\r
329                 currentEditorContribution.fillLocalToolBar(toolBarManager);\r
330     }\r
331     \r
332     protected void fillLocalPullDown() {\r
333         for (Action a : contributionSelectionActions) {\r
334                 IMenuManager menu = MenuTools.getOrCreate(getMenuID(),"View", menuManager);\r
335                 menu.add(a);\r
336         }\r
337         MenuTools.getOrCreate(getMenuID(),"Advanced", menuManager).add(refreshAction);\r
338         if (configureJMEAction != null) {\r
339                 MenuTools.getOrCreate(getMenuID(),"Advanced", menuManager).add(configureJMEAction);\r
340         }\r
341 \r
342         MenuTools.getOrCreate(getMenuID(),"Advanced", menuManager).add(lockScenegraphAction);\r
343         if (currentEditorContribution != null)\r
344                 currentEditorContribution.fillLocalPullDown(menuManager);\r
345     }\r
346     \r
347     public String getMenuID() {\r
348         return Long.toString(getInputResource().getResourceId());\r
349     }\r
350 \r
351     protected void makeActions(Graph graph) {\r
352         \r
353         refreshAction = new Action() {\r
354 \r
355             public void run() {\r
356                 GraphRequestAdapter r = new GraphRequestAdapter() {\r
357                         public GraphRequestStatus perform(Graph g) throws Exception {\r
358 //                               Stack<IGraphicsNode> stack = new Stack<IGraphicsNode>();\r
359 //                         stack.push(adapter.getNode(adapter.getRootResource()));\r
360 //                         while(!stack.isEmpty()) {\r
361 //                             IGraphicsNode node = stack.pop();\r
362 //                             stack.addAll(node.getChildren());\r
363 //                             if (node instanceof IGeometryNode) {\r
364 //                                 ((IGeometryNode)node).updateGeometry(g);\r
365 //                             }\r
366 //                         }\r
367                                  for (IGraphicsNode node : adapter.getNodes())\r
368                                          if (node instanceof IGeometryNode)\r
369                                                  ((IGeometryNode)node).updateGeometry(g);\r
370                          viewChanged = true;\r
371                          return GraphRequestStatus.transactionComplete();\r
372                         };\r
373                 };\r
374                 session.asyncRead(r);\r
375                \r
376             }\r
377         };\r
378         refreshAction.setText("Refresh");\r
379         refreshAction.setToolTipText("Refreshes the visualization");\r
380         refreshAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(\r
381                 ISharedImages.IMG_TOOL_UP));\r
382         if (getRenderingComponent() instanceof JmeSinglePassRenderingComponent) {\r
383                 configureJMEAction = new Action() {\r
384                         public void run() {\r
385                                 JmeSinglePassRenderingComponent c = (JmeSinglePassRenderingComponent)getRenderingComponent();\r
386                                 JMEDialog dialog = new JMEDialog(ThreeDimensionalEditorBase.this.parent.getShell());\r
387                                 c.getDisplaySystem().setCurrent();\r
388                                 dialog.setBounds(c.isShowBounds());\r
389                                 dialog.setNormals(c.isShowNormals());\r
390                                 dialog.setWireframe(c.isShowWireframe());\r
391                                 ColorRGBA col = c.getDisplaySystem().getRenderer().getBackgroundColor();\r
392                                 dialog.setFloatColor(new float[]{col.r,col.g,col.b});\r
393                                 if (dialog.open() == JMEDialog.CANCEL)\r
394                                         return;\r
395                                 c.setShowBounds(dialog.isBounds());\r
396                                 c.setShowNormals(dialog.isNormals());\r
397                                 c.setShowWireframe(dialog.isWireframe());\r
398                                 if (dialog.getFloatColor() != null) {\r
399                                         c.getDisplaySystem().setCurrent();\r
400                                         c.getDisplaySystem().getRenderer().setBackgroundColor(new ColorRGBA(dialog.getFloatColor()[0],dialog.getFloatColor()[1],dialog.getFloatColor()[2],0.f));\r
401                                 }\r
402                         }\r
403                 };\r
404                 configureJMEAction.setText("Configure JME");\r
405                 configureJMEAction.setImageDescriptor(Activator.imageDescriptorFromPlugin("fi.vtt.proconf.ode", "icons/silk/wrench.png"));\r
406         }\r
407         \r
408         lockScenegraphAction = new Action("Lock scenegraph",Action.AS_CHECK_BOX) {\r
409                 public void run() {\r
410                         new ScenegraphLockTraverser(adapter.getRoot(),this.isChecked());\r
411                 }\r
412         };\r
413         \r
414         cameraAction = new CameraAction(this); \r
415         currentAction = cameraAction;\r
416         \r
417         \r
418     }\r
419     \r
420     public InteractiveAction getDefaultAction() {\r
421         return cameraAction;\r
422     }\r
423     \r
424     public void createPickRay(Vector3d o, Vector3d d) {\r
425         Ray r = createPickRay();\r
426         o.x = r.origin.x;\r
427         o.y = r.origin.y;\r
428         o.z = r.origin.z;\r
429         d.x = r.direction.x;\r
430         d.y = r.direction.y;\r
431         d.z = r.direction.z;\r
432         d.normalize();\r
433     }\r
434     \r
435     public Ray createPickRay() {\r
436         Vector2f screenPos = new Vector2f();\r
437                 screenPos.set(input.mouseX(),renderingComposite.getBounds().height - input.mouseY());\r
438                 \r
439                 \r
440                 Ray mouseRay;\r
441                 if (component.getCamera().isParallelProjection()) {\r
442                         Vector3f worldCoords = renderingComposite.getDisplaySystem().getWorldCoordinates(screenPos, 0.0f);\r
443                         mouseRay = new Ray(worldCoords,\r
444                                 component.getCamera().getDirection());\r
445                 } else {\r
446                         Vector3f worldCoords = renderingComposite.getDisplaySystem().getWorldCoordinates(screenPos, 1.0f);\r
447                         mouseRay = new Ray(component.getCamera().getLocation(), worldCoords\r
448                                         .subtractLocal(component.getCamera().getLocation()));\r
449                 }\r
450                 return mouseRay;\r
451     }\r
452     \r
453     public Vector2f getScreenCoord(Tuple3d worldCoord) {\r
454         Vector3f v = renderingComposite.getDisplaySystem().getScreenCoordinates(VecmathJmeTools.get(worldCoord));\r
455         return new Vector2f(v.x,v.y);\r
456     }\r
457     \r
458     \r
459     public InputProvider getInputProvider() {\r
460         return input;\r
461     }\r
462 \r
463     /**\r
464      * Changes current action \r
465      * \r
466      * @param type\r
467      */\r
468     public void setCurrentAction(InteractiveAction action) {\r
469         if (currentAction == action)\r
470                 return;\r
471         if (toolBarManager != null) {\r
472                 toolBarManager.removeAll();\r
473                 fillLocalToolBar();\r
474         }\r
475         if (currentAction != null)\r
476             currentAction.deactivate();\r
477         currentAction = action;\r
478         if (currentAction != null) {\r
479             currentAction.activate();\r
480             if (toolBarManager != null) {\r
481                 currentAction.fillToolBar(toolBarManager);\r
482             }\r
483         }\r
484         \r
485         updateBars();\r
486     }\r
487     \r
488     public InteractiveAction getCurrentAction() {\r
489         return currentAction;\r
490     }\r
491     \r
492     public void setActiveEditorContribution(EditorContribution contribution) {\r
493         if (currentEditorContribution == contribution)\r
494                 return;\r
495         if (currentAction != getDefaultAction())\r
496                 return;\r
497         if (currentEditorContribution != null)\r
498                 currentEditorContribution.disposeControl();\r
499         currentEditorContribution = contribution;\r
500         int index = editorContributions.indexOf(contribution);\r
501         for (int i = 0; i < contributionSelectionActions.size(); i++) {\r
502                 if (i != index)\r
503                         contributionSelectionActions.get(i).setChecked(false);\r
504                 else\r
505                         contributionSelectionActions.get(i).setChecked(true);\r
506         }\r
507         if (currentEditorContribution != null)\r
508                 currentEditorContribution.createControl(parent);\r
509         \r
510         actionBars.clearGlobalActionHandlers();\r
511         \r
512         parent.layout(true, true);\r
513         if (toolBarManager != null) {\r
514                 toolBarManager.removeAll();\r
515                 fillLocalToolBar();\r
516         }\r
517         if (menuManager != null) {              \r
518                 menuManager.removeAll();\r
519                 fillLocalPullDown();\r
520         }\r
521         \r
522         updateBars();\r
523     }\r
524     \r
525     protected void updateBars() {\r
526         // TODO : actionBars.updateActionBars does not update toolbar, updating toolBar directly layouts code \r
527         //        generated widgets top of contributed (extension) widgets. Only way to achieve proper update\r
528         //        is to use WorkbenchWindow.getCoolBarManager.update(true)\r
529         actionBars.updateActionBars();\r
530 //      if (toolBarManager != null) {\r
531 //              toolBarManager.update(true);\r
532 //      }\r
533         WorkbenchWindow w = (WorkbenchWindow)PlatformUI.getWorkbench().getActiveWorkbenchWindow();\r
534         w.getCoolBarManager().update(true);\r
535     }\r
536     \r
537     public void setGizmo(Gizmo gizmo) {\r
538         if (currentGizmo != null) {\r
539                 currentGizmo.getNode().removeFromParent();\r
540         }\r
541         currentGizmo = gizmo;\r
542         selectionAdapter.setCurrentGizmo(gizmo);\r
543         viewChanged = true;\r
544     }\r
545     \r
546 //    public void setInfoText(String text) {\r
547 //        if (useInfoComposite) {\r
548 //            infoText.setText(text);\r
549 //        }\r
550 //    }\r
551 \r
552     public void showMessage(String message) {\r
553         MessageDialog.openInformation(parent.getShell(), "Shape Editor", //$NON-NLS-1$\r
554                 message);\r
555     }\r
556 \r
557 \r
558     /**\r
559      * Passing the focus request to the viewer's control.\r
560      */\r
561     public void setFocus() {\r
562         renderingComposite.getCanvas().setFocus();\r
563     }\r
564 \r
565     public void dispose() {\r
566         //System.out.println("ThreeDimensionalEditorBase.dispose()");\r
567         VisualizationScheduler.getInstance().removeVisualization(this);\r
568 \r
569         if (currentAction != null)\r
570             currentAction.deactivate();\r
571 \r
572         for (EditorContribution e : editorContributions)\r
573                 e.dispose();\r
574         \r
575         renderingComposite.dispose();\r
576 \r
577         // copy of the set is needed to avoid ConcurrentModificationException\r
578         adapter.dispose();\r
579         component.dispose();\r
580     }\r
581 \r
582     public final void reload(Graph g, Resource res) {\r
583         inputResource = res;\r
584         reloadFrom(EntityFactory.create(g, res));\r
585         // at this point we can initialize editor contributions, which may require inputResource\r
586         initializeEditorContributions(g);\r
587     }\r
588 \r
589     public Resource getInputResource() {\r
590         return inputResource;\r
591     }\r
592     \r
593     public void update(GraphChangeEvent event) {\r
594 //        System.out.println("Transaction " + this + " : " + event.getTransactionId() + " Arg1: " + event.getArg1()\r
595 //                + " arg2: " + event.getArg2() + " sender: " + event.getSender() + " source: " + event.getSource());\r
596         \r
597 //        if (event.added.size() > 0) {\r
598 //            System.out.println("Added:");\r
599 //            for (Triplet t : event.added)\r
600 //                System.out.println(t);\r
601 //        }\r
602 //        if (event.changed.size() > 0) {\r
603 //            System.out.println("Changed:");\r
604 //            for (Triplet t : event.changed)\r
605 //                System.out.println(t);\r
606 //        }\r
607 //        if (event.removed.size() > 0) {\r
608 //            System.out.println("Removed:");\r
609 //            for (Triplet t : event.removed)\r
610 //                System.out.println(t);\r
611 //        }\r
612 \r
613     }\r
614 \r
615     \r
616 \r
617     /**\r
618      * Loads the initial scene: all further updates to the view are done by\r
619      * listening changes in the shapes and int the shape group\r
620      * \r
621      * @param resource\r
622      */\r
623     protected abstract void reloadFrom(IEntity thing);\r
624 \r
625 \r
626         protected void viewUpdated() {\r
627 \r
628         }\r
629 \r
630     /*\r
631      * (non-Javadoc)\r
632      * \r
633      * @see java.lang.Runnable#run()\r
634      */\r
635     public void run() {\r
636         if (currentEditorContribution != null)\r
637                 currentEditorContribution.run();\r
638         if (parent.isDisposed() || !parent.isVisible())\r
639                         return;\r
640         //renderingComposite.getDisplaySystem().setCurrent();\r
641                 input.update();\r
642                 if (input.mouseClicked()) {\r
643                         int downMask = MouseEvent.CTRL_DOWN_MASK;\r
644 \r
645                         if ((input.clickModifiers() & downMask) > 0) {\r
646                                 selectionAdapter.setSelectionType(SelectionType.MODIFY);\r
647                         } else {\r
648                                 selectionAdapter.setSelectionType(SelectionType.SET);\r
649                         }\r
650                 }\r
651                 if (input.mouseMoved()) {\r
652                         Ray mouseRay = createPickRay();\r
653                         selectionAdapter.updateHighlights(mouseRay);\r
654                 }\r
655                 if (currentAction == cameraAction && input.mouseClicked()) {\r
656                         selectionAdapter.pickHighlighted();\r
657                 }\r
658                 if (currentAction == cameraAction && input.mousePressed()\r
659                                 && (input.pressModifiers() & MouseEvent.BUTTON3_MASK) > 0) {\r
660                         Point p = renderingComposite.toDisplay(input.mouseX(), input\r
661                                         .mouseY());\r
662                         contextMenu.setLocation(p.x, p.y);\r
663                         contextMenu.setVisible(true);\r
664                 }\r
665 \r
666                 if (currentAction != null)\r
667                         try {\r
668                                 currentAction.update();\r
669                         } catch (Exception e) {\r
670                                 ErrorLogger.defaultLogError("Action error!", e);\r
671                                 setCurrentAction(getDefaultAction());\r
672                         }\r
673 \r
674                 if (component.update())\r
675                         viewChanged = true;\r
676                     \r
677                 if (!geometryUpdateRequestAdapter.isRunning() && adapter.needsUpdateGeometry()) {\r
678                         session.asyncRead(geometryUpdateRequestAdapter);        \r
679                 }\r
680                 \r
681                 viewChanged |= adapter.isChanged();\r
682                  if (viewChanged) {\r
683                         viewChanged = false;\r
684                         adapter.setChanged(false);\r
685                         camera.updateCamera();\r
686                         viewUpdated();\r
687                         component.render();\r
688                 }\r
689         }\r
690     // TODO : there is some sort of synchronization bug in rendering:\r
691     //        part of the rendered objects are rendered with different camera transformation than others.\r
692     //        re-rendering the scene hides the worst problems.\r
693     //        Using shadows is the reason: shadowed objects are rendered with different transformation than non-shadowed.\r
694     //private boolean lastChanged = false;\r
695     \r
696     private GeometryUpdateRequestAdapter geometryUpdateRequestAdapter = new GeometryUpdateRequestAdapter();\r
697         \r
698     private class GeometryUpdateRequestAdapter extends GraphRequestAdapter {\r
699         private boolean running;\r
700         @Override\r
701                 public GraphRequestStatus perform(Graph g) throws Exception {\r
702                 running = true;\r
703                         adapter.updateGeometry(g);\r
704                         return GraphRequestStatus.transactionComplete();\r
705                 }\r
706                 @Override\r
707                 public void requestCompleted(GraphRequestStatus status) {\r
708                         running = false;\r
709                         adapter.setChanged(true);\r
710                 }\r
711                 \r
712                 public boolean isRunning() {\r
713                         return running;\r
714                 }\r
715     }\r
716 \r
717    \r
718     \r
719     protected void hookDragAndDrop() {\r
720         dropTarget = new ShapeDropTarget(this);\r
721     }\r
722 \r
723     /**\r
724      * Receives selection changes\r
725      * \r
726      * @param part\r
727      * @param selection\r
728      */\r
729     protected abstract void pageSelectionChanged(IWorkbenchPart part, ISelection selection);\r
730 \r
731     /**\r
732      * EditorPart or ViewPart uses this method to forward getAdapter(Class)\r
733      * @see org.eclipse.ui.part.WorkbenchPart.getAdapter(Class adapter)\r
734      * @param adapter\r
735      * @return\r
736      */\r
737     public Object getAdapter(Class adapter) {\r
738         return null;\r
739     }\r
740 \r
741 }