X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.g3d%2Fsrc%2Forg%2Fsimantics%2Fproconf%2Fg3d%2Fbase%2FSelectionAdapter.java;fp=org.simantics.g3d%2Fsrc%2Forg%2Fsimantics%2Fproconf%2Fg3d%2Fbase%2FSelectionAdapter.java;h=2b0b4802184fb22d36950276d03d6c185b43cd6b;hb=10f144a2bb2d7bec98b812b83acecb333fd098ea;hp=0000000000000000000000000000000000000000;hpb=3055b543aa5afc0cca4bb3b341704e7c5103fa6a;p=simantics%2F3d.git diff --git a/org.simantics.g3d/src/org/simantics/proconf/g3d/base/SelectionAdapter.java b/org.simantics.g3d/src/org/simantics/proconf/g3d/base/SelectionAdapter.java new file mode 100644 index 00000000..2b0b4802 --- /dev/null +++ b/org.simantics.g3d/src/org/simantics/proconf/g3d/base/SelectionAdapter.java @@ -0,0 +1,451 @@ +/******************************************************************************* + * Copyright (c) 2007- VTT Technical Research Centre of Finland. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.proconf.g3d.base; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.simantics.proconf.g3d.common.StructuredResourceSelection; +import org.simantics.proconf.g3d.gizmo.Gizmo; +import org.simantics.proconf.g3d.scenegraph.IGraphicsNode; +import org.simantics.proconf.ui.utils.ResourceAdaptionUtils; + +import com.jme.intersection.PickData; +import com.jme.intersection.PickResults; +import com.jme.intersection.TrianglePickResults; +import com.jme.math.Ray; + +import org.simantics.db.Resource; + +/** + * Manages highlighting and selecting of objects. + * + * @author Marko Luukkainen + * + */ +public abstract class SelectionAdapter implements ISelectionProvider{ + + protected ScenegraphAdapter adapter; + + private Gizmo currentGizmo = null; + + public SelectionAdapter(ScenegraphAdapter adapter) { + if (adapter == null) + throw new NullPointerException("Scenegraph adapter must no be null"); + this.adapter = adapter; + } + + public enum SelectionType { + SET, MODIFY + }; + + protected SelectionType mouseClickType = SelectionType.SET; + + public SelectionType getSelectionType() { + return mouseClickType; + } + + public void setSelectionType(SelectionType type) { + mouseClickType = type; + } + + public void setCurrentGizmo(Gizmo gizmo) { + currentGizmo = gizmo; + } + + /** + * Lists all selected objects + *

+ * Selection may contain objects that are not in this view: those are NOT + * returned + *

+ * + * @return + */ + public List getSelectedObjects() { + return getSelectedObjects(selection); + } + + /** + * Lists all highlighted objects. + *

+ * Typically there may be only one highlighted object. + *

+ * @return + */ + public List getHighlightedObjects() { + return getSelectedObjects(interactiveSelection); + } + + /** + * Lists all selected objects + *

+ * Selection may contain objects that are not in this view: those are NOT + * returned + *

+ * + * @return + */ + public List getInteractiveSelectedObjects() { + return getSelectedObjects(interactiveSelection); + } + + /** + * Lists all selected objects + *

+ * Selection may contain objects that are not in this view: those are NOT + * returned + *

+ * + * @return + */ + protected List getSelectedObjects(StructuredResourceSelection selection) { + List l = new ArrayList(); + Iterator i = selection.iterator(); + while (i.hasNext()) { + Resource s = i.next(); + IGraphicsNode shape = adapter.getNode(s); + if (shape != null) + l.add(shape); + + } + return l; + } + + /** + * Return selected objects + *

+ * May contain objects that are NOT in this view + *

+ * + * @return + */ + public List getSelectedResources() { + List l = new ArrayList(); + Iterator i = selection.iterator(); + while (i.hasNext()) { + Resource s = (Resource) i.next(); + l.add(s); + + } + return l; + } + + private ArrayList processed = new ArrayList(); + + private class ExtTrianglePickResults extends TrianglePickResults { + public ExtTrianglePickResults() { + this.setCheckDistance(true); + } + + public void processPick() { + processed.clear(); + if (getNumber() > 0) { + for (int j = 0; j < getNumber(); j++) { + PickData pData = getPickData(j); + ArrayList tris = pData.getTargetTris(); + if (tris != null && tris.size() > 0) { + processed.add(pData); + } + } + + } + + } + } + + private PickResults result = new ExtTrianglePickResults(); + + + private void pickPrefix(String prefix) { + + ArrayList r= new ArrayList(); + for (int i = 0; i < processed.size(); i++) { + PickData pData = processed.get(i); + if (pData.getTargetMesh().getParentGeom().getName().startsWith(prefix)) + r.add(pData); + } + processed = r; + } + + /** + * Updates highlighted objects according to mouse position. + * + * @param mouseRay + */ + public void updateHighlights(Ray mouseRay) { + result.clear(); + adapter.getRenderingComponent().getRoot().calculatePick(mouseRay, result); + if (currentGizmo != null) { + pickPrefix(currentGizmo.getPickPrefix()); + } + doHighlightPick(processed); + } + + /** + * Picks highlighted objects + */ + public void pickHighlighted() { + doPick(processed); + } + + /** + * Processes pick. + * @param result + */ + protected void doPick(ArrayList result) { + if (result != null) { + + if (result.size() == 0) { + if (mouseClickType != SelectionType.MODIFY) + updateSelection(new StructuredResourceSelection()); + return; + } + + String nodeName = result.get(0).getTargetMesh().getParentGeom().getName(); + + StructuredResourceSelection s = new StructuredResourceSelection(); + + Resource selectedResource = adapter.getNodeResource(nodeName); + if (adapter.getNode(selectedResource) == null) { + updateSelection(new StructuredResourceSelection()); + return; + //throw new RuntimeException("Picked resource that has no node ?!"); + } + if (mouseClickType == SelectionType.MODIFY) { + ArrayList selected = new ArrayList(getSelectedResources()); + if (selected.contains(selectedResource)) + selected.remove(selectedResource); + else + selected.add(selectedResource); + for (Resource r : selected) + s.add(r); + + } else { + s.add(selectedResource); + } + + updateSelection(s); + } else { + // System.out.println("Picked nothing"); + if (mouseClickType != SelectionType.MODIFY) + updateSelection(new StructuredResourceSelection()); + } + } + + /** + * Processes highlight pick + * @param result + */ + protected void doHighlightPick(ArrayList result) { + if (result != null) { + + if (result.size() == 0) { + updateGizmo(null); + //System.out.println("IPicked nothing"); + updateHighlightSelection(new StructuredResourceSelection()); + return; + } + + String nodeName = result.get(0).getTargetMesh().getParentGeom().getName(); + + updateGizmo(null); + + // System.out.println("hits: " + result); + StructuredResourceSelection s = new StructuredResourceSelection(); + + Resource selectedResource = adapter.getNodeResource(nodeName); + + if (selectedResource == null) { + if (currentGizmo != null && nodeName.startsWith(currentGizmo.getPickPrefix())) { + updateGizmo(nodeName); + } + return; + } + + if (adapter.getNode(selectedResource) != null) + s.add(selectedResource); + + updateHighlightSelection(s); + } else { + updateGizmo(null); + // System.out.println("IPicked nothing"); + updateHighlightSelection(new StructuredResourceSelection()); + } + } + + /** + * Updates gizmo according to picked object + * @param pickName + */ + private void updateGizmo(String pickName) { + if (currentGizmo != null) { + currentGizmo.setSelected(pickName); + if (currentGizmo.isChanged()) { + adapter.setChanged(true); + currentGizmo.setChanged(false); + } + } + } + + + /** + * Contains selection + */ + protected StructuredResourceSelection selection = new StructuredResourceSelection(); + + protected StructuredResourceSelection interactiveSelection = new StructuredResourceSelection(); + + public StructuredResourceSelection getCurrentSelection() { + return selection; + } + + public void setCurrentSelection(StructuredResourceSelection s) { + selection = s; + } + + public StructuredResourceSelection getHighlightSelection() { + return interactiveSelection; + } + + protected void setHighlightSelection(StructuredResourceSelection s) { + interactiveSelection = s; + } + + private ArrayList selectionChangedListeners = new ArrayList(); + + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) + */ + public void addSelectionChangedListener(ISelectionChangedListener listener) { + selectionChangedListeners.add(listener); + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection() + */ + public ISelection getSelection() { + return selection; + } + + + + public static StructuredResourceSelection transformSelection(ISelection sel) { + if (sel instanceof StructuredResourceSelection) + return (StructuredResourceSelection)sel; + StructuredResourceSelection res = new StructuredResourceSelection(); + Resource resources[] = ResourceAdaptionUtils.toResources(sel); + for (Resource r : resources) + res.add(r); + return res; + } + + + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) + */ + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + selectionChangedListeners.remove(listener); + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection) + */ + public void setSelection(ISelection selection) { + // System.out.println(); + StructuredResourceSelection s = filterSelection(selection); + if (this.selection.equals(s)) + return; + this.selection = s; + adapter.setChanged(true); + setEditorSelection(); + + } + + /** + * Filters selection given with setSelection(ISelection selection) This + * allows impemented editors to modify selection before it's applied into + * this editor + * + * @param s + * @return the filtered selection + */ + protected StructuredResourceSelection filterSelection(ISelection s) { + if (!(selection instanceof StructuredResourceSelection)) + return new StructuredResourceSelection(); + return (StructuredResourceSelection) selection; + } + + /** + * Updates visual part of selection event. Use getCurrentSelection() to get + * the selection + */ + public abstract void setEditorSelection(); + + /** + * Updates visual part of selection event. Use getInteractiveSelection() to + * get the selection + */ + protected abstract void setEditorHighlightSelection(); + + /** + * Editor's internal selection update
+ * Sends events to other editors and views about changed selection + * + * @param selection + * @return + */ + public boolean updateSelection(StructuredResourceSelection s) { + if (this.selection.equals(s)) + return false; + + this.selection = s; + adapter.setChanged(true); + fireSelectionChangedEvent(); + setEditorSelection(); + return true; + } + + protected boolean updateHighlightSelection(StructuredResourceSelection s) { + if (interactiveSelection.equals(s)) + return false; + this.interactiveSelection = s; + adapter.setChanged(true); + setEditorHighlightSelection(); + return true; + } + + /** + * Fires selection changed events. + */ + protected void fireSelectionChangedEvent() { + SelectionChangedEvent e = new SelectionChangedEvent(this, this.selection); + for (ISelectionChangedListener l : selectionChangedListeners) + l.selectionChanged(e); + } +}