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.util.ArrayList;
\r
14 import java.util.Iterator;
\r
15 import java.util.List;
\r
17 import org.eclipse.jface.viewers.ISelection;
\r
18 import org.eclipse.jface.viewers.ISelectionChangedListener;
\r
19 import org.eclipse.jface.viewers.ISelectionProvider;
\r
20 import org.eclipse.jface.viewers.SelectionChangedEvent;
\r
21 import org.simantics.proconf.g3d.common.StructuredResourceSelection;
\r
22 import org.simantics.proconf.g3d.gizmo.Gizmo;
\r
23 import org.simantics.proconf.g3d.scenegraph.IGraphicsNode;
\r
24 import org.simantics.proconf.ui.utils.ResourceAdaptionUtils;
\r
26 import com.jme.intersection.PickData;
\r
27 import com.jme.intersection.PickResults;
\r
28 import com.jme.intersection.TrianglePickResults;
\r
29 import com.jme.math.Ray;
\r
31 import org.simantics.db.Resource;
\r
34 * Manages highlighting and selecting of objects.
\r
36 * @author Marko Luukkainen
\r
39 public abstract class SelectionAdapter implements ISelectionProvider{
\r
41 protected ScenegraphAdapter adapter;
\r
43 private Gizmo currentGizmo = null;
\r
45 public SelectionAdapter(ScenegraphAdapter adapter) {
\r
46 if (adapter == null)
\r
47 throw new NullPointerException("Scenegraph adapter must no be null");
\r
48 this.adapter = adapter;
\r
51 public enum SelectionType {
\r
55 protected SelectionType mouseClickType = SelectionType.SET;
\r
57 public SelectionType getSelectionType() {
\r
58 return mouseClickType;
\r
61 public void setSelectionType(SelectionType type) {
\r
62 mouseClickType = type;
\r
65 public void setCurrentGizmo(Gizmo gizmo) {
\r
66 currentGizmo = gizmo;
\r
70 * Lists all selected objects
\r
72 * Selection may contain objects that are not in this view: those are NOT
\r
78 public List<IGraphicsNode> getSelectedObjects() {
\r
79 return getSelectedObjects(selection);
\r
83 * Lists all highlighted objects.
\r
85 * Typically there may be only one highlighted object.
\r
89 public List<IGraphicsNode> getHighlightedObjects() {
\r
90 return getSelectedObjects(interactiveSelection);
\r
94 * Lists all selected objects
\r
96 * Selection may contain objects that are not in this view: those are NOT
\r
102 public List<IGraphicsNode> getInteractiveSelectedObjects() {
\r
103 return getSelectedObjects(interactiveSelection);
\r
107 * Lists all selected objects
\r
109 * Selection may contain objects that are not in this view: those are NOT
\r
115 protected List<IGraphicsNode> getSelectedObjects(StructuredResourceSelection selection) {
\r
116 List<IGraphicsNode> l = new ArrayList<IGraphicsNode>();
\r
117 Iterator<Resource> i = selection.iterator();
\r
118 while (i.hasNext()) {
\r
119 Resource s = i.next();
\r
120 IGraphicsNode shape = adapter.getNode(s);
\r
129 * Return selected objects
\r
131 * May contain objects that are NOT in this view
\r
136 public List<Resource> getSelectedResources() {
\r
137 List<Resource> l = new ArrayList<Resource>();
\r
138 Iterator<Resource> i = selection.iterator();
\r
139 while (i.hasNext()) {
\r
140 Resource s = (Resource) i.next();
\r
147 private ArrayList<PickData> processed = new ArrayList<PickData>();
\r
149 private class ExtTrianglePickResults extends TrianglePickResults {
\r
150 public ExtTrianglePickResults() {
\r
151 this.setCheckDistance(true);
\r
154 public void processPick() {
\r
156 if (getNumber() > 0) {
\r
157 for (int j = 0; j < getNumber(); j++) {
\r
158 PickData pData = getPickData(j);
\r
159 ArrayList<Integer> tris = pData.getTargetTris();
\r
160 if (tris != null && tris.size() > 0) {
\r
161 processed.add(pData);
\r
170 private PickResults result = new ExtTrianglePickResults();
\r
173 private void pickPrefix(String prefix) {
\r
175 ArrayList<PickData> r= new ArrayList<PickData>();
\r
176 for (int i = 0; i < processed.size(); i++) {
\r
177 PickData pData = processed.get(i);
\r
178 if (pData.getTargetMesh().getParentGeom().getName().startsWith(prefix))
\r
185 * Updates highlighted objects according to mouse position.
\r
189 public void updateHighlights(Ray mouseRay) {
\r
191 adapter.getRenderingComponent().getRoot().calculatePick(mouseRay, result);
\r
192 if (currentGizmo != null) {
\r
193 pickPrefix(currentGizmo.getPickPrefix());
\r
195 doHighlightPick(processed);
\r
199 * Picks highlighted objects
\r
201 public void pickHighlighted() {
\r
209 protected void doPick(ArrayList<PickData> result) {
\r
210 if (result != null) {
\r
212 if (result.size() == 0) {
\r
213 if (mouseClickType != SelectionType.MODIFY)
\r
214 updateSelection(new StructuredResourceSelection());
\r
218 String nodeName = result.get(0).getTargetMesh().getParentGeom().getName();
\r
220 StructuredResourceSelection s = new StructuredResourceSelection();
\r
222 Resource selectedResource = adapter.getNodeResource(nodeName);
\r
223 if (adapter.getNode(selectedResource) == null) {
\r
224 updateSelection(new StructuredResourceSelection());
\r
226 //throw new RuntimeException("Picked resource that has no node ?!");
\r
228 if (mouseClickType == SelectionType.MODIFY) {
\r
229 ArrayList<Resource> selected = new ArrayList<Resource>(getSelectedResources());
\r
230 if (selected.contains(selectedResource))
\r
231 selected.remove(selectedResource);
\r
233 selected.add(selectedResource);
\r
234 for (Resource r : selected)
\r
238 s.add(selectedResource);
\r
241 updateSelection(s);
\r
243 // System.out.println("Picked nothing");
\r
244 if (mouseClickType != SelectionType.MODIFY)
\r
245 updateSelection(new StructuredResourceSelection());
\r
250 * Processes highlight pick
\r
253 protected void doHighlightPick(ArrayList<PickData> result) {
\r
254 if (result != null) {
\r
256 if (result.size() == 0) {
\r
258 //System.out.println("IPicked nothing");
\r
259 updateHighlightSelection(new StructuredResourceSelection());
\r
263 String nodeName = result.get(0).getTargetMesh().getParentGeom().getName();
\r
267 // System.out.println("hits: " + result);
\r
268 StructuredResourceSelection s = new StructuredResourceSelection();
\r
270 Resource selectedResource = adapter.getNodeResource(nodeName);
\r
272 if (selectedResource == null) {
\r
273 if (currentGizmo != null && nodeName.startsWith(currentGizmo.getPickPrefix())) {
\r
274 updateGizmo(nodeName);
\r
279 if (adapter.getNode(selectedResource) != null)
\r
280 s.add(selectedResource);
\r
282 updateHighlightSelection(s);
\r
285 // System.out.println("IPicked nothing");
\r
286 updateHighlightSelection(new StructuredResourceSelection());
\r
291 * Updates gizmo according to picked object
\r
294 private void updateGizmo(String pickName) {
\r
295 if (currentGizmo != null) {
\r
296 currentGizmo.setSelected(pickName);
\r
297 if (currentGizmo.isChanged()) {
\r
298 adapter.setChanged(true);
\r
299 currentGizmo.setChanged(false);
\r
306 * Contains selection
\r
308 protected StructuredResourceSelection selection = new StructuredResourceSelection();
\r
310 protected StructuredResourceSelection interactiveSelection = new StructuredResourceSelection();
\r
312 public StructuredResourceSelection getCurrentSelection() {
\r
316 public void setCurrentSelection(StructuredResourceSelection s) {
\r
320 public StructuredResourceSelection getHighlightSelection() {
\r
321 return interactiveSelection;
\r
324 protected void setHighlightSelection(StructuredResourceSelection s) {
\r
325 interactiveSelection = s;
\r
328 private ArrayList<ISelectionChangedListener> selectionChangedListeners = new ArrayList<ISelectionChangedListener>();
\r
334 * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
\r
336 public void addSelectionChangedListener(ISelectionChangedListener listener) {
\r
337 selectionChangedListeners.add(listener);
\r
344 * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
\r
346 public ISelection getSelection() {
\r
352 public static StructuredResourceSelection transformSelection(ISelection sel) {
\r
353 if (sel instanceof StructuredResourceSelection)
\r
354 return (StructuredResourceSelection)sel;
\r
355 StructuredResourceSelection res = new StructuredResourceSelection();
\r
356 Resource resources[] = ResourceAdaptionUtils.toResources(sel);
\r
357 for (Resource r : resources)
\r
367 * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
\r
369 public void removeSelectionChangedListener(ISelectionChangedListener listener) {
\r
370 selectionChangedListeners.remove(listener);
\r
377 * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection)
\r
379 public void setSelection(ISelection selection) {
\r
380 // System.out.println();
\r
381 StructuredResourceSelection s = filterSelection(selection);
\r
382 if (this.selection.equals(s))
\r
384 this.selection = s;
\r
385 adapter.setChanged(true);
\r
386 setEditorSelection();
\r
391 * Filters selection given with setSelection(ISelection selection) This
\r
392 * allows impemented editors to modify selection before it's applied into
\r
396 * @return the filtered selection
\r
398 protected StructuredResourceSelection filterSelection(ISelection s) {
\r
399 if (!(selection instanceof StructuredResourceSelection))
\r
400 return new StructuredResourceSelection();
\r
401 return (StructuredResourceSelection) selection;
\r
405 * Updates visual part of selection event. Use getCurrentSelection() to get
\r
408 public abstract void setEditorSelection();
\r
411 * Updates visual part of selection event. Use getInteractiveSelection() to
\r
412 * get the selection
\r
414 protected abstract void setEditorHighlightSelection();
\r
417 * Editor's internal selection update<br>
\r
418 * Sends events to other editors and views about changed selection
\r
423 public boolean updateSelection(StructuredResourceSelection s) {
\r
424 if (this.selection.equals(s))
\r
427 this.selection = s;
\r
428 adapter.setChanged(true);
\r
429 fireSelectionChangedEvent();
\r
430 setEditorSelection();
\r
434 protected boolean updateHighlightSelection(StructuredResourceSelection s) {
\r
435 if (interactiveSelection.equals(s))
\r
437 this.interactiveSelection = s;
\r
438 adapter.setChanged(true);
\r
439 setEditorHighlightSelection();
\r
444 * Fires selection changed events.
\r
446 protected void fireSelectionChangedEvent() {
\r
447 SelectionChangedEvent e = new SelectionChangedEvent(this, this.selection);
\r
448 for (ISelectionChangedListener l : selectionChangedListeners)
\r
449 l.selectionChanged(e);
\r