1 /*******************************************************************************
\r
2 * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
\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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.g3d.ui;
\r
14 import java.util.HashSet;
\r
15 import java.util.Set;
\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
28 public class ScenegraphOutlinePage extends ContentOutlinePage implements NodeListener {
\r
30 private ParentNode<? extends INode> rootNode;
\r
32 public ScenegraphOutlinePage(ParentNode<? extends INode> rootNode) {
\r
33 if (rootNode == null)
\r
34 throw new NullPointerException();
\r
35 this.rootNode = rootNode;
\r
40 public void createControl(Composite parent) {
\r
41 super.createControl(parent);
\r
42 if (rootNode == null)
\r
44 TreeViewer viewer = getTreeViewer();
\r
45 createProviders(viewer);
\r
46 viewer.setInput(rootNode);
\r
50 protected void createProviders(TreeViewer viewer) {
\r
51 viewer.setContentProvider(new ScenegraphContentProvider());
\r
52 viewer.setLabelProvider(new ScenegraphLabelProvider());
\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
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
78 public void propertyChanged(INode node, String id) {
\r
79 refershViewer(node);
\r
83 public <T extends INode> void nodeAdded(ParentNode<T> node, INode child,
\r
86 refershViewer(node);
\r
92 public <T extends INode> void nodeRemoved(ParentNode<T> node, INode child,
\r
94 stopListening(child);
\r
95 refershViewer(node);
\r
98 //private Queue<INode> toRefresh = new LinkedList<INode>();
\r
99 private Set<INode> toRefresh = new HashSet<INode>();
\r
100 private NodeUpdater updater;
\r
102 protected void refershViewer(final INode node) {
\r
103 if (getTreeViewer() == null)
\r
105 synchronized (toRefresh) {
\r
106 toRefresh.add(node);
\r
107 if (updater != null)
\r
111 updater = new NodeUpdater();
\r
112 Display.getDefault().asyncExec(updater);
\r
115 private class NodeUpdater implements Runnable {
\r
117 public void run() {
\r
118 if (getTreeViewer().getTree().isDisposed()) {
\r
123 // limit the amount of refreshes.
\r
124 while (count < 100) {
\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
135 //node = toRefresh.poll();
\r
136 if (toRefresh.size() > 0) {
\r
137 node = toRefresh.iterator().next();
\r
138 toRefresh.remove(node);
\r
140 if (node == null) {
\r
145 getTreeViewer().refresh(node);
\r
148 if (toRefresh.size() > 0) {
\r
149 Display.getDefault().asyncExec(this);
\r
154 public static class ScenegraphContentProvider implements ITreeContentProvider {
\r
156 public ScenegraphContentProvider() {
\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
166 return new Object[0];
\r
170 public Object[] getElements(Object inputElement) {
\r
171 return getChildren(inputElement);
\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
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
193 public void dispose() {
\r
198 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
\r
203 public class ScenegraphLabelProvider extends LabelProvider {
\r