Pārlūkot izejas kodu

Fixes #34 - Allow the User to start/stop several Controls by removing/adding them from the SDKs' Internal SceneGraph. See Right-Click on Controls or Nodes. Nodes will iterate recursively over all children (!)

MeFisto94 9 gadi atpakaļ
vecāks
revīzija
dd86ef64c6

+ 2 - 2
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeAnimControl.java

@@ -34,6 +34,7 @@ package com.jme3.gde.core.sceneexplorer.nodes;
 import com.jme3.animation.AnimControl;
 import com.jme3.gde.core.icons.IconList;
 import com.jme3.gde.core.properties.AnimationProperty;
+import com.jme3.gde.core.sceneexplorer.nodes.actions.ControlsPopup;
 import com.jme3.gde.core.sceneexplorer.nodes.actions.TrackVisibilityPopup;
 import java.awt.Image;
 import javax.swing.Action;
@@ -116,10 +117,9 @@ public class JmeAnimControl extends JmeControl {
 
     @Override
     public Action[] getActions(boolean context) {
-
-
         return new Action[]{
                     new TrackVisibilityPopup(this),
+                    new ControlsPopup(this),
                     SystemAction.get(DeleteAction.class)
                 };
     }

+ 60 - 1
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeControl.java

@@ -32,6 +32,7 @@
 package com.jme3.gde.core.sceneexplorer.nodes;
 
 import com.jme3.gde.core.scene.SceneApplication;
+import com.jme3.gde.core.sceneexplorer.nodes.actions.ControlsPopup;
 import com.jme3.scene.Spatial;
 import com.jme3.scene.control.Control;
 import java.io.IOException;
@@ -54,6 +55,8 @@ import org.openide.util.actions.SystemAction;
 public abstract class JmeControl extends AbstractSceneExplorerNode {
 
     protected Control control;
+    protected boolean enabled;
+    
     public JmeControl() {
         super();
     }
@@ -72,10 +75,11 @@ public abstract class JmeControl extends AbstractSceneExplorerNode {
     
     @Override
     public Action[] getActions(boolean context) {
-        return new SystemAction[]{
+        return new Action[]{
                     //                    SystemAction.get(CopyAction.class),
                     //                    SystemAction.get(CutAction.class),
                     //                    SystemAction.get(PasteAction.class),
+                    new ControlsPopup(this),
                     SystemAction.get(DeleteAction.class)
                 };
     }
@@ -120,4 +124,59 @@ public abstract class JmeControl extends AbstractSceneExplorerNode {
             par.fireSave(modified);
         }
     }
+    
+    /**
+     * Enable/Disable the Control. This means essentially it will get detached from our Scene Graph.
+     * Also see: {@link #isEnabled() }
+     * @param enabled Whether the Control should be enabled or disabled
+     * @return If we had success (false when an Exception occured or no {@link Control} assigned.
+     */
+    public boolean setEnabled(boolean enabled) {
+        if (control == null)
+            return false;
+        
+        this.enabled = enabled;
+        final Spatial spat = getParentNode().getLookup().lookup(Spatial.class);
+        
+        try {
+            if (enabled) {
+                SceneApplication.getApplication().enqueue(new Callable<Void>() {
+                    public Void call() throws Exception {
+                        if (spat.getControl(control.getClass()) == null)
+                            spat.addControl(control);
+                        return null;
+                    }
+                }).get();
+        
+            } else {
+                SceneApplication.getApplication().enqueue(new Callable<Void>() {
+                        public Void call() throws Exception {
+                            if (spat.getControl(control.getClass()) != null)
+                                spat.removeControl(control);
+                            return null;
+                        }
+                    }).get();
+            }
+        } catch (InterruptedException ex) {
+            Exceptions.printStackTrace(ex);
+            this.enabled = false;
+            return false;
+        } catch (ExecutionException ex) {
+            Exceptions.printStackTrace(ex);
+            this.enabled = false;
+            return false;
+        }
+        
+        return true;
+    }
+    
+    /**
+     * Returns whether this Control is enabled or disabled (i.e. attached to the SceneGraph and has it's controlUpdate rendered).
+     * <b>Note:</b> When an Exception occurs during {@link #setEnabled(boolean) }, it's status is considered disabled.
+     * @return -
+     */
+    public boolean isEnabled()
+    {
+        return enabled;
+    }
 }

+ 2 - 0
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeNode.java

@@ -34,6 +34,7 @@ package com.jme3.gde.core.sceneexplorer.nodes;
 import com.jme3.gde.core.icons.IconList;
 import com.jme3.gde.core.scene.SceneApplication;
 import com.jme3.gde.core.sceneexplorer.nodes.actions.AddUserDataAction;
+import com.jme3.gde.core.sceneexplorer.nodes.actions.ControlsPopup;
 import com.jme3.gde.core.sceneexplorer.nodes.actions.NewControlPopup;
 import com.jme3.gde.core.sceneexplorer.nodes.actions.NewLightPopup;
 import com.jme3.gde.core.sceneexplorer.nodes.actions.NewSpatialPopup;
@@ -166,6 +167,7 @@ public class JmeNode extends JmeSpatial {
                         new NewLightPopup(this),
                         Actions.alwaysEnabled(new AddUserDataAction(this), "Add User Data", "", false),
                         new ToolPopup(this),
+                        new ControlsPopup(this),
                         SystemAction.get(RenameAction.class),
                         SystemAction.get(CopyAction.class),
                         SystemAction.get(CutAction.class),

+ 21 - 1
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeSpatial.java

@@ -36,6 +36,7 @@ import com.jme3.export.binary.BinaryExporter;
 import com.jme3.gde.core.properties.UserDataProperty;
 import com.jme3.gde.core.scene.SceneApplication;
 import com.jme3.gde.core.sceneexplorer.nodes.actions.AddUserDataAction;
+import com.jme3.gde.core.sceneexplorer.nodes.actions.ControlsPopup;
 import com.jme3.gde.core.sceneexplorer.nodes.actions.NewControlPopup;
 import com.jme3.gde.core.sceneexplorer.nodes.actions.NewLightPopup;
 import com.jme3.gde.core.sceneexplorer.nodes.actions.ToolPopup;
@@ -125,11 +126,14 @@ public class JmeSpatial extends AbstractSceneExplorerNode {
 //        return super.getActions(context);
         if (((JmeSpatialChildren) jmeChildren).readOnly) {
             return new Action[]{
-                        SystemAction.get(CopyAction.class),};
+                        SystemAction.get(CopyAction.class),
+                        new ControlsPopup(this)
+                };
         } else {
             return new Action[]{
                         new NewControlPopup(this),
                         new NewLightPopup(this),
+                        new ControlsPopup(this),
                         Actions.alwaysEnabled(new AddUserDataAction(this), "Add User Data", "", false),
                         new ToolPopup(this),
                         SystemAction.get(RenameAction.class),
@@ -358,4 +362,20 @@ public class JmeSpatial extends AbstractSceneExplorerNode {
         children.setDataObject(key2);
         return new Node[]{new JmeSpatial((Spatial) key, children).setReadOnly(cookie)};
     }
+    
+    /**
+     * This method will call {@link JmeControl#setEnabled(boolean) } for all children nodes of this.
+     * It will enabled/disable the Controls from the Scene Graph and hence being run.
+     * Note: There is no isEnabled because it's only passed on to the Controls and they could have several states.
+     * @param enable 
+     */
+    public void setEnabled(boolean enable) {
+        for (Node n : getChildren().getNodes()) {
+            if (n instanceof JmeSpatial) {
+                ((JmeSpatial)n).setEnabled(enable);
+            } else if (n instanceof JmeControl) {
+                ((JmeControl)n).setEnabled(enable);
+            }
+        }
+    }
 }

+ 0 - 3
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeVehicleControl.java

@@ -43,14 +43,11 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
-import javax.swing.Action;
-import org.openide.actions.DeleteAction;
 import org.openide.loaders.DataObject;
 import org.openide.nodes.Children;
 import org.openide.nodes.Node;
 import org.openide.nodes.Sheet;
 import org.openide.util.Exceptions;
-import org.openide.util.actions.SystemAction;
 
 /**
  *

+ 158 - 0
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/ControlsPopup.java

@@ -0,0 +1,158 @@
+/*
+ *  Copyright (c) 2009-2016 jMonkeyEngine
+ *  All rights reserved.
+ * 
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ * 
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ *  * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ *  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.gde.core.sceneexplorer.nodes.actions;
+
+import com.jme3.gde.core.sceneexplorer.nodes.JmeControl;
+import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial;
+import com.jme3.scene.Node;
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import org.openide.loaders.DataObject;
+import org.openide.util.actions.Presenter;
+
+/**
+ * This class offers the Popupmenu for all SceneExplorer nodes which allows to start/stop all Controls under this Node.
+ * @author MeFisto94
+ */
+public class ControlsPopup extends AbstractAction implements Presenter.Popup {
+
+    protected JmeSpatial jmeSpatial;
+    protected JmeControl jmeControl;
+    protected Node node;
+    protected DataObject dataObject;
+    protected boolean isControl = false;
+
+    public ControlsPopup(JmeSpatial node) {
+        this.jmeSpatial = node;
+        this.node = node.getLookup().lookup(Node.class);
+        this.dataObject = node.getLookup().lookup(DataObject.class);
+    }
+    
+    public ControlsPopup(JmeControl node) {
+        this.jmeControl = node;
+        this.node = node.getLookup().lookup(Node.class);
+        this.dataObject = node.getLookup().lookup(DataObject.class);
+        isControl = true;
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+    }
+
+    @Override
+    public JMenuItem getPopupPresenter() {
+        JMenu result;
+        
+        if (isControl) {
+            result = new JMenu("Control");
+            result.add(new JMenuItem(getStartAction(jmeControl)));
+            result.add(new JMenuItem(getStopAction(jmeControl)));
+        } else {
+            result = new JMenu("Controls");
+            result.add(new JMenuItem(getStartAction(jmeSpatial)));
+            result.add(new JMenuItem(getStopAction(jmeSpatial)));
+        }
+        
+        return result;
+    }
+    
+    /**
+     * Create the Action which will start all subsequent controls to this Spatial.
+     * See {@link #getStopAction(com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial) } and {@link #getStartAction(com.jme3.gde.core.sceneexplorer.nodes.JmeControl) }
+     * @param Spatial The JmeSpatial to depend this Action on.
+     * @return -
+     */
+    public static Action getStartAction(final JmeSpatial Spatial) {
+        return new AbstractAction("Start All") {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                if (Spatial != null) {
+                    Spatial.setEnabled(true);
+                }
+            }
+        };
+    }
+    
+    /**
+     * Create the Action which will start the given Control
+     * See {@link #getStopAction(com.jme3.gde.core.sceneexplorer.nodes.JmeControl) } and {@link #getStartAction(com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial) }
+     * @param Control The JmeControl to depend this Action on.
+     * @return -
+     */
+    public static Action getStartAction(final JmeControl Control) {
+        return new AbstractAction("Start") {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                if (Control != null) {
+                    Control.setEnabled(true);
+                }
+            }
+        };
+    }
+    
+    /**
+     * Create the Action which will stop all subsequent controls to Spatial
+     * See {@link #getStartAction(com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial)} and {@link #getStopAction(com.jme3.gde.core.sceneexplorer.nodes.JmeControl) }
+     * @param Spatial The JmeSpatial to depend this Action on.
+     * @return -
+     */
+    public static Action getStopAction(final JmeSpatial Spatial) {
+        return new AbstractAction("Stop All") {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                if (Spatial != null) {
+                    Spatial.setEnabled(false);
+                }
+            }
+        };
+    }
+    
+    /**
+     * Create the Action which will stop the given Control.
+     * See {@link #getStopAction(com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial) } and {@link #getStartAction(com.jme3.gde.core.sceneexplorer.nodes.JmeControl) }
+     * @param Control The JmeControl to depend this Action on.
+     * @return -
+     */
+    public static Action getStopAction(final JmeControl Control) {
+        return new AbstractAction("Stop") {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                if (Control != null) {
+                    Control.setEnabled(false);
+                }
+            }
+        };
+    }
+}