]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d/src/org/simantics/g3d/ui/ScenegraphOutlinePage.java
Reflection-based handling of Enum property editing.
[simantics/3d.git] / org.simantics.g3d / src / org / simantics / g3d / ui / ScenegraphOutlinePage.java
1 /*******************************************************************************\r
2  * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.g3d.ui;\r
13 \r
14 import java.util.HashSet;\r
15 import java.util.Set;\r
16 \r
17 import org.eclipse.jface.viewers.ITreeContentProvider;\r
18 import org.eclipse.jface.viewers.LabelProvider;\r
19 import org.eclipse.jface.viewers.TreeViewer;\r
20 import org.eclipse.jface.viewers.Viewer;\r
21 import org.eclipse.swt.widgets.Composite;\r
22 import org.eclipse.swt.widgets.Display;\r
23 import org.eclipse.ui.views.contentoutline.ContentOutlinePage;\r
24 import org.simantics.g3d.scenegraph.base.INode;\r
25 import org.simantics.g3d.scenegraph.base.NodeListener;\r
26 import org.simantics.g3d.scenegraph.base.ParentNode;\r
27 \r
28 public class ScenegraphOutlinePage extends ContentOutlinePage implements NodeListener {\r
29         \r
30         private ParentNode<? extends INode> rootNode;\r
31         \r
32         public ScenegraphOutlinePage(ParentNode<? extends INode> rootNode) {\r
33                 if (rootNode == null)\r
34                         throw new NullPointerException();\r
35                 this.rootNode = rootNode;\r
36         }\r
37 \r
38         \r
39         @Override\r
40         public void createControl(Composite parent) {\r
41                 super.createControl(parent);\r
42                 if (rootNode == null)\r
43                         return;\r
44                 TreeViewer viewer = getTreeViewer();\r
45                 createProviders(viewer);\r
46                 viewer.setInput(rootNode);\r
47                 listen(rootNode);\r
48         }\r
49         \r
50         protected void createProviders(TreeViewer viewer) {\r
51                 viewer.setContentProvider(new ScenegraphContentProvider());\r
52                 viewer.setLabelProvider(new ScenegraphLabelProvider());\r
53         }\r
54         \r
55         \r
56         \r
57         @SuppressWarnings("unchecked")\r
58         protected void listen(INode node) {\r
59                 node.addListener(this);\r
60                 if (node instanceof ParentNode<?>) {\r
61                         ParentNode<INode> parentNode = (ParentNode<INode>)node;\r
62                         for (INode n : parentNode.getNodes())\r
63                                 listen(n);\r
64                 }\r
65         }\r
66         \r
67         @SuppressWarnings("unchecked")\r
68         protected void stopListening(INode node) {\r
69                 node.removeListener(this);\r
70                 if (node instanceof ParentNode<?>) {\r
71                         ParentNode<INode> parentNode = (ParentNode<INode>)node;\r
72                         for (INode n : parentNode.getNodes())\r
73                                 stopListening(n);\r
74                 }\r
75         }\r
76         \r
77         @Override\r
78         public void propertyChanged(INode node, String id) {\r
79                 refershViewer(node);\r
80         }\r
81         \r
82         @Override\r
83         public <T extends INode> void nodeAdded(ParentNode<T> node, INode child,\r
84                         String rel) {\r
85                 listen(child);\r
86                 refershViewer(node);\r
87         }\r
88         \r
89         \r
90         \r
91         @Override\r
92         public <T extends INode> void nodeRemoved(ParentNode<T> node, INode child,\r
93                         String rel) {\r
94                 stopListening(child);\r
95                 refershViewer(node);\r
96         }\r
97         \r
98         //private Queue<INode> toRefresh = new LinkedList<INode>();\r
99         private Set<INode> toRefresh = new HashSet<INode>();\r
100         private NodeUpdater updater;\r
101         \r
102         protected void refershViewer(final INode node) {\r
103                 if (getTreeViewer() == null)\r
104                         return;\r
105                 synchronized (toRefresh) {\r
106                         toRefresh.add(node);\r
107                         if (updater != null)\r
108                                 return;\r
109                 }\r
110                 \r
111                 updater = new NodeUpdater();\r
112                 Display.getDefault().asyncExec(updater);\r
113         }\r
114         \r
115         private class NodeUpdater implements Runnable {\r
116                 @Override\r
117                 public void run() {\r
118                         if (getTreeViewer().getTree().isDisposed()) {\r
119                                 updater =null;\r
120                                 return;\r
121                         }\r
122                         int count = 0;\r
123                         // limit the amount of refreshes.\r
124                         while (count < 100) {\r
125                                 INode node = null;\r
126                                 synchronized (toRefresh) {\r
127                                         // if the queue becomes too long, refresh the whole tree\r
128 //                                      if (toRefresh.size() > 100) {\r
129 //                                              toRefresh.clear();\r
130 //                                              getTreeViewer().refresh();\r
131 //                                              updater = null;\r
132 //                                              return;\r
133 //                                      }\r
134                                         \r
135                                         //node = toRefresh.poll();\r
136                                         if (toRefresh.size() > 0) {\r
137                                                 node = toRefresh.iterator().next();\r
138                                                 toRefresh.remove(node);\r
139                                         }\r
140                                         if (node == null) {\r
141                                                 updater = null;\r
142                                                 return;\r
143                                         }\r
144                                 }\r
145                                 getTreeViewer().refresh(node);\r
146                                 count++;\r
147                         }\r
148                         if (toRefresh.size() > 0) {\r
149                                 Display.getDefault().asyncExec(this);\r
150                         }\r
151                 }\r
152         }\r
153         \r
154         public static class ScenegraphContentProvider implements ITreeContentProvider {\r
155                 \r
156                 public ScenegraphContentProvider() {\r
157                         \r
158                 }\r
159                 \r
160                 @Override\r
161                 public Object[] getChildren(Object parentElement) {\r
162                         if (parentElement instanceof ParentNode<?>) {\r
163                                 ParentNode<?> parentNode = (ParentNode<?>)parentElement;\r
164                                 return parentNode.getNodes().toArray();\r
165                         }\r
166                         return new Object[0];\r
167                 }\r
168                 \r
169                 @Override\r
170                 public Object[] getElements(Object inputElement) {\r
171                         return getChildren(inputElement);\r
172                 }\r
173                 \r
174                 @Override\r
175                 public Object getParent(Object element) {\r
176                         if (element instanceof INode) {\r
177                                 INode node = (INode) element;\r
178                                 return node.getParent();\r
179                         }\r
180                         return null;\r
181                 }\r
182                 \r
183                 @Override\r
184                 public boolean hasChildren(Object element) {\r
185                         if (element instanceof ParentNode<?>) {\r
186                                 ParentNode<?> parentNode = (ParentNode<?>)element;\r
187                                 return parentNode.getNodes().size() > 0;\r
188                         }\r
189                         return false;\r
190                 }\r
191                 \r
192                 @Override\r
193                 public void dispose() {\r
194                         \r
195                 }\r
196                 \r
197                 @Override\r
198                 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
199                         \r
200                 }\r
201         }\r
202         \r
203         public class ScenegraphLabelProvider extends LabelProvider {\r
204                 \r
205         }\r
206 }\r