OSDN Git Service

terrain paint tool remembers undo history as an entire mouseDown event now. RMB now...
authorbrentowens@gmail.com <brentowens@gmail.com@75d07b2b-3a1a-0410-a2c5-0572b91ccdca>
Fri, 8 Mar 2013 19:11:02 +0000 (19:11 +0000)
committerbrentowens@gmail.com <brentowens@gmail.com@75d07b2b-3a1a-0410-a2c5-0572b91ccdca>
Fri, 8 Mar 2013 19:11:02 +0000 (19:11 +0000)
git-svn-id: http://jmonkeyengine.googlecode.com/svn/trunk@10473 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/AbstractStatefulGLToolAction.java
sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/Bundle.properties
sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainCameraController.java
sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainEditorTopComponent.form
sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainEditorTopComponent.java
sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainToolController.java
sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/AbstractTerrainToolAction.java
sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/PaintTerrainTool.java
sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/PaintTerrainToolAction.java
sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/TerrainTool.java

index 647abf5..322c238 100644 (file)
@@ -62,9 +62,15 @@ public abstract class AbstractStatefulGLToolAction {
     }
 
     public void doActionPerformed(final AbstractSceneExplorerNode rootNode, final DataObject dataObject) {
+        doActionPerformed(rootNode, dataObject, true);
+    }
+    
+    public void doActionPerformed(final AbstractSceneExplorerNode rootNode, final DataObject dataObject, boolean recordUndo) {
 
         final Object object = doApplyTool(rootNode);
-        if (object!=null) {
+        
+        if (object!=null && recordUndo) {
+            
             Lookup lookup = Lookup.getDefault() ;
             SceneUndoRedoManager manager = lookup.lookup(SceneUndoRedoManager.class);
 
index 89be453..5ac2494 100644 (file)
@@ -89,8 +89,6 @@ TerrainEditorTopComponent.remainingTexturesLabel.text=\
 TerrainEditorTopComponent.textureTable.columnModel.title4=Normal
 TerrainEditorTopComponent.eraseButton.toolTipText=Erase a texture from the terrain
 TerrainEditorTopComponent.eraseButton.text=
-TerrainEditorTopComponent.paintButton.toolTipText=Paint a texture onto the terrain
-TerrainEditorTopComponent.paintButton.text=
 TerrainEditorTopComponent.paintingPanel.border.title=Painting
 TerrainEditorTopComponent.triPlanarCheckBox.toolTipText=Enable if you have a lot of vertical surfaces. It will look nice but lower performance
 TerrainEditorTopComponent.triPlanarCheckBox.text=Tri-planar
index a601187..e4deb55 100644 (file)
@@ -105,32 +105,43 @@ public class TerrainCameraController extends AbstractCameraController {
 
     @Override
     protected void checkClick(int button, boolean pressed) {
+        checkMouseButtonState(button, pressed);
+    }
+    
+    @Override
+    protected void checkDragged(int button, boolean pressed) {
+        checkMouseButtonState(button, pressed);
+    }
+    
+    private void checkMouseButtonState(int button, boolean pressed) {
+        if (isTerrainEditButtonEnabled() && !forceCameraControls) {
+            if (terrainEditToolActivated != pressed)
+                toolController.doTerrainEditToolActionEnded(); // button state change, trigger undo action
+            terrainEditToolActivated = pressed;
+        }
         
-         /*if (button == 0) {
+        
+        if (button == 0) {
             if (isTerrainEditButtonEnabled() && !forceCameraControls) {
-                terrainEditToolActivated = true;
+                toolController.setPrimary(pressed);
+                System.out.println("primary "+pressed);
             }
         }
-       
-         if (button == 1) {
-         if (isTerrainEditButtonEnabled() && !forceCameraControls) {
-         toolController.doTerrainEditToolAlternateActivated();
-         }
-         }*/
-
+        
         if (button == 1) {
             if (isTerrainEditButtonEnabled() && !forceCameraControls) {
-                toolController.doTerrainEditToolAlternateActivated();
+                toolController.setAlternate(pressed);
+                System.out.println("alternate "+pressed);
             }
         }
     }
 
-    @Override
+    /*@Override
     protected void checkDragged(int button, boolean pressed) {
-        if (button == 0  && !forceCameraControls) {
+        if ( (button == 0 || button == 1) && !forceCameraControls) {
             terrainEditToolActivated = true;
         }
-    }
+    }*/
 
     @Override
     protected void checkMoved() {
@@ -151,8 +162,9 @@ public class TerrainCameraController extends AbstractCameraController {
                 lastModifyTime = 0;
                 if (terrainEditToolActivated) {
                     toolController.doTerrainEditToolActivated();
+                    toolController.doTerrainEditToolAlternateActivated();
                 }
-                terrainEditToolActivated = false;
+                //terrainEditToolActivated = false;
                 lastModifyTime = app.getContext().getTimer().getTime();
             }
         }
index 60b0965..b07ee78 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.1" encoding="UTF-8" ?>
+<?xml version="1.0" encoding="UTF-8" ?>
 
 <Form version="1.6" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
   <NonVisualComponents>
                   <Component id="hintPanel" max="32767" attributes="1"/>
                   <Component id="paintingPanel" alignment="0" max="32767" attributes="1"/>
                   <Component id="toolSettingsPanel" alignment="0" pref="132" max="32767" attributes="1"/>
-                  <Component id="jPanel2" pref="132" max="32767" attributes="1"/>
+                  <Component id="jPanel2" max="32767" attributes="1"/>
               </Group>
           </Group>
       </Group>
             <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="removeTextureButtonActionPerformed"/>
           </Events>
         </Component>
-        <Component class="javax.swing.JToggleButton" name="paintButton">
-          <Properties>
-            <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
-              <ComponentRef name="terrainModButtonGroup"/>
-            </Property>
-            <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
-              <Image iconType="3" name="/com/jme3/gde/terraineditor/icon_terrain-paint-circle.png"/>
-            </Property>
-            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.paintButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-            </Property>
-            <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.paintButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-            </Property>
-            <Property name="focusable" type="boolean" value="false"/>
-            <Property name="horizontalTextPosition" type="int" value="0"/>
-            <Property name="verticalTextPosition" type="int" value="3"/>
-          </Properties>
-          <Events>
-            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="paintButtonActionPerformed"/>
-          </Events>
-        </Component>
         <Component class="javax.swing.JToggleButton" name="eraseButton">
           <Properties>
             <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
             <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
               <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.eraseButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
             </Property>
+            <Property name="enabled" type="boolean" value="false"/>
             <Property name="focusable" type="boolean" value="false"/>
             <Property name="horizontalTextPosition" type="int" value="0"/>
             <Property name="verticalTextPosition" type="int" value="3"/>
             <Property name="majorTickSpacing" type="int" value="10"/>
             <Property name="minorTickSpacing" type="int" value="5"/>
             <Property name="paintTicks" type="boolean" value="true"/>
-            <Property name="snapToTicks" type="boolean" value="true"/>
             <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
               <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.radiusSlider.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
             </Property>
index a209354..a130003 100644 (file)
@@ -252,7 +252,6 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
         jSeparator2 = new javax.swing.JToolBar.Separator();
         addTextureButton = new javax.swing.JButton();
         removeTextureButton = new javax.swing.JButton();
-        paintButton = new javax.swing.JToggleButton();
         eraseButton = new javax.swing.JToggleButton();
         jSeparator3 = new javax.swing.JToolBar.Separator();
         radiusLabel = new javax.swing.JLabel();
@@ -512,24 +511,11 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
         });
         jToolBar1.add(removeTextureButton);
 
-        terrainModButtonGroup.add(paintButton);
-        paintButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/terraineditor/icon_terrain-paint-circle.png"))); // NOI18N
-        org.openide.awt.Mnemonics.setLocalizedText(paintButton, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.paintButton.text")); // NOI18N
-        paintButton.setToolTipText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.paintButton.toolTipText")); // NOI18N
-        paintButton.setFocusable(false);
-        paintButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
-        paintButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
-        paintButton.addActionListener(new java.awt.event.ActionListener() {
-            public void actionPerformed(java.awt.event.ActionEvent evt) {
-                paintButtonActionPerformed(evt);
-            }
-        });
-        jToolBar1.add(paintButton);
-
         terrainModButtonGroup.add(eraseButton);
         eraseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/terraineditor/icon_terrain-erase-circle.png"))); // NOI18N
         org.openide.awt.Mnemonics.setLocalizedText(eraseButton, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.eraseButton.text")); // NOI18N
         eraseButton.setToolTipText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.eraseButton.toolTipText")); // NOI18N
+        eraseButton.setEnabled(false);
         eraseButton.setFocusable(false);
         eraseButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
         eraseButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
@@ -547,7 +533,6 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
         radiusSlider.setMajorTickSpacing(10);
         radiusSlider.setMinorTickSpacing(5);
         radiusSlider.setPaintTicks(true);
-        radiusSlider.setSnapToTicks(true);
         radiusSlider.setToolTipText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.radiusSlider.toolTipText")); // NOI18N
         radiusSlider.setValue(5);
         radiusSlider.setOpaque(false);
@@ -722,7 +707,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
                     .addComponent(hintPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                     .addComponent(paintingPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                     .addComponent(toolSettingsPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 132, Short.MAX_VALUE)
-                    .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, 132, Short.MAX_VALUE)))
+                    .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
         );
     }// </editor-fold>//GEN-END:initComponents
 
@@ -755,17 +740,6 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
         }
     }//GEN-LAST:event_lowerTerrainButtonActionPerformed
 
-    private void paintButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_paintButtonActionPerformed
-        if (paintButton.isSelected()) {
-            PaintTerrainTool tool = new PaintTerrainTool();
-            toolController.setTerrainEditButtonState(tool);
-            setHintText(tool);
-        } else {
-            toolController.setTerrainEditButtonState(null);
-            setHintText((TerrainTool) null);
-        }
-    }//GEN-LAST:event_paintButtonActionPerformed
-
     private void addTextureButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addTextureButtonActionPerformed
         if (editorController == null || editorController.getTerrain(null) == null) {
             return;
@@ -807,7 +781,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
 
     private void eraseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_eraseButtonActionPerformed
         if (eraseButton.isSelected()) {
-            EraseTerrainTool tool = new EraseTerrainTool();
+            PaintTerrainTool tool = new PaintTerrainTool();
             toolController.setTerrainEditButtonState(tool);
             setHintText(tool);
         } else {
@@ -977,7 +951,6 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
     private javax.swing.JToggleButton levelTerrainButton;
     private javax.swing.JToggleButton lowerTerrainButton;
     private javax.swing.JTextField octavesField;
-    private javax.swing.JToggleButton paintButton;
     private javax.swing.JPanel paintingPanel;
     private javax.swing.JLabel radiusLabel;
     private javax.swing.JSlider radiusSlider;
index b264e5c..531bd2f 100644 (file)
@@ -35,6 +35,7 @@ package com.jme3.gde.terraineditor;
 import com.jme3.asset.AssetManager;
 import com.jme3.gde.core.scene.SceneApplication;
 import com.jme3.gde.core.scene.controller.SceneToolController;
+import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode;
 import com.jme3.gde.core.sceneexplorer.nodes.JmeNode;
 import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial;
 import com.jme3.gde.terraineditor.tools.TerrainTool;
@@ -42,6 +43,7 @@ import com.jme3.input.event.KeyInputEvent;
 import com.jme3.math.Vector3f;
 import com.jme3.scene.Node;
 import java.util.concurrent.Callable;
+import org.openide.loaders.DataObject;
 
 /**
  * The controller for the terrain modification tools. It will in turn interact
@@ -63,6 +65,8 @@ public class TerrainToolController extends SceneToolController {
     private float toolWeight;
     private int selectedTextureIndex = -1;
     private boolean mesh = false;
+    private boolean primary = false;
+    private boolean alternate = false;
     
 
     public TerrainToolController(Node toolsNode, AssetManager manager, JmeNode rootNode) {
@@ -200,7 +204,7 @@ public class TerrainToolController extends SceneToolController {
      */
     public void doTerrainEditToolActivated() {
 
-        if (terrainTool != null) {
+        if (terrainTool != null && primary && !alternate) {
             Vector3f point = getMarkerLocation();
             if (point != null) {
                 topComponent.getExtraToolParams();
@@ -215,9 +219,11 @@ public class TerrainToolController extends SceneToolController {
      */
     public void doTerrainEditToolAlternateActivated() {
         
-        if (terrainTool != null) {
-            Vector3f point = cameraController.getTerrainCollisionPoint();
+        if (terrainTool != null && alternate && !primary) {
+            //Vector3f point = cameraController.getTerrainCollisionPoint();
+            Vector3f point = getMarkerLocation();
             if (point != null) {
+                topComponent.getExtraToolParams();
                 terrainTool.actionSecondary(point, selectedTextureIndex, jmeRootNode, editorController.getCurrentDataObject());
             }
             
@@ -225,6 +231,14 @@ public class TerrainToolController extends SceneToolController {
 
     }
 
+    public void setPrimary(boolean primary) {
+        this.primary = primary;
+    }
+
+    public void setAlternate(boolean alternate) {
+        this.alternate = alternate;
+    }
+
     void setExtraToolParams(ExtraToolParams params) {
         if (terrainTool != null) {
             terrainTool.setExtraParams(params);
@@ -240,4 +254,14 @@ public class TerrainToolController extends SceneToolController {
             terrainTool.keyPressed(kie);
         }
     }
+
+    /**
+     * The action on the tool has ended (mouse button up), record the Undo (for painting only now)
+     */
+    void doTerrainEditToolActionEnded() {
+        if (terrainTool != null) {
+            System.out.println("undo tagged");
+            terrainTool.actionEnded(jmeRootNode, editorController.getCurrentDataObject());
+        }
+    }
 } 
index 64b891b..5ad1a06 100644 (file)
@@ -43,11 +43,17 @@ import com.jme3.terrain.Terrain;
  */
 public abstract class AbstractTerrainToolAction extends AbstractStatefulGLToolAction {
 
+    private Terrain terrain;
+    
     protected Terrain getTerrain(Spatial root) {
 
+        if (terrain != null)
+            return terrain;
+        
         // is this the terrain?
         if (root instanceof Terrain && root instanceof Node) {
-            return (Terrain)root;
+            terrain = (Terrain)root;
+            return terrain;
         }
 
         if (root instanceof Node) {
index faa2b8c..4441480 100644 (file)
 package com.jme3.gde.terraineditor.tools;
 
 import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode;
+import com.jme3.gde.core.sceneexplorer.nodes.actions.AbstractStatefulGLToolAction;
+import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit;
+import com.jme3.gde.core.undoredo.SceneUndoRedoManager;
 import com.jme3.math.ColorRGBA;
 import com.jme3.math.Vector3f;
 import com.jme3.scene.Node;
+import com.jme3.terrain.Terrain;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.undo.CannotRedoException;
+import javax.swing.undo.CannotUndoException;
 import org.openide.loaders.DataObject;
+import org.openide.util.Lookup;
 
 /**
- *
+ * Paint or erase the textures on the terrain.
+ * 
  * @author Brent Owens
  */
 public class PaintTerrainTool extends TerrainTool {
 
+    private boolean painting = false; // to check when undo actions need to be set
+    List<PaintTerrainToolAction> actions = new ArrayList<PaintTerrainToolAction>();
+
+    
     @Override
     public void actionPrimary(Vector3f point, int textureIndex, AbstractSceneExplorerNode rootNode, DataObject dataObject) {
-        if (radius == 0 || weight == 0)
-            return;
-        PaintTerrainToolAction action = new PaintTerrainToolAction(point, radius, weight, textureIndex);
-        action.doActionPerformed(rootNode, dataObject);
+        setPrimary(true);
+        action(point, textureIndex, rootNode, dataObject);
     }
 
     @Override
     public void actionSecondary(Vector3f point, int textureIndex, AbstractSceneExplorerNode rootNode, DataObject dataObject) {
-        // do nothing
+        setPrimary(false);
+        action(point, textureIndex, rootNode, dataObject);
+    }
+    
+    private void action(Vector3f point, int textureIndex, AbstractSceneExplorerNode rootNode, DataObject dataObject) {
+        if (radius == 0 || weight == 0)
+            return;
+        
+        if (!painting)
+            painting = true;
+        
+        PaintTerrainToolAction action;
+        if (isPrimary())
+            action = new PaintTerrainToolAction(point, radius, weight, textureIndex);
+        else
+            action = new PaintTerrainToolAction(point, radius, -weight, textureIndex);
+        action.doActionPerformed(rootNode, dataObject, false);
+        actions.add(action);
+    }
+    
+    @Override
+    public void actionEnded(AbstractSceneExplorerNode rootNode, DataObject dataObject) {
+        if (painting) {
+            painting = false;
+            
+            if (actions.isEmpty())
+                return;
+            
+            // record undo action
+            List<PaintTerrainToolAction> cloned = new ArrayList<PaintTerrainToolAction>();
+            cloned.addAll(actions);
+            recordUndo(cloned, rootNode, dataObject);
+            actions.clear();
+        }
+    }
+
+    /**
+     * Is it already painting?
+     * If the user releases the mouse outside the window, this can be used to check
+     * if they were painting, and if so, call actionEnded()
+     */
+    public boolean isPainting() {
+        return painting;
     }
     
     @Override
@@ -61,4 +115,48 @@ public class PaintTerrainTool extends TerrainTool {
         super.addMarkerPrimary(parent);
         markerPrimary.getMaterial().setColor("Color", ColorRGBA.Cyan);
     }
+
+    private void recordUndo(final List<PaintTerrainToolAction> actions, final AbstractSceneExplorerNode rootNode, final DataObject dataObject) {
+        Lookup lookup = Lookup.getDefault() ;
+        SceneUndoRedoManager manager = lookup.lookup(SceneUndoRedoManager.class);
+
+        AbstractUndoableSceneEdit undoer = new AbstractUndoableSceneEdit() {
+
+            @Override
+            public void sceneUndo() throws CannotUndoException {
+                Terrain terrain = null;
+                for (int i=actions.size()-1; i>=0; i--) {
+                    PaintTerrainToolAction a = actions.get(i);
+                    if (terrain == null) 
+                        terrain = a.getTerrain(rootNode.getLookup().lookup(Node.class));
+                    a.doUndoTool(rootNode, terrain);
+                }
+                setModified(rootNode, dataObject);
+            }
+
+            @Override
+            public void sceneRedo() throws CannotRedoException {
+                for (int i=0; i<actions.size(); i++) {
+                    PaintTerrainToolAction a = actions.get(i);
+                    a.applyTool(rootNode);
+                }
+                setModified(rootNode, dataObject);
+            }
+
+        };
+        if (manager != null) // this is a temporary check, it should never be null but occasionally is
+            manager.addEdit(this, undoer);
+    }
+    
+    protected void setModified(final AbstractSceneExplorerNode rootNode, final DataObject dataObject) {
+        if (dataObject.isModified())
+            return;
+        java.awt.EventQueue.invokeLater(new Runnable() {
+
+            public void run() {
+                dataObject.setModified(true);
+                rootNode.refresh(true);
+            }
+        });
+    }
 }
index 4188adc..a9cdcff 100644 (file)
@@ -43,7 +43,7 @@ import com.jme3.texture.Texture;
 import java.nio.ByteBuffer;
 
 /**
- * Paint the texture at the specified location.
+ * Paint or erase the texture at the specified location.
  * 
  * @author Brent Owens
  */
@@ -62,6 +62,10 @@ public class PaintTerrainToolAction extends AbstractTerrainToolAction {
         name = "Paint terrain";
     }
     
+    public Object applyTool(AbstractSceneExplorerNode rootNode) {
+        return doApplyTool(rootNode);
+    }
+    
     @Override
     protected Object doApplyTool(AbstractSceneExplorerNode rootNode) {
         Terrain terrain = getTerrain(rootNode.getLookup().lookup(Node.class));
index e4da780..c7cd5cd 100644 (file)
@@ -81,6 +81,7 @@ public abstract class TerrainTool {
     private Vector3f axis;
     private Meshes mesh;
     private final Map<Vector3f, Float> cachedMap = new HashMap<Vector3f, Float>(); // caching only
+    private boolean primary = true;
     
     public static enum Meshes {
         Box, Sphere
@@ -103,6 +104,14 @@ public abstract class TerrainTool {
         this.manager = manager;
         addMarkerPrimary(parent);
     }
+
+    public boolean isPrimary() {
+        return primary;
+    }
+
+    public void setPrimary(boolean primary) {
+        this.primary = primary;
+    }
     
     /**
      * The primary action for the tool gets activated
@@ -115,6 +124,12 @@ public abstract class TerrainTool {
     public abstract void actionSecondary(Vector3f point, int textureIndex, AbstractSceneExplorerNode rootNode, DataObject dataObject);
     
     /**
+     * The action has ended, record undo actions.
+     * Currently just implemented for Paint tool
+     */
+    public void actionEnded(AbstractSceneExplorerNode rootNode, DataObject dataObject) {}
+    
+    /**
      * Signals that this tool will or will not snap to fixed axis angles
      */
     protected boolean useStraightLine() {