/* * 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.tools.brushes; import pixelitor.Composition; import pixelitor.tools.BrushType; import pixelitor.tools.Symmetry; import pixelitor.tools.Tool; import pixelitor.utils.debug.DebugNode; import java.awt.Graphics2D; /** * Delegates the work to other brushes according to the symmetry and brush type settings */ public class SymmetryBrush implements Brush { private static final int MAX_BRUSHES = 4; private final Brush[] brushes = new Brush[MAX_BRUSHES]; private int numInstantiatedBrushes; private final Tool tool; private BrushType brushType; private Symmetry symmetry; private final BrushAffectedArea affectedArea; public SymmetryBrush(Tool tool, BrushType brushType, Symmetry symmetry, int radius) { this.tool = tool; this.brushType = brushType; this.symmetry = symmetry; this.affectedArea = new BrushAffectedArea(); numInstantiatedBrushes = symmetry.getNumBrushes(); assert numInstantiatedBrushes <= MAX_BRUSHES; brushTypeChanged(brushType, radius); } public BrushAffectedArea getAffectedArea() { return affectedArea; } @Override public void setTarget(Composition comp, Graphics2D g) { for(int i = 0; i < numInstantiatedBrushes; i++) { brushes[i].setTarget(comp, g); } } @Override public void setRadius(int radius) { for(int i = 0; i < numInstantiatedBrushes; i++) { assert brushes[i] != null : "i = " + i + ", numInstantiatedBrushes = " + numInstantiatedBrushes; brushes[i].setRadius(radius); } } @Override public void onDragStart(double x, double y) { symmetry.onDragStart(this, x, y); } @Override public void onNewMousePoint(double x, double y) { symmetry.onNewMousePoint(this, x, y); } public void brushTypeChanged(BrushType brushType, int radius) { this.brushType = brushType; for(int i = 0; i < numInstantiatedBrushes; i++) { if(brushes[i] != null) { brushes[i].dispose(); } brushes[i] = brushType.createBrush(tool, radius); } assert checkThatAllBrushesAreDifferentInstances(); } public void symmetryChanged(Symmetry symmetry, int radius) { this.symmetry = symmetry; if(symmetry.getNumBrushes() > numInstantiatedBrushes) { // we need to create more brushes of the same type int newNumBrushes = symmetry.getNumBrushes(); assert newNumBrushes <= MAX_BRUSHES; for(int i = numInstantiatedBrushes; i < newNumBrushes; i++) { brushes[i] = brushType.createBrush(tool, radius); } numInstantiatedBrushes = newNumBrushes; } assert checkThatAllBrushesAreDifferentInstances(); } private boolean checkThatAllBrushesAreDifferentInstances() { for (int i = 0; i < numInstantiatedBrushes; i++) { for (int j = 0; j < numInstantiatedBrushes; j++) { if(i != j) { if(brushes[i] == brushes[j]) { return false; } } } } return true; } public void onDragStart(int brushNo, double x, double y) { affectedArea.updateAffectedCoordinates(x, y); brushes[brushNo].onDragStart(x, y); } public void onNewMousePoint(int brushNo, double endX, double endY) { affectedArea.updateAffectedCoordinates(endX, endY); brushes[brushNo].onNewMousePoint(endX, endY); } @Override public DebugNode getDebugNode() { DebugNode node = new DebugNode("Symmetry Brush", this); for (int i = 0; i < numInstantiatedBrushes; i++) { node.add(brushes[i].getDebugNode()); } node.addStringChild("Brush Type", brushType.toString()); node.addStringChild("Symmetry", symmetry.toString()); node.add(affectedArea.getDebugNode()); return node; } }