terrain paint tool remembers undo history as an entire mouseDown event now. RMB now erases
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10473 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
32e6516a47
commit
ef700eff19
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -105,33 +105,44 @@ public class TerrainCameraController extends AbstractCameraController {
|
||||
|
||||
@Override
|
||||
protected void checkClick(int button, boolean pressed) {
|
||||
|
||||
/*if (button == 0) {
|
||||
if (isTerrainEditButtonEnabled() && !forceCameraControls) {
|
||||
terrainEditToolActivated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (button == 1) {
|
||||
if (isTerrainEditButtonEnabled() && !forceCameraControls) {
|
||||
toolController.doTerrainEditToolAlternateActivated();
|
||||
}
|
||||
}*/
|
||||
|
||||
if (button == 1) {
|
||||
if (isTerrainEditButtonEnabled() && !forceCameraControls) {
|
||||
toolController.doTerrainEditToolAlternateActivated();
|
||||
}
|
||||
}
|
||||
checkMouseButtonState(button, pressed);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void checkDragged(int button, boolean pressed) {
|
||||
if (button == 0 && !forceCameraControls) {
|
||||
terrainEditToolActivated = true;
|
||||
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 (isTerrainEditButtonEnabled() && !forceCameraControls) {
|
||||
toolController.setPrimary(pressed);
|
||||
System.out.println("primary "+pressed);
|
||||
}
|
||||
}
|
||||
|
||||
if (button == 1) {
|
||||
if (isTerrainEditButtonEnabled() && !forceCameraControls) {
|
||||
toolController.setAlternate(pressed);
|
||||
System.out.println("alternate "+pressed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*@Override
|
||||
protected void checkDragged(int button, boolean pressed) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
@ -254,7 +254,7 @@
|
||||
<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>
|
||||
@ -462,28 +462,6 @@
|
||||
<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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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">
|
||||
@ -498,6 +476,7 @@
|
||||
<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, "{key}")"/>
|
||||
</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"/>
|
||||
@ -520,7 +499,6 @@
|
||||
<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, "{key}")"/>
|
||||
</Property>
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -32,28 +32,82 @@
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
@ -114,6 +123,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
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user