]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.g3d/src/org/simantics/proconf/g3d/base/SelectionAdapter.java
git-svn-id: https://www.simantics.org/svn/simantics/3d/trunk@22280 ac1ea38d-2e2b...
[simantics/3d.git] / org.simantics.g3d / src / org / simantics / proconf / g3d / base / SelectionAdapter.java
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 (file)
index 0000000..2b0b480
--- /dev/null
@@ -0,0 +1,451 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007- VTT Technical Research Centre of Finland.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.base;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.ISelectionChangedListener;\r
+import org.eclipse.jface.viewers.ISelectionProvider;\r
+import org.eclipse.jface.viewers.SelectionChangedEvent;\r
+import org.simantics.proconf.g3d.common.StructuredResourceSelection;\r
+import org.simantics.proconf.g3d.gizmo.Gizmo;\r
+import org.simantics.proconf.g3d.scenegraph.IGraphicsNode;\r
+import org.simantics.proconf.ui.utils.ResourceAdaptionUtils;\r
+\r
+import com.jme.intersection.PickData;\r
+import com.jme.intersection.PickResults;\r
+import com.jme.intersection.TrianglePickResults;\r
+import com.jme.math.Ray;\r
+\r
+import org.simantics.db.Resource;\r
+\r
+/**\r
+ * Manages highlighting and selecting of objects.\r
+ * \r
+ * @author Marko Luukkainen\r
+ *\r
+ */\r
+public abstract class SelectionAdapter implements ISelectionProvider{\r
+       \r
+       protected ScenegraphAdapter adapter;\r
+       \r
+       private Gizmo currentGizmo = null;\r
+       \r
+       public SelectionAdapter(ScenegraphAdapter adapter) {\r
+               if (adapter == null)\r
+                       throw new NullPointerException("Scenegraph adapter must no be null");\r
+               this.adapter = adapter;\r
+       }\r
+       \r
+    public enum SelectionType {\r
+        SET, MODIFY\r
+    };\r
+\r
+    protected SelectionType mouseClickType = SelectionType.SET;\r
+    \r
+    public SelectionType getSelectionType() {\r
+       return mouseClickType;\r
+    }\r
+    \r
+    public void setSelectionType(SelectionType type) {\r
+       mouseClickType = type;\r
+    }\r
+    \r
+    public void setCurrentGizmo(Gizmo gizmo) {\r
+       currentGizmo = gizmo;\r
+    }\r
+    \r
+    /**\r
+     * Lists all selected objects\r
+     * <p>\r
+     * Selection may contain objects that are not in this view: those are NOT\r
+     * returned\r
+     * </p>\r
+     * \r
+     * @return\r
+     */\r
+    public List<IGraphicsNode> getSelectedObjects() {\r
+        return getSelectedObjects(selection);\r
+    }\r
+    \r
+    /**\r
+     * Lists all highlighted objects.\r
+     * <p>\r
+     * Typically there may be only one highlighted object.\r
+     * </p>\r
+     * @return\r
+     */\r
+    public List<IGraphicsNode> getHighlightedObjects() {\r
+        return getSelectedObjects(interactiveSelection);\r
+    }\r
+\r
+    /**\r
+     * Lists all selected objects\r
+     * <p>\r
+     * Selection may contain objects that are not in this view: those are NOT\r
+     * returned\r
+     * </p>\r
+     * \r
+     * @return\r
+     */\r
+    public List<IGraphicsNode> getInteractiveSelectedObjects() {\r
+        return getSelectedObjects(interactiveSelection);\r
+    }\r
+\r
+    /**\r
+     * Lists all selected objects\r
+     * <p>\r
+     * Selection may contain objects that are not in this view: those are NOT\r
+     * returned\r
+     * </p>\r
+     * \r
+     * @return\r
+     */\r
+    protected List<IGraphicsNode> getSelectedObjects(StructuredResourceSelection selection) {\r
+        List<IGraphicsNode> l = new ArrayList<IGraphicsNode>();\r
+        Iterator<Resource> i = selection.iterator();\r
+        while (i.hasNext()) {\r
+            Resource s = i.next();\r
+            IGraphicsNode shape = adapter.getNode(s);\r
+            if (shape != null)\r
+                l.add(shape);\r
+\r
+        }\r
+        return l;\r
+    }\r
+\r
+    /**\r
+     * Return selected objects\r
+     * <p>\r
+     * May contain objects that are NOT in this view\r
+     * </p>\r
+     * \r
+     * @return\r
+     */\r
+    public List<Resource> getSelectedResources() {\r
+        List<Resource> l = new ArrayList<Resource>();\r
+        Iterator<Resource> i = selection.iterator();\r
+        while (i.hasNext()) {\r
+            Resource s = (Resource) i.next();\r
+            l.add(s);\r
+\r
+        }\r
+        return l;\r
+    }\r
+    \r
+    private ArrayList<PickData> processed = new ArrayList<PickData>();\r
+    \r
+    private class ExtTrianglePickResults extends TrianglePickResults {\r
+       public ExtTrianglePickResults() {\r
+               this.setCheckDistance(true);\r
+        }\r
+       \r
+       public void processPick() {\r
+                       processed.clear();\r
+                       if (getNumber() > 0) {\r
+                               for (int j = 0; j < getNumber(); j++) {\r
+                                       PickData pData = getPickData(j);\r
+                                       ArrayList<Integer> tris = pData.getTargetTris();\r
+                                       if (tris != null && tris.size() > 0) {\r
+                                               processed.add(pData);\r
+                                       }\r
+                               }\r
+                               \r
+                       }\r
+                       \r
+               }\r
+    }\r
+    \r
+    private PickResults result = new ExtTrianglePickResults();\r
+\r
+       \r
+       private void pickPrefix(String prefix) {\r
+\r
+               ArrayList<PickData> r= new ArrayList<PickData>();\r
+               for (int i = 0; i < processed.size(); i++) {\r
+                       PickData pData = processed.get(i);\r
+                       if (pData.getTargetMesh().getParentGeom().getName().startsWith(prefix))\r
+                               r.add(pData);\r
+               }\r
+               processed = r;\r
+       }\r
+       \r
+       /**\r
+        * Updates highlighted objects according to mouse position.\r
+        * \r
+        * @param mouseRay\r
+        */\r
+       public void updateHighlights(Ray mouseRay) {\r
+               result.clear();\r
+               adapter.getRenderingComponent().getRoot().calculatePick(mouseRay, result);\r
+               if (currentGizmo != null) {\r
+                       pickPrefix(currentGizmo.getPickPrefix());\r
+               }\r
+               doHighlightPick(processed);\r
+       }\r
+       \r
+       /**\r
+        * Picks highlighted objects\r
+        */\r
+       public void pickHighlighted() {\r
+               doPick(processed);\r
+       }\r
+       \r
+    /**\r
+     * Processes pick.\r
+     * @param result\r
+     */\r
+    protected void doPick(ArrayList<PickData> result) {\r
+        if (result != null) {\r
+\r
+               if (result.size() == 0) {\r
+                       if (mouseClickType != SelectionType.MODIFY)\r
+                    updateSelection(new StructuredResourceSelection());\r
+                       return;\r
+               }\r
+               \r
+               String nodeName = result.get(0).getTargetMesh().getParentGeom().getName();\r
+\r
+            StructuredResourceSelection s = new StructuredResourceSelection();\r
+            \r
+            Resource selectedResource = adapter.getNodeResource(nodeName);\r
+            if (adapter.getNode(selectedResource) == null) {\r
+                updateSelection(new StructuredResourceSelection());\r
+                return;\r
+                //throw new RuntimeException("Picked resource that has no node ?!");\r
+            }\r
+            if (mouseClickType == SelectionType.MODIFY) {\r
+                ArrayList<Resource> selected = new ArrayList<Resource>(getSelectedResources());\r
+                if (selected.contains(selectedResource))\r
+                    selected.remove(selectedResource);\r
+                else\r
+                    selected.add(selectedResource);\r
+                for (Resource r : selected)\r
+                    s.add(r);\r
+\r
+            } else {\r
+                s.add(selectedResource);\r
+            }\r
+\r
+            updateSelection(s);\r
+        } else {\r
+            // System.out.println("Picked nothing");\r
+            if (mouseClickType != SelectionType.MODIFY)\r
+                updateSelection(new StructuredResourceSelection());\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Processes highlight pick\r
+     * @param result\r
+     */\r
+    protected void doHighlightPick(ArrayList<PickData> result) {\r
+        if (result != null) {\r
+\r
+               if (result.size() == 0) {\r
+                       updateGizmo(null);\r
+                //System.out.println("IPicked nothing");\r
+                updateHighlightSelection(new StructuredResourceSelection());\r
+                       return;\r
+               }\r
+               \r
+               String nodeName = result.get(0).getTargetMesh().getParentGeom().getName();\r
+        \r
+            updateGizmo(null);\r
+            \r
+            // System.out.println("hits: " + result);\r
+            StructuredResourceSelection s = new StructuredResourceSelection();\r
+                      \r
+            Resource selectedResource = adapter.getNodeResource(nodeName);\r
+            \r
+            if (selectedResource == null) {\r
+               if (currentGizmo != null && nodeName.startsWith(currentGizmo.getPickPrefix())) {\r
+                    updateGizmo(nodeName);\r
+                } \r
+               return;\r
+            }\r
+            \r
+            if (adapter.getNode(selectedResource) != null)\r
+                s.add(selectedResource);\r
+\r
+            updateHighlightSelection(s);\r
+        } else {\r
+            updateGizmo(null);\r
+            // System.out.println("IPicked nothing");\r
+            updateHighlightSelection(new StructuredResourceSelection());\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Updates gizmo according to picked object\r
+     * @param pickName\r
+     */\r
+    private void updateGizmo(String pickName) {\r
+        if (currentGizmo != null) {\r
+            currentGizmo.setSelected(pickName);\r
+            if (currentGizmo.isChanged()) {\r
+               adapter.setChanged(true);\r
+                currentGizmo.setChanged(false);\r
+            }\r
+        }\r
+    }\r
+    \r
+    \r
+    /**\r
+     * Contains selection\r
+     */\r
+    protected StructuredResourceSelection selection = new StructuredResourceSelection();\r
+\r
+    protected StructuredResourceSelection interactiveSelection = new StructuredResourceSelection();\r
+    \r
+    public StructuredResourceSelection getCurrentSelection() {\r
+        return selection;\r
+    }\r
+\r
+    public void setCurrentSelection(StructuredResourceSelection s) {\r
+        selection = s;\r
+    }\r
+\r
+    public StructuredResourceSelection getHighlightSelection() {\r
+        return interactiveSelection;\r
+    }\r
+\r
+    protected void setHighlightSelection(StructuredResourceSelection s) {\r
+        interactiveSelection = s;\r
+    }\r
+    \r
+    private ArrayList<ISelectionChangedListener> selectionChangedListeners = new ArrayList<ISelectionChangedListener>();\r
+\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)\r
+     */\r
+    public void addSelectionChangedListener(ISelectionChangedListener listener) {\r
+        selectionChangedListeners.add(listener);\r
+\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()\r
+     */\r
+    public ISelection getSelection() {\r
+        return selection;\r
+    }\r
+\r
+    \r
+    \r
+    public static StructuredResourceSelection transformSelection(ISelection sel) {\r
+       if (sel instanceof StructuredResourceSelection)\r
+               return (StructuredResourceSelection)sel;\r
+       StructuredResourceSelection res = new StructuredResourceSelection();\r
+       Resource resources[] = ResourceAdaptionUtils.toResources(sel);\r
+       for (Resource r : resources)\r
+               res.add(r);\r
+       return res;\r
+    }\r
+    \r
+\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)\r
+     */\r
+    public void removeSelectionChangedListener(ISelectionChangedListener listener) {\r
+        selectionChangedListeners.remove(listener);\r
+\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection)\r
+     */\r
+    public void setSelection(ISelection selection) {\r
+        // System.out.println();\r
+        StructuredResourceSelection s = filterSelection(selection);\r
+        if (this.selection.equals(s))\r
+            return;\r
+        this.selection = s;\r
+        adapter.setChanged(true);\r
+        setEditorSelection();\r
+\r
+    }\r
+\r
+    /**\r
+     * Filters selection given with setSelection(ISelection selection) This\r
+     * allows impemented editors to modify selection before it's applied into\r
+     * this editor\r
+     * \r
+     * @param s\r
+     * @return the filtered selection\r
+     */\r
+    protected StructuredResourceSelection filterSelection(ISelection s) {\r
+       if (!(selection instanceof StructuredResourceSelection))\r
+                       return new StructuredResourceSelection();\r
+               return (StructuredResourceSelection) selection;\r
+    }\r
+\r
+    /**\r
+     * Updates visual part of selection event. Use getCurrentSelection() to get\r
+     * the selection\r
+     */\r
+    public abstract void setEditorSelection();\r
+\r
+    /**\r
+     * Updates visual part of selection event. Use getInteractiveSelection() to\r
+     * get the selection\r
+     */\r
+    protected abstract void setEditorHighlightSelection();\r
+\r
+    /**\r
+     * Editor's internal selection update<br>\r
+     * Sends events to other editors and views about changed selection\r
+     * \r
+     * @param selection\r
+     * @return\r
+     */\r
+    public boolean updateSelection(StructuredResourceSelection s) {\r
+        if (this.selection.equals(s))\r
+            return false;\r
+\r
+        this.selection = s;\r
+        adapter.setChanged(true);\r
+        fireSelectionChangedEvent();\r
+        setEditorSelection();\r
+        return true;\r
+    }\r
+\r
+    protected boolean updateHighlightSelection(StructuredResourceSelection s) {\r
+        if (interactiveSelection.equals(s))\r
+            return false;\r
+        this.interactiveSelection = s;\r
+        adapter.setChanged(true);\r
+        setEditorHighlightSelection();\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * Fires selection changed events.\r
+     */\r
+    protected void fireSelectionChangedEvent() {\r
+        SelectionChangedEvent e = new SelectionChangedEvent(this, this.selection);\r
+        for (ISelectionChangedListener l : selectionChangedListeners)\r
+            l.selectionChanged(e);\r
+    }\r
+}\r