]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.g3d/src/org/simantics/g3d/ui/ScenegraphOutlinePage.java
3D framework (Simca 2012)
[simantics/3d.git] / org.simantics.g3d / src / org / simantics / g3d / ui / ScenegraphOutlinePage.java
diff --git a/org.simantics.g3d/src/org/simantics/g3d/ui/ScenegraphOutlinePage.java b/org.simantics.g3d/src/org/simantics/g3d/ui/ScenegraphOutlinePage.java
new file mode 100644 (file)
index 0000000..71e1c68
--- /dev/null
@@ -0,0 +1,195 @@
+package org.simantics.g3d.ui;\r
+\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.eclipse.jface.viewers.ITreeContentProvider;\r
+import org.eclipse.jface.viewers.LabelProvider;\r
+import org.eclipse.jface.viewers.TreeViewer;\r
+import org.eclipse.jface.viewers.Viewer;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.ui.views.contentoutline.ContentOutlinePage;\r
+import org.simantics.g3d.scenegraph.base.INode;\r
+import org.simantics.g3d.scenegraph.base.NodeListener;\r
+import org.simantics.g3d.scenegraph.base.ParentNode;\r
+\r
+public class ScenegraphOutlinePage extends ContentOutlinePage implements NodeListener {\r
+       \r
+       private ParentNode<? extends INode> rootNode;\r
+       \r
+       public ScenegraphOutlinePage(ParentNode<? extends INode> rootNode) {\r
+               if (rootNode == null)\r
+                       throw new NullPointerException();\r
+               this.rootNode = rootNode;\r
+       }\r
+\r
+       \r
+       @Override\r
+       public void createControl(Composite parent) {\r
+               super.createControl(parent);\r
+               if (rootNode == null)\r
+                       return;\r
+               TreeViewer viewer = getTreeViewer();\r
+               createProviders(viewer);\r
+               viewer.setInput(rootNode);\r
+               listen(rootNode);\r
+       }\r
+       \r
+       protected void createProviders(TreeViewer viewer) {\r
+               viewer.setContentProvider(new ScenegraphContentProvider());\r
+               viewer.setLabelProvider(new ScenegraphLabelProvider());\r
+       }\r
+       \r
+       \r
+       \r
+       @SuppressWarnings("unchecked")\r
+       protected void listen(INode node) {\r
+               node.addListener(this);\r
+               if (node instanceof ParentNode<?>) {\r
+                       ParentNode<INode> parentNode = (ParentNode<INode>)node;\r
+                       for (INode n : parentNode.getNodes())\r
+                               listen(n);\r
+               }\r
+       }\r
+       \r
+       @SuppressWarnings("unchecked")\r
+       protected void stopListening(INode node) {\r
+               node.removeListener(this);\r
+               if (node instanceof ParentNode<?>) {\r
+                       ParentNode<INode> parentNode = (ParentNode<INode>)node;\r
+                       for (INode n : parentNode.getNodes())\r
+                               stopListening(n);\r
+               }\r
+       }\r
+       \r
+       @Override\r
+       public void propertyChanged(INode node, String id) {\r
+               refershViewer(node);\r
+       }\r
+       \r
+       @Override\r
+       public <T extends INode> void nodeAdded(ParentNode<T> node, INode child,\r
+                       String rel) {\r
+               listen(child);\r
+               refershViewer(node);\r
+       }\r
+       \r
+       \r
+       \r
+       @Override\r
+       public <T extends INode> void nodeRemoved(ParentNode<T> node, INode child,\r
+                       String rel) {\r
+               stopListening(child);\r
+               refershViewer(node);\r
+       }\r
+       \r
+       //private Queue<INode> toRefresh = new LinkedList<INode>();\r
+       private Set<INode> toRefresh = new HashSet<INode>();\r
+       private NodeUpdater updater;\r
+       \r
+       protected void refershViewer(final INode node) {\r
+               if (getTreeViewer() == null)\r
+                       return;\r
+               synchronized (toRefresh) {\r
+                       toRefresh.add(node);\r
+                       if (updater != null)\r
+                               return;\r
+               }\r
+               \r
+               updater = new NodeUpdater();\r
+               Display.getDefault().asyncExec(updater);\r
+       }\r
+       \r
+       private class NodeUpdater implements Runnable {\r
+               @Override\r
+               public void run() {\r
+                       if (getTreeViewer().getTree().isDisposed()) {\r
+                               updater =null;\r
+                               return;\r
+                       }\r
+                       int count = 0;\r
+                       // limit the amount of refreshes.\r
+                       while (count < 100) {\r
+                               INode node = null;\r
+                               synchronized (toRefresh) {\r
+                                       // if the queue becomes too long, refresh the whole tree\r
+//                                     if (toRefresh.size() > 100) {\r
+//                                             toRefresh.clear();\r
+//                                             getTreeViewer().refresh();\r
+//                                             updater = null;\r
+//                                             return;\r
+//                                     }\r
+                                       \r
+                                       //node = toRefresh.poll();\r
+                                       if (toRefresh.size() > 0) {\r
+                                               node = toRefresh.iterator().next();\r
+                                               toRefresh.remove(node);\r
+                                       }\r
+                                       if (node == null) {\r
+                                               updater = null;\r
+                                               return;\r
+                                       }\r
+                               }\r
+                               getTreeViewer().refresh(node);\r
+                               count++;\r
+                       }\r
+                       if (toRefresh.size() > 0) {\r
+                               Display.getDefault().asyncExec(this);\r
+                       }\r
+               }\r
+       }\r
+       \r
+       public static class ScenegraphContentProvider implements ITreeContentProvider {\r
+               \r
+               public ScenegraphContentProvider() {\r
+                       \r
+               }\r
+               \r
+               @Override\r
+               public Object[] getChildren(Object parentElement) {\r
+                       if (parentElement instanceof ParentNode<?>) {\r
+                               ParentNode<?> parentNode = (ParentNode<?>)parentElement;\r
+                               return parentNode.getNodes().toArray();\r
+                       }\r
+                       return new Object[0];\r
+               }\r
+               \r
+               @Override\r
+               public Object[] getElements(Object inputElement) {\r
+                       return getChildren(inputElement);\r
+               }\r
+               \r
+               @Override\r
+               public Object getParent(Object element) {\r
+                       if (element instanceof INode) {\r
+                               INode node = (INode) element;\r
+                               return node.getParent();\r
+                       }\r
+                       return null;\r
+               }\r
+               \r
+               @Override\r
+               public boolean hasChildren(Object element) {\r
+                       if (element instanceof ParentNode<?>) {\r
+                               ParentNode<?> parentNode = (ParentNode<?>)element;\r
+                               return parentNode.getNodes().size() > 0;\r
+                       }\r
+                       return false;\r
+               }\r
+               \r
+               @Override\r
+               public void dispose() {\r
+                       \r
+               }\r
+               \r
+               @Override\r
+               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
+                       \r
+               }\r
+       }\r
+       \r
+       public class ScenegraphLabelProvider extends LabelProvider {\r
+               \r
+       }\r
+}\r