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
9 * VTT Technical Research Centre of Finland - initial API and implementation
\r
10 *******************************************************************************/
\r
11 package org.simantics.proconf.g3d.base;
\r
13 import java.awt.event.MouseEvent;
\r
14 import java.util.ArrayList;
\r
15 import java.util.List;
\r
17 import javax.vecmath.Tuple3d;
\r
18 import javax.vecmath.Vector3d;
\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.ErrorLogger;
\r
67 import org.simantics.utils.ui.jface.MenuTools;
\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
75 public abstract class ThreeDimensionalEditorBase implements Runnable {
\r
77 private Resource inputResource;
\r
79 private List<EditorContribution> editorContributions = new ArrayList<EditorContribution>();
\r
81 private EditorContribution currentEditorContribution;
\r
83 protected List<ContextAction> actions = new ArrayList<ContextAction>();
\r
85 private List<Action> contributionSelectionActions = new ArrayList<Action>();
\r
87 protected Composite parent;
\r
89 protected ISessionContext sessionContext;
\r
91 protected Session session;
\r
93 protected ScenegraphAdapter adapter;
\r
95 protected SelectionAdapter selectionAdapter;
\r
97 protected Action refreshAction;
\r
99 protected Action configureJMEAction;
\r
101 private Action lockScenegraphAction;
\r
103 protected Menu contextMenu;
\r
105 private JmeComposite renderingComposite = null;
\r
107 protected OrbitalCamera camera = new OrbitalCamera();
\r
109 protected boolean viewChanged = true;
\r
111 private InteractiveAction currentAction = null;
\r
113 private Gizmo currentGizmo = null;
\r
115 private InteractiveAction cameraAction = null;
\r
117 private JmeRenderingComponent component = null;
\r
119 protected InputProvider input = null;
\r
121 protected ShapeDropTarget dropTarget;
\r
123 // protected IEditorActionBarContributor actionBarContributor;
\r
124 protected IActionBars actionBars;
\r
125 protected IToolBarManager toolBarManager;
\r
126 protected IMenuManager menuManager;
\r
128 public ThreeDimensionalEditorBase(ISessionContext session) {
\r
129 this.sessionContext = session;
\r
130 this.session = session.getSession();
\r
131 component = new JmeSinglePassRenderingComponent();
\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
140 // public void setActionBarContributor(IEditorActionBarContributor contributor) {
\r
141 // actionBarContributor = contributor;
\r
144 public void setActionBars(IActionBars actionBars) {
\r
145 this.actionBars = actionBars;
\r
146 this.menuManager = actionBars.getMenuManager();
\r
147 this.toolBarManager = actionBars.getToolBarManager();
\r
153 public ISessionContext getSessionContext() {
\r
154 return sessionContext;
\r
157 public Session getSession() {
\r
162 * Creates basic UI for ThreeDimenionalEditors.
\r
163 * Note : inputResource has not been set at this point.
\r
168 public void createControl(Graph graph, Composite parent) {
\r
169 this.parent = parent;
\r
170 renderingComposite = new JmeComposite(parent,component);
\r
171 // add listeners to force repaint on size changes
\r
172 renderingComposite.getCanvas().addPaintListener(new PaintListener() {
\r
173 public void paintControl(PaintEvent e) {
\r
174 viewChanged = true;
\r
179 input = new SWTInputProvider();
\r
181 renderingComposite.initGL();
\r
182 camera.setCamera(component.getCamera());
\r
183 camera.updateCamera();
\r
184 makeActions(graph);
\r
187 // provide selection events for properies view
\r
188 this.adapter = createScenegraphAdapter();
\r
189 this.selectionAdapter = createSelectionAdapter();
\r
191 this.selectionAdapter.addSelectionChangedListener(new ISelectionChangedListener() {
\r
192 public void selectionChanged(SelectionChangedEvent event) {
\r
193 setCurrentAction(getDefaultAction());
\r
196 hookDragAndDrop();
\r
198 VisualizationScheduler.getInstance().addVisualization(this);
\r
200 if (editorContributions.size() > 0) {
\r
201 // setActiveEditorContribution(editorContributions.get(0));
\r
202 // } else if (editorContributions.size() > 1) {
\r
203 // create actions for selecting contribution
\r
204 for (EditorContribution ec : editorContributions) {
\r
205 final EditorContribution e = ec;
\r
206 Action a = new Action(e.getName(),Action.AS_RADIO_BUTTON) {
\r
208 public void run() {
\r
210 setActiveEditorContribution(e);
\r
213 contributionSelectionActions.add(a);
\r
220 public void addEditorContribution(EditorContribution e) {
\r
221 if (parent != null)
\r
222 throw new RuntimeException("Editor contributions must be added before editor is created.");
\r
223 editorContributions.add(e);
\r
226 private void initializeEditorContributions(Graph graph) {
\r
227 for (EditorContribution e : editorContributions) {
\r
228 e.initialize(graph);
\r
230 if (editorContributions.size() > 0)
\r
231 parent.getDisplay().asyncExec(new Runnable() {
\r
233 public void run() {
\r
234 setActiveEditorContribution(editorContributions.get(0));
\r
240 private void hookInput() {
\r
241 renderingComposite.getCanvas().addKeyListener((SWTInputProvider) input);
\r
242 renderingComposite.getCanvas().addMouseListener((SWTInputProvider) input);
\r
243 renderingComposite.getCanvas().addMouseMoveListener((SWTInputProvider) input);
\r
244 renderingComposite.getCanvas().addMouseTrackListener((SWTInputProvider) input);
\r
245 renderingComposite.getCanvas().addFocusListener((SWTInputProvider) input);
\r
248 protected abstract ScenegraphAdapter createScenegraphAdapter();
\r
249 protected abstract SelectionAdapter createSelectionAdapter();
\r
252 public JmeComposite getRenderingComposite() {
\r
253 return renderingComposite;
\r
256 public JmeRenderingComponent getRenderingComponent() {
\r
260 public ScenegraphAdapter getScenegraphAdapter() {
\r
264 public SelectionAdapter getSelectionAdapter() {
\r
265 return selectionAdapter;
\r
268 public OrbitalCamera getCamera() {
\r
272 public void setViewChanged(boolean b) {
\r
276 protected void hookContextMenu() {
\r
277 MenuManager menuMgr = new MenuManager("#PopupMenu");
\r
278 menuMgr.setRemoveAllWhenShown(true);
\r
279 menuMgr.addMenuListener(new IMenuListener() {
\r
280 public void menuAboutToShow(IMenuManager manager) {
\r
281 final IMenuManager m = manager;
\r
282 GraphRequestAdapter r = new GraphRequestAdapter() {
\r
284 public GraphRequestStatus perform(Graph g) throws Exception {
\r
285 ThreeDimensionalEditorBase.this.fillContextMenu(g,m);
\r
286 return GraphRequestStatus.transactionComplete();
\r
290 session.syncRead(r);
\r
295 contextMenu = menuMgr.createContextMenu(renderingComposite);
\r
300 protected void fillContextMenu(Graph graph,IMenuManager manager) {
\r
301 manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
\r
303 List<Resource> selected = selectionAdapter.getSelectedResources();
\r
304 for (ContextAction action : actions) {
\r
305 if(action.usable(graph,selected)) {
\r
306 manager.add(action);
\r
309 if (currentEditorContribution != null) {
\r
310 currentEditorContribution.fillContextMenu(graph, manager, selectionAdapter.getCurrentSelection());
\r
311 for (ContextAction action : currentEditorContribution.getActions()) {
\r
312 if(action.usable(graph,selected)) {
\r
313 manager.add(action);
\r
320 protected void fillLocalToolBar() {
\r
322 if (currentEditorContribution != null)
\r
323 currentEditorContribution.fillLocalToolBar(toolBarManager);
\r
326 protected void fillLocalPullDown() {
\r
327 for (Action a : contributionSelectionActions) {
\r
328 IMenuManager menu = MenuTools.getOrCreate(getMenuID(),"View", menuManager);
\r
331 MenuTools.getOrCreate(getMenuID(),"Advanced", menuManager).add(refreshAction);
\r
332 if (configureJMEAction != null) {
\r
333 MenuTools.getOrCreate(getMenuID(),"Advanced", menuManager).add(configureJMEAction);
\r
336 MenuTools.getOrCreate(getMenuID(),"Advanced", menuManager).add(lockScenegraphAction);
\r
337 if (currentEditorContribution != null)
\r
338 currentEditorContribution.fillLocalPullDown(menuManager);
\r
341 public String getMenuID() {
\r
342 return Long.toString(getInputResource().getResourceId());
\r
345 protected void makeActions(Graph graph) {
\r
347 refreshAction = new Action() {
\r
349 public void run() {
\r
350 GraphRequestAdapter r = new GraphRequestAdapter() {
\r
351 public GraphRequestStatus perform(Graph g) throws Exception {
\r
352 // Stack<IGraphicsNode> stack = new Stack<IGraphicsNode>();
\r
353 // stack.push(adapter.getNode(adapter.getRootResource()));
\r
354 // while(!stack.isEmpty()) {
\r
355 // IGraphicsNode node = stack.pop();
\r
356 // stack.addAll(node.getChildren());
\r
357 // if (node instanceof IGeometryNode) {
\r
358 // ((IGeometryNode)node).updateGeometry(g);
\r
361 for (IGraphicsNode node : adapter.getNodes())
\r
362 if (node instanceof IGeometryNode)
\r
363 ((IGeometryNode)node).updateGeometry(g);
\r
364 viewChanged = true;
\r
365 return GraphRequestStatus.transactionComplete();
\r
368 session.asyncRead(r);
\r
372 refreshAction.setText("Refresh");
\r
373 refreshAction.setToolTipText("Refreshes the visualization");
\r
374 refreshAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
\r
375 ISharedImages.IMG_TOOL_UP));
\r
376 if (getRenderingComponent() instanceof JmeSinglePassRenderingComponent) {
\r
377 configureJMEAction = new Action() {
\r
378 public void run() {
\r
379 JmeSinglePassRenderingComponent c = (JmeSinglePassRenderingComponent)getRenderingComponent();
\r
380 JMEDialog dialog = new JMEDialog(ThreeDimensionalEditorBase.this.parent.getShell());
\r
381 c.getDisplaySystem().setCurrent();
\r
382 dialog.setBounds(c.isShowBounds());
\r
383 dialog.setNormals(c.isShowNormals());
\r
384 dialog.setWireframe(c.isShowWireframe());
\r
385 ColorRGBA col = c.getDisplaySystem().getRenderer().getBackgroundColor();
\r
386 dialog.setFloatColor(new float[]{col.r,col.g,col.b});
\r
387 if (dialog.open() == JMEDialog.CANCEL)
\r
389 c.setShowBounds(dialog.isBounds());
\r
390 c.setShowNormals(dialog.isNormals());
\r
391 c.setShowWireframe(dialog.isWireframe());
\r
392 if (dialog.getFloatColor() != null) {
\r
393 c.getDisplaySystem().setCurrent();
\r
394 c.getDisplaySystem().getRenderer().setBackgroundColor(new ColorRGBA(dialog.getFloatColor()[0],dialog.getFloatColor()[1],dialog.getFloatColor()[2],0.f));
\r
398 configureJMEAction.setText("Configure JME");
\r
399 configureJMEAction.setImageDescriptor(Activator.imageDescriptorFromPlugin("fi.vtt.proconf.ode", "icons/silk/wrench.png"));
\r
402 lockScenegraphAction = new Action("Lock scenegraph",Action.AS_CHECK_BOX) {
\r
403 public void run() {
\r
404 new ScenegraphLockTraverser(adapter.getRoot(),this.isChecked());
\r
408 cameraAction = new CameraAction(this);
\r
409 currentAction = cameraAction;
\r
414 public InteractiveAction getDefaultAction() {
\r
415 return cameraAction;
\r
418 public void createPickRay(Vector3d o, Vector3d d) {
\r
419 Ray r = createPickRay();
\r
423 d.x = r.direction.x;
\r
424 d.y = r.direction.y;
\r
425 d.z = r.direction.z;
\r
429 public Ray createPickRay() {
\r
430 Vector2f screenPos = new Vector2f();
\r
431 screenPos.set(input.mouseX(),renderingComposite.getBounds().height - input.mouseY());
\r
435 if (component.getCamera().isParallelProjection()) {
\r
436 Vector3f worldCoords = renderingComposite.getDisplaySystem().getWorldCoordinates(screenPos, 0.0f);
\r
437 mouseRay = new Ray(worldCoords,
\r
438 component.getCamera().getDirection());
\r
440 Vector3f worldCoords = renderingComposite.getDisplaySystem().getWorldCoordinates(screenPos, 1.0f);
\r
441 mouseRay = new Ray(component.getCamera().getLocation(), worldCoords
\r
442 .subtractLocal(component.getCamera().getLocation()));
\r
447 public Vector2f getScreenCoord(Tuple3d worldCoord) {
\r
448 Vector3f v = renderingComposite.getDisplaySystem().getScreenCoordinates(VecmathJmeTools.get(worldCoord));
\r
449 return new Vector2f(v.x,v.y);
\r
453 public InputProvider getInputProvider() {
\r
458 * Changes current action
\r
462 public void setCurrentAction(InteractiveAction action) {
\r
463 if (currentAction == action)
\r
465 if (toolBarManager != null) {
\r
466 toolBarManager.removeAll();
\r
467 fillLocalToolBar();
\r
469 if (currentAction != null)
\r
470 currentAction.deactivate();
\r
471 currentAction = action;
\r
472 if (currentAction != null) {
\r
473 currentAction.activate();
\r
474 if (toolBarManager != null) {
\r
475 currentAction.fillToolBar(toolBarManager);
\r
482 public InteractiveAction getCurrentAction() {
\r
483 return currentAction;
\r
486 public void setActiveEditorContribution(EditorContribution contribution) {
\r
487 if (currentEditorContribution == contribution)
\r
489 if (currentAction != getDefaultAction())
\r
491 if (currentEditorContribution != null)
\r
492 currentEditorContribution.disposeControl();
\r
493 currentEditorContribution = contribution;
\r
494 int index = editorContributions.indexOf(contribution);
\r
495 for (int i = 0; i < contributionSelectionActions.size(); i++) {
\r
497 contributionSelectionActions.get(i).setChecked(false);
\r
499 contributionSelectionActions.get(i).setChecked(true);
\r
501 if (currentEditorContribution != null)
\r
502 currentEditorContribution.createControl(parent);
\r
504 actionBars.clearGlobalActionHandlers();
\r
506 parent.layout(true, true);
\r
507 if (toolBarManager != null) {
\r
508 toolBarManager.removeAll();
\r
509 fillLocalToolBar();
\r
511 if (menuManager != null) {
\r
512 menuManager.removeAll();
\r
513 fillLocalPullDown();
\r
519 protected void updateBars() {
\r
520 // TODO : actionBars.updateActionBars does not update toolbar, updating toolBar directly layouts code
\r
521 // generated widgets top of contributed (extension) widgets. Only way to achieve proper update
\r
522 // is to use WorkbenchWindow.getCoolBarManager.update(true)
\r
523 actionBars.updateActionBars();
\r
524 // if (toolBarManager != null) {
\r
525 // toolBarManager.update(true);
\r
527 WorkbenchWindow w = (WorkbenchWindow)PlatformUI.getWorkbench().getActiveWorkbenchWindow();
\r
528 w.getCoolBarManager().update(true);
\r
531 public void setGizmo(Gizmo gizmo) {
\r
532 if (currentGizmo != null) {
\r
533 currentGizmo.getNode().removeFromParent();
\r
535 currentGizmo = gizmo;
\r
536 selectionAdapter.setCurrentGizmo(gizmo);
\r
537 viewChanged = true;
\r
540 // public void setInfoText(String text) {
\r
541 // if (useInfoComposite) {
\r
542 // infoText.setText(text);
\r
546 public void showMessage(String message) {
\r
547 MessageDialog.openInformation(parent.getShell(), "Shape Editor", //$NON-NLS-1$
\r
553 * Passing the focus request to the viewer's control.
\r
555 public void setFocus() {
\r
556 renderingComposite.getCanvas().setFocus();
\r
559 public void dispose() {
\r
560 //System.out.println("ThreeDimensionalEditorBase.dispose()");
\r
561 VisualizationScheduler.getInstance().removeVisualization(this);
\r
563 if (currentAction != null)
\r
564 currentAction.deactivate();
\r
566 for (EditorContribution e : editorContributions)
\r
569 renderingComposite.dispose();
\r
571 // copy of the set is needed to avoid ConcurrentModificationException
\r
573 component.dispose();
\r
576 public final void reload(Graph g, Resource res) {
\r
577 inputResource = res;
\r
578 reloadFrom(EntityFactory.create(g, res));
\r
579 // at this point we can initialize editor contributions, which may require inputResource
\r
580 initializeEditorContributions(g);
\r
583 public Resource getInputResource() {
\r
584 return inputResource;
\r
587 public void update(GraphChangeEvent event) {
\r
588 // System.out.println("Transaction " + this + " : " + event.getTransactionId() + " Arg1: " + event.getArg1()
\r
589 // + " arg2: " + event.getArg2() + " sender: " + event.getSender() + " source: " + event.getSource());
\r
591 // if (event.added.size() > 0) {
\r
592 // System.out.println("Added:");
\r
593 // for (Triplet t : event.added)
\r
594 // System.out.println(t);
\r
596 // if (event.changed.size() > 0) {
\r
597 // System.out.println("Changed:");
\r
598 // for (Triplet t : event.changed)
\r
599 // System.out.println(t);
\r
601 // if (event.removed.size() > 0) {
\r
602 // System.out.println("Removed:");
\r
603 // for (Triplet t : event.removed)
\r
604 // System.out.println(t);
\r
612 * Loads the initial scene: all further updates to the view are done by
\r
613 * listening changes in the shapes and int the shape group
\r
617 protected abstract void reloadFrom(IEntity thing);
\r
620 protected void viewUpdated() {
\r
627 * @see java.lang.Runnable#run()
\r
629 public void run() {
\r
630 if (currentEditorContribution != null)
\r
631 currentEditorContribution.run();
\r
632 if (parent.isDisposed() || !parent.isVisible())
\r
634 //renderingComposite.getDisplaySystem().setCurrent();
\r
636 if (input.mouseClicked()) {
\r
637 int downMask = MouseEvent.CTRL_DOWN_MASK;
\r
639 if ((input.clickModifiers() & downMask) > 0) {
\r
640 selectionAdapter.setSelectionType(SelectionType.MODIFY);
\r
642 selectionAdapter.setSelectionType(SelectionType.SET);
\r
645 if (input.mouseMoved()) {
\r
646 Ray mouseRay = createPickRay();
\r
647 selectionAdapter.updateHighlights(mouseRay);
\r
649 if (currentAction == cameraAction && input.mouseClicked()) {
\r
650 selectionAdapter.pickHighlighted();
\r
652 if (currentAction == cameraAction && input.mousePressed()
\r
653 && (input.pressModifiers() & MouseEvent.BUTTON3_MASK) > 0) {
\r
654 Point p = renderingComposite.toDisplay(input.mouseX(), input
\r
656 contextMenu.setLocation(p.x, p.y);
\r
657 contextMenu.setVisible(true);
\r
660 if (currentAction != null)
\r
662 currentAction.update();
\r
663 } catch (Exception e) {
\r
664 ErrorLogger.defaultLogError("Action error!", e);
\r
665 setCurrentAction(getDefaultAction());
\r
668 if (component.update())
\r
669 viewChanged = true;
\r
671 if (!geometryUpdateRequestAdapter.isRunning() && adapter.needsUpdateGeometry()) {
\r
672 session.asyncRead(geometryUpdateRequestAdapter);
\r
675 viewChanged |= adapter.isChanged();
\r
677 viewChanged = false;
\r
678 adapter.setChanged(false);
\r
679 camera.updateCamera();
\r
681 component.render();
\r
684 // TODO : there is some sort of synchronization bug in rendering:
\r
685 // part of the rendered objects are rendered with different camera transformation than others.
\r
686 // re-rendering the scene hides the worst problems.
\r
687 // Using shadows is the reason: shadowed objects are rendered with different transformation than non-shadowed.
\r
688 //private boolean lastChanged = false;
\r
690 private GeometryUpdateRequestAdapter geometryUpdateRequestAdapter = new GeometryUpdateRequestAdapter();
\r
692 private class GeometryUpdateRequestAdapter extends GraphRequestAdapter {
\r
693 private boolean running;
\r
695 public GraphRequestStatus perform(Graph g) throws Exception {
\r
697 adapter.updateGeometry(g);
\r
698 return GraphRequestStatus.transactionComplete();
\r
701 public void requestCompleted(GraphRequestStatus status) {
\r
703 adapter.setChanged(true);
\r
706 public boolean isRunning() {
\r
713 protected void hookDragAndDrop() {
\r
714 dropTarget = new ShapeDropTarget(this);
\r
718 * Receives selection changes
\r
723 protected abstract void pageSelectionChanged(IWorkbenchPart part, ISelection selection);
\r
726 * EditorPart or ViewPart uses this method to forward getAdapter(Class)
\r
727 * @see org.eclipse.ui.part.WorkbenchPart.getAdapter(Class adapter)
\r
731 public Object getAdapter(Class adapter) {
\r