]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d/src/org/simantics/g3d/ui/ScenegraphOutlinePage.java
71e1c6839ef788517866db82dad80bbcbaa0ad71
[simantics/3d.git] / org.simantics.g3d / src / org / simantics / g3d / ui / ScenegraphOutlinePage.java
1 package org.simantics.g3d.ui;\r
2 \r
3 import java.util.HashSet;\r
4 import java.util.Set;\r
5 \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
16 \r
17 public class ScenegraphOutlinePage extends ContentOutlinePage implements NodeListener {\r
18         \r
19         private ParentNode<? extends INode> rootNode;\r
20         \r
21         public ScenegraphOutlinePage(ParentNode<? extends INode> rootNode) {\r
22                 if (rootNode == null)\r
23                         throw new NullPointerException();\r
24                 this.rootNode = rootNode;\r
25         }\r
26 \r
27         \r
28         @Override\r
29         public void createControl(Composite parent) {\r
30                 super.createControl(parent);\r
31                 if (rootNode == null)\r
32                         return;\r
33                 TreeViewer viewer = getTreeViewer();\r
34                 createProviders(viewer);\r
35                 viewer.setInput(rootNode);\r
36                 listen(rootNode);\r
37         }\r
38         \r
39         protected void createProviders(TreeViewer viewer) {\r
40                 viewer.setContentProvider(new ScenegraphContentProvider());\r
41                 viewer.setLabelProvider(new ScenegraphLabelProvider());\r
42         }\r
43         \r
44         \r
45         \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
52                                 listen(n);\r
53                 }\r
54         }\r
55         \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
62                                 stopListening(n);\r
63                 }\r
64         }\r
65         \r
66         @Override\r
67         public void propertyChanged(INode node, String id) {\r
68                 refershViewer(node);\r
69         }\r
70         \r
71         @Override\r
72         public <T extends INode> void nodeAdded(ParentNode<T> node, INode child,\r
73                         String rel) {\r
74                 listen(child);\r
75                 refershViewer(node);\r
76         }\r
77         \r
78         \r
79         \r
80         @Override\r
81         public <T extends INode> void nodeRemoved(ParentNode<T> node, INode child,\r
82                         String rel) {\r
83                 stopListening(child);\r
84                 refershViewer(node);\r
85         }\r
86         \r
87         //private Queue<INode> toRefresh = new LinkedList<INode>();\r
88         private Set<INode> toRefresh = new HashSet<INode>();\r
89         private NodeUpdater updater;\r
90         \r
91         protected void refershViewer(final INode node) {\r
92                 if (getTreeViewer() == null)\r
93                         return;\r
94                 synchronized (toRefresh) {\r
95                         toRefresh.add(node);\r
96                         if (updater != null)\r
97                                 return;\r
98                 }\r
99                 \r
100                 updater = new NodeUpdater();\r
101                 Display.getDefault().asyncExec(updater);\r
102         }\r
103         \r
104         private class NodeUpdater implements Runnable {\r
105                 @Override\r
106                 public void run() {\r
107                         if (getTreeViewer().getTree().isDisposed()) {\r
108                                 updater =null;\r
109                                 return;\r
110                         }\r
111                         int count = 0;\r
112                         // limit the amount of refreshes.\r
113                         while (count < 100) {\r
114                                 INode node = null;\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
120 //                                              updater = null;\r
121 //                                              return;\r
122 //                                      }\r
123                                         \r
124                                         //node = toRefresh.poll();\r
125                                         if (toRefresh.size() > 0) {\r
126                                                 node = toRefresh.iterator().next();\r
127                                                 toRefresh.remove(node);\r
128                                         }\r
129                                         if (node == null) {\r
130                                                 updater = null;\r
131                                                 return;\r
132                                         }\r
133                                 }\r
134                                 getTreeViewer().refresh(node);\r
135                                 count++;\r
136                         }\r
137                         if (toRefresh.size() > 0) {\r
138                                 Display.getDefault().asyncExec(this);\r
139                         }\r
140                 }\r
141         }\r
142         \r
143         public static class ScenegraphContentProvider implements ITreeContentProvider {\r
144                 \r
145                 public ScenegraphContentProvider() {\r
146                         \r
147                 }\r
148                 \r
149                 @Override\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
154                         }\r
155                         return new Object[0];\r
156                 }\r
157                 \r
158                 @Override\r
159                 public Object[] getElements(Object inputElement) {\r
160                         return getChildren(inputElement);\r
161                 }\r
162                 \r
163                 @Override\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
168                         }\r
169                         return null;\r
170                 }\r
171                 \r
172                 @Override\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
177                         }\r
178                         return false;\r
179                 }\r
180                 \r
181                 @Override\r
182                 public void dispose() {\r
183                         \r
184                 }\r
185                 \r
186                 @Override\r
187                 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
188                         \r
189                 }\r
190         }\r
191         \r
192         public class ScenegraphLabelProvider extends LabelProvider {\r
193                 \r
194         }\r
195 }\r