/*
* Copyright 2017 Laszlo Balazs-Csiki
*
* This file is part of Pixelitor. Pixelitor is free software: you
* can redistribute it and/or modify it under the terms of the GNU
* General Public License, version 3 as published by the Free
* Software Foundation.
*
* Pixelitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Pixelitor. If not, see <http://www.gnu.org/licenses/>.
*/
package pixelitor.history;
import pixelitor.Composition;
import pixelitor.layers.ContentLayer;
import pixelitor.layers.ImageLayer;
import pixelitor.layers.Layer;
import pixelitor.selection.IgnoreSelection;
import java.awt.Shape;
import java.awt.image.BufferedImage;
/**
* Encapsulates the state needed by a MultiLayerEdit
*/
public class MultiLayerBackup {
private final Composition comp;
private final String editName;
private Layer layer;
private CanvasChangeEdit canvasChangeEdit;
private TranslationEdit translationEdit;
private final Shape backupShape;
// Saved before the change, but the edit is
// created after the change.
// This way no image copy is necessary.
private BufferedImage backupImage;
private BufferedImage backupMaskImage;
/**
* This object needs to be created before the translations,
* canvas changes or selection changes take place
*/
public MultiLayerBackup(Composition comp, String editName, boolean changesCanvasDimensions) {
this.comp = comp;
this.editName = editName;
// save canvas dimensions
if (changesCanvasDimensions) {
canvasChangeEdit = new CanvasChangeEdit(comp, editName);
}
// save translation
ContentLayer contentLayer = comp.getAnyContentLayer();
if (contentLayer != null) { // could be null, if there are only adj layers - TODO allowed?
translationEdit = new TranslationEdit(comp, contentLayer, true);
}
// save selection
backupShape = comp.getSelectionShape();
// save backup images
boolean imageLayerFound = false;
int numLayers = comp.getNumLayers();
for (int i = 0; i < numLayers; i++) {
Layer compLayer = comp.getLayer(i);
if (compLayer instanceof ImageLayer) {
imageLayerFound = true;
ImageLayer imageLayer = (ImageLayer) compLayer;
this.layer = imageLayer;
backupImage = imageLayer.getImage();
if (imageLayer.hasMask()) {
backupMaskImage = imageLayer.getMask().getImage();
}
break;
}
}
if (!imageLayerFound) {
if (contentLayer != null) {
layer = contentLayer;
if (contentLayer.hasMask()) {
backupMaskImage = contentLayer.getMask().getImage();
}
} else {
// we must have a single adj layer
// TODO why is this allowed??
layer = comp.getLayer(0);
backupMaskImage = layer.getMask().getImage();
}
}
assert layer != null;
}
public CanvasChangeEdit getCanvasChangeEdit() {
return canvasChangeEdit;
}
public TranslationEdit getTranslationEdit() {
return translationEdit;
}
public boolean hasSavedSelection() {
return backupShape != null;
}
public ImageEdit createImageEdit(BufferedImage currentImage, BufferedImage currentMaskImage) {
assert backupImage != null;
assert layer instanceof ImageLayer;
ImageLayer imageLayer = (ImageLayer) layer;
if (currentImage == backupImage && backupMaskImage == currentMaskImage) {
// for enlarge canvas with big layer it can happen that
// the image does not need to be changed at all
return null;
}
ImageEdit edit;
if (backupMaskImage != null) {
edit = new ImageAndMaskEdit(comp, editName, imageLayer,
backupImage, backupMaskImage, false);
} else {
edit = new ImageEdit(comp, editName, imageLayer,
backupImage, IgnoreSelection.YES, false);
}
edit.setEmbedded(true);
return edit;
}
public ImageEdit createImageEditForMaskOnly(BufferedImage currentMaskImage) {
if (backupMaskImage == currentMaskImage) {
return null;
}
ImageEdit edit = new ImageEdit(comp, editName, layer.getMask(),
backupMaskImage, IgnoreSelection.YES, false);
edit.setEmbedded(true);
return edit;
}
public SelectionChangeEdit createSelectionChangeEdit() {
assert backupShape != null;
SelectionChangeEdit edit = new SelectionChangeEdit(comp, backupShape, editName);
edit.setEmbedded(true);
return edit;
}
public DeselectEdit createDeselectEdit() {
assert backupShape != null;
DeselectEdit edit = new DeselectEdit(comp, backupShape, editName);
edit.setEmbedded(true);
return edit;
}
}