1 /*******************************************************************************
\r
2 * Copyright (c) 2007- VTT Technical Research Centre of Finland.
\r
3 * All rights reserved. This program and the accompanying materials
\r
4 * are made available under the terms of the Eclipse Public License v1.0
\r
5 * which accompanies this distribution, and is available at
\r
6 * http://www.eclipse.org/legal/epl-v10.html
\r
9 * VTT Technical Research Centre of Finland - initial API and implementation
\r
10 *******************************************************************************/
\r
11 package org.simantics.proconf.g3d.views;
\r
13 import java.util.ArrayList;
\r
14 import java.util.Iterator;
\r
15 import java.util.List;
\r
17 import org.eclipse.core.runtime.IAdaptable;
\r
18 import org.eclipse.jface.action.Action;
\r
19 import org.eclipse.jface.action.IMenuManager;
\r
20 import org.eclipse.jface.action.IToolBarManager;
\r
21 import org.eclipse.jface.resource.ImageDescriptor;
\r
22 import org.eclipse.jface.viewers.ITreeContentProvider;
\r
23 import org.eclipse.jface.viewers.LabelProvider;
\r
24 import org.eclipse.jface.viewers.TreeViewer;
\r
25 import org.eclipse.jface.viewers.Viewer;
\r
26 import org.eclipse.swt.SWT;
\r
27 import org.eclipse.swt.graphics.Image;
\r
28 import org.eclipse.swt.widgets.Composite;
\r
29 import org.eclipse.ui.IActionBars;
\r
30 import org.eclipse.ui.IPartListener;
\r
31 import org.eclipse.ui.IWorkbenchPart;
\r
32 import org.eclipse.ui.IWorkbenchWindow;
\r
33 import org.eclipse.ui.PlatformUI;
\r
34 import org.eclipse.ui.part.ViewPart;
\r
35 import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor;
\r
36 import org.eclipse.ui.views.properties.IPropertyDescriptor;
\r
37 import org.eclipse.ui.views.properties.IPropertySource;
\r
38 import org.eclipse.ui.views.properties.TextPropertyDescriptor;
\r
39 import org.simantics.proconf.g3d.Activator;
\r
40 import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;
\r
41 import org.simantics.proconf.g3d.base.ThreeDimensionalEditorPart;
\r
42 import org.simantics.proconf.g3d.scenegraph.IGeometryNode;
\r
43 import org.simantics.proconf.g3d.scenegraph.IGraphicsNode;
\r
44 import org.simantics.proconf.g3d.scenegraph.ISelectableNode;
\r
45 import org.simantics.utils.ui.gfx.ImageCache;
\r
47 import com.jme.scene.Geometry;
\r
48 import com.jme.scene.Node;
\r
49 import com.jme.scene.SceneElement;
\r
50 import com.jme.scene.Spatial;
\r
51 import com.jme.scene.batch.GeomBatch;
\r
53 public class ScenegraphViewPart extends ViewPart{
\r
55 private static final ImageDescriptor GEOMETRY_IMAGE = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/geometry.png");
\r
56 private static final ImageDescriptor BATCH_IMAGE = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/batch.png");
\r
57 private static final ImageDescriptor NODE_IMAGE = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/node.png");
\r
62 IPartListener listener;
\r
64 Action showJMEAction;
\r
67 public void createPartControl(Composite parent) {
\r
69 viewer = new TreeViewer(parent, SWT.SINGLE | SWT.H_SCROLL| SWT.V_SCROLL);
\r
70 viewer.setContentProvider(new GNScenegraphContentProvider());
\r
71 viewer.setLabelProvider(new GNScenegraphLabelProvider());
\r
72 getSite().setSelectionProvider(viewer);
\r
76 IActionBars actionBar = getViewSite().getActionBars();
\r
77 contributeToActionBars(actionBar);
\r
79 listener = new IPartListener() {
\r
81 public void partActivated(IWorkbenchPart part) {
\r
82 if (part instanceof ThreeDimensionalEditorPart) {
\r
83 ThreeDimensionalEditorPart p = (ThreeDimensionalEditorPart)part;
\r
84 Object newInput = p.getEditor();
\r
85 if (viewer.getInput() != newInput)
\r
86 viewer.setInput(newInput);
\r
88 //viewer.setInput(null);
\r
94 public void partBroughtToTop(IWorkbenchPart part) {
\r
99 public void partClosed(IWorkbenchPart part) {
\r
104 public void partDeactivated(IWorkbenchPart part) {
\r
109 public void partOpened(IWorkbenchPart part) {
\r
113 for (IWorkbenchWindow w : PlatformUI.getWorkbench().getWorkbenchWindows()) {
\r
114 w.getPartService().addPartListener(listener);
\r
120 protected void makeActions() {
\r
121 showJMEAction = new Action("jME",Action.AS_CHECK_BOX) {
\r
123 public void run() {
\r
124 Object input = viewer.getInput();
\r
125 viewer.setInput(null);
\r
126 if (this.isChecked()) {
\r
127 viewer.setContentProvider(new JMEScenegraphContentProvider());
\r
128 viewer.setLabelProvider(new JMEScenegraphLabelProvider());
\r
130 viewer.setContentProvider(new GNScenegraphContentProvider());
\r
131 viewer.setLabelProvider(new GNScenegraphLabelProvider());
\r
133 viewer.setInput(input);
\r
138 protected void contributeToActionBars(IActionBars bars) {
\r
139 fillLocalToolBar(bars.getToolBarManager());
\r
140 fillLocalPullDown(bars.getMenuManager());
\r
141 bars.updateActionBars();
\r
144 protected void fillLocalToolBar(IToolBarManager manager) {
\r
145 manager.add(showJMEAction);
\r
148 protected void fillLocalPullDown(IMenuManager manager) {
\r
153 public void setFocus() {
\r
154 viewer.getControl().setFocus();
\r
157 public void dispose() {
\r
158 for (IWorkbenchWindow w : PlatformUI.getWorkbench().getWorkbenchWindows()) {
\r
159 w.getPartService().removePartListener(listener);
\r
166 private class JMEScenegraphContentProvider implements ITreeContentProvider {
\r
168 public Object[] getChildren(Object parentElement) {
\r
169 if (parentElement instanceof JMEAdaptable)
\r
170 parentElement = ((JMEAdaptable)parentElement).getElement();
\r
172 if (parentElement instanceof Node) {
\r
173 Node n = (Node)parentElement;
\r
174 Object o[] = new Object[n.getChildren().size()];
\r
175 for (int i = 0; i < n.getChildren().size(); i++) {
\r
176 o[i] = new JMEAdaptable(n.getChild(i));
\r
180 if (parentElement instanceof Geometry) {
\r
181 Geometry g = (Geometry)parentElement;
\r
182 Object o[] = new Object[g.getBatchCount()];
\r
183 for (int i = 0 ; i < g.getBatchCount(); i++)
\r
184 o[i] = new JMEAdaptable(g.getBatch(i));
\r
191 public Object[] getElements(Object inputElement) {
\r
192 if (inputElement instanceof ThreeDimensionalEditorBase) {
\r
193 SceneElement root = ((ThreeDimensionalEditorBase)inputElement).getRenderingComponent().getRoot();
\r
195 return new Object[]{new JMEAdaptable(root)};
\r
197 return new Object[0];
\r
201 public Object getParent(Object element) {
\r
203 if (element instanceof JMEAdaptable)
\r
204 e = ((JMEAdaptable)element).getElement();
\r
206 e = (SceneElement)element;
\r
207 if (e instanceof Spatial) {
\r
208 Spatial s = (Spatial)e;
\r
209 return s.getParent();
\r
211 if (e instanceof GeomBatch) {
\r
212 GeomBatch g = (GeomBatch)e;
\r
213 return g.getParentGeom();
\r
219 public boolean hasChildren(Object element) {
\r
220 if (element instanceof JMEAdaptable)
\r
221 element = ((JMEAdaptable)element).getElement();
\r
222 if (element instanceof Node) {
\r
223 Node n = (Node)element;
\r
224 if (n.getChildren() == null)
\r
226 return n.getChildren().size() > 0;
\r
228 if (element instanceof Geometry) {
\r
229 Geometry g = (Geometry)element;
\r
230 return g.getBatchCount() > 0;
\r
236 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
\r
241 public void dispose() {
\r
246 private class JMEScenegraphLabelProvider extends LabelProvider {
\r
248 public String getText(Object element) {
\r
249 if (element == null)
\r
251 if (element instanceof JMEAdaptable)
\r
252 element = ((JMEAdaptable)element).getElement();
\r
253 SceneElement e = (SceneElement)element;
\r
254 return e.getName() + " : " + e.getClass();
\r
258 public Image getImage(Object element) {
\r
259 if (element == null)
\r
261 if (element instanceof JMEAdaptable)
\r
262 element = ((JMEAdaptable)element).getElement();
\r
263 ImageDescriptor desc = null;
\r
264 if (element instanceof GeomBatch)
\r
265 desc = BATCH_IMAGE;
\r
266 else if (element instanceof Geometry)
\r
267 desc = GEOMETRY_IMAGE;
\r
268 else if (element instanceof Node)
\r
272 return ImageCache.getInstance().getImage(desc);
\r
276 private class GNScenegraphContentProvider implements ITreeContentProvider {
\r
278 public Object[] getChildren(Object parentElement) {
\r
279 if (parentElement instanceof GNAdaptable)
\r
280 parentElement = ((GNAdaptable)parentElement).getNode();
\r
281 IGraphicsNode node = (IGraphicsNode)parentElement;
\r
282 Object children[] = new Object[node.getChildren().size()];
\r
283 Iterator<IGraphicsNode> it = node.getChildren().iterator();
\r
284 for (int i = 0; i < node.getChildren().size(); i++) {
\r
285 children[i] = new GNAdaptable(it.next());
\r
291 public Object[] getElements(Object inputElement) {
\r
292 if (inputElement instanceof ThreeDimensionalEditorBase) {
\r
293 IGraphicsNode root = ((ThreeDimensionalEditorBase)inputElement).getScenegraphAdapter().getRootNode();
\r
295 return new Object[]{new GNAdaptable(root)};
\r
297 return new Object[0];
\r
301 public Object getParent(Object element) {
\r
302 if (element instanceof GNAdaptable)
\r
303 element = ((GNAdaptable)element).getNode();
\r
304 IGraphicsNode node = (IGraphicsNode)element;
\r
305 return node.getParent();
\r
309 public boolean hasChildren(Object element) {
\r
310 if (element instanceof GNAdaptable)
\r
311 element = ((GNAdaptable)element).getNode();
\r
312 IGraphicsNode node = (IGraphicsNode)element;
\r
313 return node.getChildren().size() > 0;
\r
317 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
\r
322 public void dispose() {
\r
327 private class GNScenegraphLabelProvider extends LabelProvider {
\r
329 public String getText(Object element) {
\r
330 if (element instanceof GNAdaptable)
\r
331 element = ((GNAdaptable)element).getNode();
\r
332 IGraphicsNode node = (IGraphicsNode)element;
\r
333 return node.getGroup().getName() + " : " + node.getClass();
\r
337 public Image getImage(Object element) {
\r
338 ImageDescriptor desc = NODE_IMAGE;
\r
339 // if (element instanceof GeomBatch)
\r
340 // desc = BATCH_IMAGE;
\r
341 // else if (element instanceof Geometry)
\r
342 // desc = GEOMETRY_IMAGE;
\r
343 // else if (element instanceof Node)
\r
344 // desc = NODE_IMAGE;
\r
347 return ImageCache.getInstance().getImage(desc);
\r
351 private class JMEAdaptable implements IAdaptable {
\r
352 SceneElement element;
\r
354 public JMEAdaptable(SceneElement element) {
\r
355 assert (element != null);
\r
356 this.element = element;
\r
359 @SuppressWarnings("unchecked")
\r
361 public Object getAdapter(Class adapter) {
\r
362 if (adapter == IPropertySource.class) {
\r
363 return new JMEProperties(element);
\r
368 public SceneElement getElement() {
\r
373 private class GNAdaptable implements IAdaptable {
\r
374 IGraphicsNode node;
\r
376 public GNAdaptable(IGraphicsNode node) {
\r
377 assert (node != null);
\r
381 @SuppressWarnings("unchecked")
\r
383 public Object getAdapter(Class adapter) {
\r
384 if (adapter == IPropertySource.class) {
\r
385 return new GNProperties(node);
\r
390 public IGraphicsNode getNode() {
\r
395 private static final String NAME = "name";
\r
396 private static final String CULL_MODE = "cullmode";
\r
397 private static final String CULL_MODES[] = {"Inherit","Dynamic","Always","Never"};
\r
398 private static final String LIGHT_MODE = "lightmode";
\r
399 private static final String LIGHT_MODES[] = {"Off","Combine First","Combine Closest","Combine Recent Enabled","Inherit","Replace"};
\r
400 private static final String LOCAL_CULL_MODE = "localcullmode";
\r
401 private static final String LOCAL_LIGHT_MODE = "locallightmode";
\r
402 private static final String LOCAL_NORMALS_MODE = "localnormalsmode";
\r
403 private static final String LOCAL_RENDER_QUEUE_MODE ="localrenderqueuemode";
\r
404 private static final String LOCAL_TEXTURE_COMBINE_MODE = "localtexturecombinemode";
\r
405 private static final String LOCKS = "locks";
\r
406 private static final String NORMALS_MODE = "normalsmode";
\r
407 private static final String NORMALS_MODES[] = {"Inherit","Use Provided","Normalize Provided","Normalize if scaled","Off"};
\r
408 private static final String RENDER_QUEUE_MODE = "renderqueuemode";
\r
409 private static final String RENDER_QUEUE_MODES[] = {"Inherit","Skip","Opaque","Transparent","Ortho"};
\r
410 private static final String TEXTURE_COMBINE_MODE = "texturecombinemode";
\r
411 private static final String TEXTURE_COMBINE_MODES[] = {"Off","First","Closest","Recent enabled","Inherit","Replace"};
\r
413 private static final String BOOLEAN_VALUES[] = {"False","True"};
\r
415 private class JMEProperties implements IPropertySource {
\r
417 SceneElement element;
\r
419 public JMEProperties(SceneElement element) {
\r
420 this.element = element;
\r
424 public Object getEditableValue() {
\r
429 public IPropertyDescriptor[] getPropertyDescriptors() {
\r
430 List<IPropertyDescriptor> desc = new ArrayList<IPropertyDescriptor>();
\r
431 desc.add(new TextPropertyDescriptor(NAME,"Name"));
\r
432 desc.add(new ComboBoxPropertyDescriptor(CULL_MODE,"Cull Mode",CULL_MODES));
\r
433 desc.add(new ComboBoxPropertyDescriptor(LIGHT_MODE,"Light Combine Mode",LIGHT_MODES));
\r
434 desc.add(new ComboBoxPropertyDescriptor(LOCAL_CULL_MODE,"Local Cull Mode",CULL_MODES));
\r
435 desc.add(new ComboBoxPropertyDescriptor(LOCAL_LIGHT_MODE,"Local Light Combine Mode",LIGHT_MODES));
\r
436 desc.add(new ComboBoxPropertyDescriptor(LOCAL_NORMALS_MODE,"Local Normals Mode",NORMALS_MODES));
\r
437 desc.add(new ComboBoxPropertyDescriptor(LOCAL_RENDER_QUEUE_MODE,"Local Render Queue Mode",RENDER_QUEUE_MODES));
\r
438 desc.add(new ComboBoxPropertyDescriptor(LOCAL_TEXTURE_COMBINE_MODE,"Local Texture Combine Mode",TEXTURE_COMBINE_MODES));
\r
439 desc.add(new TextPropertyDescriptor(LOCKS,"Locks"));
\r
440 desc.add(new ComboBoxPropertyDescriptor(NORMALS_MODE,"Normals Mode",NORMALS_MODES));
\r
441 desc.add(new ComboBoxPropertyDescriptor(RENDER_QUEUE_MODE,"Render Queue Mode",RENDER_QUEUE_MODES));
\r
442 desc.add(new ComboBoxPropertyDescriptor(TEXTURE_COMBINE_MODE,"Texture Combine Mode",TEXTURE_COMBINE_MODES));
\r
443 return desc.toArray(new IPropertyDescriptor[desc.size()]);
\r
448 public Object getPropertyValue(Object id) {
\r
450 return element.getName();
\r
451 } else if (id == CULL_MODE) {
\r
452 return element.getCullMode();
\r
453 } else if (id == LIGHT_MODE) {
\r
454 return element.getLightCombineMode();
\r
455 } else if (id == LOCAL_CULL_MODE) {
\r
456 return element.getLocalCullMode();
\r
457 } else if (id == LOCAL_LIGHT_MODE) {
\r
458 return element.getLocalLightCombineMode();
\r
459 } else if (id == LOCAL_NORMALS_MODE) {
\r
460 return element.getLocalNormalsMode();
\r
461 } else if (id == LOCAL_RENDER_QUEUE_MODE) {
\r
462 return element.getLocalRenderQueueMode();
\r
463 } else if (id == LOCAL_TEXTURE_COMBINE_MODE) {
\r
464 return element.getLocalTextureCombineMode();
\r
465 } else if (id == LOCKS) {
\r
466 return element.getLocks();
\r
467 } else if (id == NORMALS_MODE) {
\r
468 return element.getNormalsMode();
\r
469 } else if (id == RENDER_QUEUE_MODE) {
\r
470 return element.getRenderQueueMode();
\r
471 } else if (id == TEXTURE_COMBINE_MODE) {
\r
472 return element.getTextureCombineMode();
\r
475 // element.getZOrder();
\r
476 // element.isCollidable();
\r
482 public boolean isPropertySet(Object id) {
\r
487 public void resetPropertyValue(Object id) {
\r
492 public void setPropertyValue(Object id, Object value) {
\r
494 element.setName((String)value);
\r
495 } else if (id == CULL_MODE) {
\r
496 element.setCullMode((Integer)value);
\r
497 } else if (id == LIGHT_MODE) {
\r
498 element.setLightCombineMode((Integer)value);
\r
499 } else if (id == LOCAL_CULL_MODE) {
\r
501 } else if (id == LOCAL_LIGHT_MODE) {
\r
503 } else if (id == LOCAL_NORMALS_MODE) {
\r
505 } else if (id == LOCAL_RENDER_QUEUE_MODE) {
\r
507 } else if (id == LOCAL_TEXTURE_COMBINE_MODE) {
\r
509 } else if (id == LOCKS) {
\r
510 element.setLocks((Integer)value);
\r
511 } else if (id == NORMALS_MODE) {
\r
512 element.setNormalsMode((Integer)value);
\r
513 } else if (id == RENDER_QUEUE_MODE) {
\r
514 element.setRenderQueueMode((Integer)value);
\r
515 } else if (id == TEXTURE_COMBINE_MODE) {
\r
516 element.setTextureCombineMode((Integer)value);
\r
523 private static final String SELECTED = "selected";
\r
524 private static final String HIGHLIGHTED = "highlighted";
\r
525 private static final String VISIBLE = "visible";
\r
527 private class GNProperties implements IPropertySource {
\r
528 IGraphicsNode node;
\r
530 public GNProperties(IGraphicsNode node) {
\r
536 public Object getEditableValue() {
\r
541 public IPropertyDescriptor[] getPropertyDescriptors() {
\r
542 List<IPropertyDescriptor> desc = new ArrayList<IPropertyDescriptor>();
\r
543 if (node instanceof ISelectableNode) {
\r
544 //ISelectableNode n = (ISelectableNode)node;
\r
546 desc.add(new ComboBoxPropertyDescriptor(SELECTED,"Selected",BOOLEAN_VALUES));
\r
547 desc.add(new ComboBoxPropertyDescriptor(HIGHLIGHTED,"Highlighted",BOOLEAN_VALUES));
\r
548 desc.add(new ComboBoxPropertyDescriptor(VISIBLE,"Visible",BOOLEAN_VALUES));
\r
551 return desc.toArray(new IPropertyDescriptor[desc.size()]);
\r
555 public Object getPropertyValue(Object id) {
\r
556 if (node instanceof ISelectableNode) {
\r
557 ISelectableNode n = (ISelectableNode)node;
\r
558 if (id == SELECTED) {
\r
559 if (n.isSelected())
\r
562 } else if (id == HIGHLIGHTED) {
\r
563 if (n.isHighlighted())
\r
566 } else if (id == VISIBLE) {
\r
572 if (node instanceof IGeometryNode) {
\r
573 //IGeometryNode n = (IGeometryNode)node;
\r
580 public boolean isPropertySet(Object id) {
\r
585 public void resetPropertyValue(Object id) {
\r
590 public void setPropertyValue(Object id, Object value) {
\r
591 if (node instanceof ISelectableNode) {
\r
592 ISelectableNode n = (ISelectableNode)node;
\r
593 boolean b = ((Integer)value) == 1;
\r
594 if (id == SELECTED) {
\r
596 } else if (id == HIGHLIGHTED) {
\r
597 n.setHighlighted(b);
\r
598 } else if (id == VISIBLE) {
\r