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