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 this.adapter = adapter;
\r
49 public enum SelectionType {
\r
53 protected SelectionType mouseClickType = SelectionType.SET;
\r
55 public SelectionType getSelectionType() {
\r
56 return mouseClickType;
\r
59 public void setSelectionType(SelectionType type) {
\r
60 mouseClickType = type;
\r
63 public void setCurrentGizmo(Gizmo gizmo) {
\r
64 currentGizmo = gizmo;
\r
68 * Lists all selected objects
\r
70 * Selection may contain objects that are not in this view: those are NOT
\r
76 public List<IGraphicsNode> getSelectedObjects() {
\r
77 return getSelectedObjects(selection);
\r
81 * Lists all highlighted objects.
\r
83 * Typically there may be only one highlighted object.
\r
87 public List<IGraphicsNode> getHighlightedObjects() {
\r
88 return getSelectedObjects(interactiveSelection);
\r
92 * Lists all selected objects
\r
94 * Selection may contain objects that are not in this view: those are NOT
\r
100 public List<IGraphicsNode> getInteractiveSelectedObjects() {
\r
101 return getSelectedObjects(interactiveSelection);
\r
105 * Lists all selected objects
\r
107 * Selection may contain objects that are not in this view: those are NOT
\r
113 protected List<IGraphicsNode> getSelectedObjects(StructuredResourceSelection selection) {
\r
114 List<IGraphicsNode> l = new ArrayList<IGraphicsNode>();
\r
115 Iterator<Resource> i = selection.iterator();
\r
116 while (i.hasNext()) {
\r
117 Resource s = i.next();
\r
118 IGraphicsNode shape = adapter.getNode(s);
\r
127 * Return selected objects
\r
129 * May contain objects that are NOT in this view
\r
134 public List<Resource> getSelectedResources() {
\r
135 List<Resource> l = new ArrayList<Resource>();
\r
136 Iterator<Resource> i = selection.iterator();
\r
137 while (i.hasNext()) {
\r
138 Resource s = (Resource) i.next();
\r
145 private ArrayList<PickData> processed = new ArrayList<PickData>();
\r
147 private class ExtTrianglePickResults extends TrianglePickResults {
\r
148 public ExtTrianglePickResults() {
\r
149 this.setCheckDistance(true);
\r
152 public void processPick() {
\r
154 if (getNumber() > 0) {
\r
155 for (int j = 0; j < getNumber(); j++) {
\r
156 PickData pData = getPickData(j);
\r
157 ArrayList<Integer> tris = pData.getTargetTris();
\r
158 if (tris != null && tris.size() > 0) {
\r
159 processed.add(pData);
\r
168 private PickResults result = new ExtTrianglePickResults();
\r
171 private void pickPrefix(String prefix) {
\r
173 ArrayList<PickData> r= new ArrayList<PickData>();
\r
174 for (int i = 0; i < processed.size(); i++) {
\r
175 PickData pData = processed.get(i);
\r
176 if (pData.getTargetMesh().getParentGeom().getName().startsWith(prefix))
\r
183 * Updates highlighted objects according to mouse position.
\r
187 public void updateHighlights(Ray mouseRay) {
\r
189 adapter.getRenderingComponent().getRoot().calculatePick(mouseRay, result);
\r
190 if (currentGizmo != null) {
\r
191 pickPrefix(currentGizmo.getPickPrefix());
\r
193 doHighlightPick(processed);
\r
197 * Picks highlighted objects
\r
199 public void pickHighlighted() {
\r
207 protected void doPick(ArrayList<PickData> result) {
\r
208 if (result != null) {
\r
210 if (result.size() == 0) {
\r
211 if (mouseClickType != SelectionType.MODIFY)
\r
212 updateSelection(new StructuredResourceSelection());
\r
216 String nodeName = result.get(0).getTargetMesh().getParentGeom().getName();
\r
218 StructuredResourceSelection s = new StructuredResourceSelection();
\r
220 Resource selectedResource = adapter.getNodeResource(nodeName);
\r
221 if (adapter.getNode(selectedResource) == null) {
\r
222 updateSelection(new StructuredResourceSelection());
\r
224 //throw new RuntimeException("Picked resource that has no node ?!");
\r
226 if (mouseClickType == SelectionType.MODIFY) {
\r
227 ArrayList<Resource> selected = new ArrayList<Resource>(getSelectedResources());
\r
228 if (selected.contains(selectedResource))
\r
229 selected.remove(selectedResource);
\r
231 selected.add(selectedResource);
\r
232 for (Resource r : selected)
\r
236 s.add(selectedResource);
\r
239 updateSelection(s);
\r
241 // System.out.println("Picked nothing");
\r
242 if (mouseClickType != SelectionType.MODIFY)
\r
243 updateSelection(new StructuredResourceSelection());
\r
248 * Processes highlight pick
\r
251 protected void doHighlightPick(ArrayList<PickData> result) {
\r
252 if (result != null) {
\r
254 if (result.size() == 0) {
\r
256 //System.out.println("IPicked nothing");
\r
257 updateHighlightSelection(new StructuredResourceSelection());
\r
261 String nodeName = result.get(0).getTargetMesh().getParentGeom().getName();
\r
265 // System.out.println("hits: " + result);
\r
266 StructuredResourceSelection s = new StructuredResourceSelection();
\r
268 Resource selectedResource = adapter.getNodeResource(nodeName);
\r
270 if (selectedResource == null) {
\r
271 if (currentGizmo != null && nodeName.startsWith(currentGizmo.getPickPrefix())) {
\r
272 updateGizmo(nodeName);
\r
277 if (adapter.getNode(selectedResource) != null)
\r
278 s.add(selectedResource);
\r
280 updateHighlightSelection(s);
\r
283 // System.out.println("IPicked nothing");
\r
284 updateHighlightSelection(new StructuredResourceSelection());
\r
289 * Updates gizmo according to picked object
\r
292 private void updateGizmo(String pickName) {
\r
293 if (currentGizmo != null) {
\r
294 currentGizmo.setSelected(pickName);
\r
295 if (currentGizmo.isChanged()) {
\r
296 adapter.setChanged(true);
\r
297 currentGizmo.setChanged(false);
\r
304 * Contains selection
\r
306 protected StructuredResourceSelection selection = new StructuredResourceSelection();
\r
308 protected StructuredResourceSelection interactiveSelection = new StructuredResourceSelection();
\r
310 public StructuredResourceSelection getCurrentSelection() {
\r
314 public void setCurrentSelection(StructuredResourceSelection s) {
\r
318 public StructuredResourceSelection getHighlightSelection() {
\r
319 return interactiveSelection;
\r
322 protected void setHighlightSelection(StructuredResourceSelection s) {
\r
323 interactiveSelection = s;
\r
326 private ArrayList<ISelectionChangedListener> selectionChangedListeners = new ArrayList<ISelectionChangedListener>();
\r
332 * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
\r
334 public void addSelectionChangedListener(ISelectionChangedListener listener) {
\r
335 selectionChangedListeners.add(listener);
\r
342 * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
\r
344 public ISelection getSelection() {
\r
350 public static StructuredResourceSelection transformSelection(ISelection sel) {
\r
351 if (sel instanceof StructuredResourceSelection)
\r
352 return (StructuredResourceSelection)sel;
\r
353 StructuredResourceSelection res = new StructuredResourceSelection();
\r
354 Resource resources[] = ResourceAdaptionUtils.toResources(sel);
\r
355 for (Resource r : resources)
\r
365 * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
\r
367 public void removeSelectionChangedListener(ISelectionChangedListener listener) {
\r
368 selectionChangedListeners.remove(listener);
\r
375 * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection)
\r
377 public void setSelection(ISelection selection) {
\r
378 // System.out.println();
\r
379 StructuredResourceSelection s = filterSelection(selection);
\r
380 if (this.selection.equals(s))
\r
382 this.selection = s;
\r
383 adapter.setChanged(true);
\r
384 setEditorSelection();
\r
389 * Filters selection given with setSelection(ISelection selection) This
\r
390 * allows impemented editors to modify selection before it's applied into
\r
394 * @return the filtered selection
\r
396 protected abstract StructuredResourceSelection filterSelection(ISelection s);
\r
399 * Updates visual part of selection event. Use getCurrentSelection() to get
\r
402 public abstract void setEditorSelection();
\r
405 * Updates visual part of selection event. Use getInteractiveSelection() to
\r
406 * get the selection
\r
408 protected abstract void setEditorHighlightSelection();
\r
411 * Editor's internal selection update<br>
\r
412 * Sends events to other editors and views about changed selection
\r
417 public boolean updateSelection(StructuredResourceSelection s) {
\r
418 if (this.selection.equals(s))
\r
421 this.selection = s;
\r
422 adapter.setChanged(true);
\r
423 fireSelectionChangedEvent();
\r
424 setEditorSelection();
\r
428 protected boolean updateHighlightSelection(StructuredResourceSelection s) {
\r
429 if (interactiveSelection.equals(s))
\r
431 this.interactiveSelection = s;
\r
432 adapter.setChanged(true);
\r
433 setEditorHighlightSelection();
\r
438 * Fires selection changed events.
\r
440 protected void fireSelectionChangedEvent() {
\r
441 SelectionChangedEvent e = new SelectionChangedEvent(this, this.selection);
\r
442 for (ISelectionChangedListener l : selectionChangedListeners)
\r
443 l.selectionChanged(e);
\r