/*
* Copyright 2016 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.menus;
import pixelitor.gui.ImageComponents;
import pixelitor.gui.utils.Dialogs;
import pixelitor.layers.AdjustmentLayer;
import pixelitor.layers.ImageLayer;
import pixelitor.layers.Layer;
import pixelitor.layers.TextLayer;
import pixelitor.utils.Messages;
import pixelitor.utils.test.RandomGUITest;
import javax.swing.*;
import java.awt.event.ActionEvent;
/**
* An abstraction for a task that can be done only with image layers (or masks)
*/
public abstract class ImageLayerAction extends AbstractAction {
protected final String name;
protected String menuName;
protected boolean hasDialog;
private final boolean allowMasks;
protected ImageLayerAction(String name) {
this(name, true, true);
}
protected ImageLayerAction(String name, boolean hasDialog) {
this(name, hasDialog, true);
}
protected ImageLayerAction(String name, boolean hasDialog, boolean allowMasks) {
this.hasDialog = hasDialog;
assert name != null;
this.name = name;
this.menuName = hasDialog ? name + "..." : name;
setActionName(menuName);
this.allowMasks = allowMasks;
}
/**
* This callback method represents the task that has to be done.
* It gets called only if we know that the active layer is
* an image layer or if it was rasterized into an image layer.
*/
protected abstract void process(ImageLayer layer);
@Override
public void actionPerformed(ActionEvent e) {
try {
ImageComponents.onActiveLayer(this::startOnLayer);
} catch (Exception ex) {
Messages.showException(ex);
}
}
private void startOnLayer(Layer layer) {
if (layer.isMaskEditing()) {
if (allowMasks) {
process(layer.getMask());
} else {
if (!RandomGUITest.isRunning()) {
Dialogs.showErrorDialog("Mask is active",
name + " cannot be applied to masks.");
}
}
} else if (layer instanceof ImageLayer) {
process((ImageLayer) layer);
} else if (layer instanceof TextLayer) {
if (RandomGUITest.isRunning()) {
return;
}
boolean isNoun = name.contains("Tool");
String firstName = isNoun ? "The " + name : name;
String secondName = isNoun ? "the " + name : name;
String msg = String.format("The active layer \"%s\" is a text layer.\n" +
"%s needs pixels and cannot be used on text layers.\n" +
"If you rasterize this text layer, you can use %s,\n" +
"but the text will no longer be editable.",
layer.getName(), firstName, secondName);
String[] options = {"Rasterize", "Cancel"};
if (Dialogs.showOKCancelWarningDialog(msg, "Text Layer", options, 1)) {
ImageLayer newImageLayer = ((TextLayer) layer).replaceWithRasterized();
process(newImageLayer);
}
} else if (layer instanceof AdjustmentLayer) {
Dialogs.showErrorDialog("Adjustment Layer",
name + " cannot be applied to adjustment layers.");
} else {
throw new IllegalStateException("layer is " + layer.getClass().getSimpleName());
}
}
public String getMenuName() {
return menuName;
}
public String getName() {
return name;
}
public void setActionName(String newName) {
putValue(AbstractAction.NAME, newName);
}
}