use of org.pepsoft.util.undo.UndoManager in project WorldPainter by Captain-Chaos.
the class App method setDimension.
public void setDimension(final Dimension dimension) {
Configuration config = Configuration.getInstance();
if (this.dimension != null) {
this.dimension.removePropertyChangeListener(this);
Point viewPosition = view.getViewCentreInWorldCoords();
if (viewPosition != null) {
this.dimension.setLastViewPosition(viewPosition);
// in sync
if (world != null) {
Dimension oppositeDimension = null;
switch(this.dimension.getDim()) {
case DIM_NORMAL:
oppositeDimension = world.getDimension(DIM_NORMAL_CEILING);
break;
case DIM_NORMAL_CEILING:
oppositeDimension = world.getDimension(DIM_NORMAL);
break;
case DIM_NETHER:
oppositeDimension = world.getDimension(DIM_NETHER_CEILING);
break;
case DIM_NETHER_CEILING:
oppositeDimension = world.getDimension(DIM_NETHER);
break;
case DIM_END:
oppositeDimension = world.getDimension(DIM_END_CEILING);
break;
case DIM_END_CEILING:
oppositeDimension = world.getDimension(DIM_END);
break;
}
if (oppositeDimension != null) {
oppositeDimension.setLastViewPosition(viewPosition);
}
}
}
this.dimension.unregister();
currentUndoManager.unregisterActions();
currentUndoManager = null;
// currently in use
if (!paletteManager.isEmpty()) {
List<CustomLayer> customLayers = new ArrayList<>();
boolean visibleLayersChanged = false;
for (Palette palette : paletteManager.clear()) {
List<CustomLayer> paletteLayers = palette.getLayers();
customLayers.addAll(paletteLayers);
for (Layer layer : paletteLayers) {
if (hiddenLayers.contains(layer)) {
hiddenLayers.remove(layer);
visibleLayersChanged = true;
}
if (layer.equals(soloLayer)) {
soloLayer = null;
visibleLayersChanged = true;
}
}
dockingManager.removeFrame(palette.getDockableFrame().getKey());
}
if (visibleLayersChanged) {
updateLayerVisibility();
}
layerSoloCheckBoxes.clear();
this.dimension.setCustomLayers(customLayers);
} else {
this.dimension.setCustomLayers(Collections.EMPTY_LIST);
}
layersWithNoButton.clear();
saveCustomBiomes();
}
this.dimension = dimension;
if (dimension != null) {
// NOI18N
setTitle("WorldPainter - " + world.getName() + " - " + dimension.getName());
viewSurfaceMenuItem.setSelected(dimension.getDim() == DIM_NORMAL);
viewSurfaceCeilingMenuItem.setSelected(dimension.getDim() == DIM_NORMAL_CEILING);
viewNetherMenuItem.setSelected(dimension.getDim() == DIM_NETHER);
viewNetherCeilingMenuItem.setSelected(dimension.getDim() == DIM_NETHER_CEILING);
viewEndMenuItem.setSelected(dimension.getDim() == DIM_END);
viewEndCeilingMenuItem.setSelected(dimension.getDim() == DIM_END_CEILING);
// neglected to do it automatically)
if (dimension.isFixOverlayCoords()) {
Toolkit.getDefaultToolkit().beep();
if (showConfirmDialog(this, "This world was created in an older version of WorldPainter\n" + "in which the overlay offsets were not stored correctly.\n" + "Do you want WorldPainter to fix the offsets now?\n" + "\n" + "If you already manually fixed the offsets using version 1.9.0\n" + "or 1.9.1 of WorldPainter, say no. If you're unsure, say yes.", "Fix Overlay Offset?", YES_NO_OPTION, QUESTION_MESSAGE) != NO_OPTION) {
dimension.setOverlayOffsetX(dimension.getOverlayOffsetX() + dimension.getLowestX() << TILE_SIZE_BITS);
dimension.setOverlayOffsetY(dimension.getOverlayOffsetY() + dimension.getLowestY() << TILE_SIZE_BITS);
}
dimension.setFixOverlayCoords(false);
}
view.setDimension(dimension);
view.moveTo(dimension.getLastViewPosition());
setDimensionControlStates(world.getPlatform());
if ((!"true".equals(System.getProperty("org.pepsoft.worldpainter.disableUndo"))) && config.isUndoEnabled()) {
currentUndoManager = undoManagers.get(dimension.getDim());
if (currentUndoManager == null) {
currentUndoManager = new UndoManager(ACTION_UNDO, ACTION_REDO, Math.max(config.getUndoLevels() + 1, 2));
undoManagers.put(dimension.getDim(), currentUndoManager);
currentUndoManager.setStopAtClasses(PropertyChangeListener.class, Tile.Listener.class, Biome.class, BetterAction.class);
dimension.register(currentUndoManager);
} else {
currentUndoManager.registerActions(ACTION_UNDO, ACTION_REDO);
}
dimension.armSavePoint();
} else {
// Still install an undo manager, because some operations depend
// on one level of undo being available
currentUndoManager = new UndoManager(2);
currentUndoManager.setStopAtClasses(PropertyChangeListener.class, Tile.Listener.class, Biome.class, BetterAction.class);
dimension.register(currentUndoManager);
ACTION_UNDO.setEnabled(false);
ACTION_REDO.setEnabled(false);
}
if (threeDeeFrame != null) {
threeDeeFrame.setDimension(dimension);
}
// Add the custom object layers from the world
StringBuilder warnings = new StringBuilder();
for (CustomLayer customLayer : dimension.getCustomLayers()) {
if (customLayer.isHide()) {
layersWithNoButton.add(customLayer);
} else {
registerCustomLayer(customLayer, false);
}
if (customLayer instanceof CombinedLayer) {
if (!((CombinedLayer) customLayer).restoreCustomTerrain()) {
if (warnings.length() == 0) {
warnings.append("The Custom Terrain for one or more Combined Layer could not be restored:\n\n");
}
warnings.append(customLayer.getName()).append('\n');
} else {
// Check for a custom terrain type and if necessary make
// sure it has a button
Terrain terrain = ((CombinedLayer) customLayer).getTerrain();
if ((terrain != null) && terrain.isCustom() && (customMaterialButtons[terrain.getCustomTerrainIndex()] == null)) {
addButtonForNewCustomTerrain(terrain.getCustomTerrainIndex(), Terrain.getCustomMaterial(terrain.getCustomTerrainIndex()), false);
}
}
}
}
if (warnings.length() > 0) {
warnings.append("\nThe Custom Terrain has been removed from the layer(s).");
showMessageDialog(this, warnings.toString(), "Custom Terrain(s) Not Restored", ERROR_MESSAGE);
}
// Set action states
ACTION_GRID.setSelected(view.isPaintGrid());
ACTION_CONTOURS.setSelected(view.isDrawContours());
ACTION_OVERLAY.setSelected(view.isDrawOverlay());
// TODO: make this work correctly with undo/redo, and make "inside selection" ineffective when there is no selection, to avoid confusion
// Set operation states
// if (dimension.containsOneOf(SelectionChunk.INSTANCE, SelectionBlock.INSTANCE)) {
// selectionState.setValue(true);
// } else {
// if (activeOperation instanceof CopySelectionOperation) {
// deselectTool();
// }
// selectionState.setValue(false);
// }
// Load custom biomes. But first remove any that are now regular
// biomes
List<CustomBiome> customBiomes = dimension.getCustomBiomes();
if (customBiomes != null) {
for (Iterator<CustomBiome> i = customBiomes.iterator(); i.hasNext(); ) {
CustomBiome customBiome = i.next();
if (autoBiomeScheme.isBiomePresent(customBiome.getId())) {
i.remove();
}
}
if (customBiomes.isEmpty()) {
customBiomes = null;
}
}
programmaticChange = true;
try {
customBiomeManager.setCustomBiomes(customBiomes);
} finally {
programmaticChange = false;
}
dimension.addPropertyChangeListener(this);
} else {
view.setDimension(null);
// NOI18N
setTitle("WorldPainter");
// Clear action states
ACTION_GRID.setSelected(false);
ACTION_CONTOURS.setSelected(false);
ACTION_OVERLAY.setSelected(false);
// Close the 3D view
if (threeDeeFrame != null) {
threeDeeFrame.dispose();
threeDeeFrame = null;
}
// Clear status bar
locationLabel.setText(strings.getString("location-"));
heightLabel.setText(" ");
waterLabel.setText(" ");
biomeLabel.setText(" ");
materialLabel.setText(" ");
// Deselect any current operation
if (activeOperation != null) {
deselectTool();
}
// TODO: make this work correctly with undo/redo, and make "inside selection" ineffective when there is no selection, to avoid confusion
// Disable copy selection operation
// selectionState.setValue(false);
programmaticChange = true;
try {
customBiomeManager.setCustomBiomes(null);
} finally {
programmaticChange = false;
}
}
}
use of org.pepsoft.util.undo.UndoManager in project WorldPainter by Captain-Chaos.
the class RiverGenerator method generateRivers.
public void generateRivers() {
dimension.setEventsInhibited(true);
UndoManager undoManager = new UndoManager(2);
dimension.register(undoManager);
snapshot = dimension.getSnapshot();
dimension.armSavePoint();
garden = dimension.getGarden();
try {
dimension.getTiles().forEach(this::generateRivers);
// Grow seeds until all activity has ceased
while (!garden.tick()) ;
// Apply the river nodes to the landscape
// A river source
dimension.getGarden().getSeeds().stream().filter(seed -> (seed instanceof RiverNode) && (seed.getParent() == null)).forEach(seed -> {
// A river source
((RiverNode) seed).apply(dimension, snapshot, new HashSet<>());
});
} finally {
garden = null;
snapshot = null;
dimension.unregister();
dimension.setEventsInhibited(false);
}
}
Aggregations