1 package org.simantics.g3d.ui;
\r
3 import java.util.HashSet;
\r
4 import java.util.Set;
\r
6 import org.eclipse.jface.viewers.ITreeContentProvider;
\r
7 import org.eclipse.jface.viewers.LabelProvider;
\r
8 import org.eclipse.jface.viewers.TreeViewer;
\r
9 import org.eclipse.jface.viewers.Viewer;
\r
10 import org.eclipse.swt.widgets.Composite;
\r
11 import org.eclipse.swt.widgets.Display;
\r
12 import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
\r
13 import org.simantics.g3d.scenegraph.base.INode;
\r
14 import org.simantics.g3d.scenegraph.base.NodeListener;
\r
15 import org.simantics.g3d.scenegraph.base.ParentNode;
\r
17 public class ScenegraphOutlinePage extends ContentOutlinePage implements NodeListener {
\r
19 private ParentNode<? extends INode> rootNode;
\r
21 public ScenegraphOutlinePage(ParentNode<? extends INode> rootNode) {
\r
22 if (rootNode == null)
\r
23 throw new NullPointerException();
\r
24 this.rootNode = rootNode;
\r
29 public void createControl(Composite parent) {
\r
30 super.createControl(parent);
\r
31 if (rootNode == null)
\r
33 TreeViewer viewer = getTreeViewer();
\r
34 createProviders(viewer);
\r
35 viewer.setInput(rootNode);
\r
39 protected void createProviders(TreeViewer viewer) {
\r
40 viewer.setContentProvider(new ScenegraphContentProvider());
\r
41 viewer.setLabelProvider(new ScenegraphLabelProvider());
\r
46 @SuppressWarnings("unchecked")
\r
47 protected void listen(INode node) {
\r
48 node.addListener(this);
\r
49 if (node instanceof ParentNode<?>) {
\r
50 ParentNode<INode> parentNode = (ParentNode<INode>)node;
\r
51 for (INode n : parentNode.getNodes())
\r
56 @SuppressWarnings("unchecked")
\r
57 protected void stopListening(INode node) {
\r
58 node.removeListener(this);
\r
59 if (node instanceof ParentNode<?>) {
\r
60 ParentNode<INode> parentNode = (ParentNode<INode>)node;
\r
61 for (INode n : parentNode.getNodes())
\r
67 public void propertyChanged(INode node, String id) {
\r
68 refershViewer(node);
\r
72 public <T extends INode> void nodeAdded(ParentNode<T> node, INode child,
\r
75 refershViewer(node);
\r
81 public <T extends INode> void nodeRemoved(ParentNode<T> node, INode child,
\r
83 stopListening(child);
\r
84 refershViewer(node);
\r
87 //private Queue<INode> toRefresh = new LinkedList<INode>();
\r
88 private Set<INode> toRefresh = new HashSet<INode>();
\r
89 private NodeUpdater updater;
\r
91 protected void refershViewer(final INode node) {
\r
92 if (getTreeViewer() == null)
\r
94 synchronized (toRefresh) {
\r
95 toRefresh.add(node);
\r
96 if (updater != null)
\r
100 updater = new NodeUpdater();
\r
101 Display.getDefault().asyncExec(updater);
\r
104 private class NodeUpdater implements Runnable {
\r
106 public void run() {
\r
107 if (getTreeViewer().getTree().isDisposed()) {
\r
112 // limit the amount of refreshes.
\r
113 while (count < 100) {
\r
115 synchronized (toRefresh) {
\r
116 // if the queue becomes too long, refresh the whole tree
\r
117 // if (toRefresh.size() > 100) {
\r
118 // toRefresh.clear();
\r
119 // getTreeViewer().refresh();
\r
124 //node = toRefresh.poll();
\r
125 if (toRefresh.size() > 0) {
\r
126 node = toRefresh.iterator().next();
\r
127 toRefresh.remove(node);
\r
129 if (node == null) {
\r
134 getTreeViewer().refresh(node);
\r
137 if (toRefresh.size() > 0) {
\r
138 Display.getDefault().asyncExec(this);
\r
143 public static class ScenegraphContentProvider implements ITreeContentProvider {
\r
145 public ScenegraphContentProvider() {
\r
150 public Object[] getChildren(Object parentElement) {
\r
151 if (parentElement instanceof ParentNode<?>) {
\r
152 ParentNode<?> parentNode = (ParentNode<?>)parentElement;
\r
153 return parentNode.getNodes().toArray();
\r
155 return new Object[0];
\r
159 public Object[] getElements(Object inputElement) {
\r
160 return getChildren(inputElement);
\r
164 public Object getParent(Object element) {
\r
165 if (element instanceof INode) {
\r
166 INode node = (INode) element;
\r
167 return node.getParent();
\r
173 public boolean hasChildren(Object element) {
\r
174 if (element instanceof ParentNode<?>) {
\r
175 ParentNode<?> parentNode = (ParentNode<?>)element;
\r
176 return parentNode.getNodes().size() > 0;
\r
182 public void dispose() {
\r
187 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
\r
192 public class ScenegraphLabelProvider extends LabelProvider {
\r