/*
* Copyright © 2009-2011 Rebecca G. Bettencourt / Kreative Software
* <p>
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* <a href="http://www.mozilla.org/MPL/">http://www.mozilla.org/MPL/</a>
* <p>
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
* <p>
* Alternatively, the contents of this file may be used under the terms
* of the GNU Lesser General Public License (the "LGPL License"), in which
* case the provisions of LGPL License are applicable instead of those
* above. If you wish to allow use of your version of this file only
* under the terms of the LGPL License and not to allow others to use
* your version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the LGPL License. If you do not delete
* the provisions above, a recipient may use your version of this file
* under either the MPL or the LGPL License.
* @since PowerPaint 1.0
* @author Rebecca G. Bettencourt, Kreative Software
*/
package com.kreative.paint.tool;
import java.awt.Cursor;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.util.Random;
import com.kreative.paint.ToolContext;
import com.kreative.paint.document.tile.PaintSurface;
import com.kreative.paint.form.Form;
import com.kreative.paint.form.IntegerOption;
import com.kreative.paint.util.CursorUtils;
public class TwisterTool extends AbstractPaintTool implements ToolOptions.Custom {
private static final int K = 0xFF000000;
private static final int W = 0xFFFFFFFF;
private static final Image icon = ToolUtilities.makeIcon(
16, 16,
new int[] {
0,0,K,K,K,K,K,K,K,K,K,K,K,K,0,0,
K,K,K,0,0,0,0,0,0,0,0,0,K,K,K,K,
K,K,0,K,K,K,K,K,K,K,K,K,0,0,K,K,
0,K,K,K,K,K,0,0,0,0,K,K,K,K,K,0,
0,0,0,0,0,K,K,K,K,K,K,K,0,0,0,0,
0,0,0,0,0,0,0,K,K,K,K,K,0,0,0,0,
0,0,0,0,0,0,0,0,0,K,K,K,K,0,0,0,
0,0,0,0,0,0,0,0,0,0,K,K,K,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,K,K,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,K,K,0,0,0,
0,0,0,0,0,0,0,0,0,0,K,K,0,0,0,0,
0,0,0,0,0,0,0,0,0,K,K,0,0,0,0,0,
0,0,0,0,0,0,0,0,K,K,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,K,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,K,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,K,0,0,0,0,0,0,
}
);
private static final Cursor curs1 = CursorUtils.makeCursor(
18, 18,
new int[] {
0,0,0,W,W,W,W,W,W,W,W,W,W,W,W,0,0,0,
0,W,W,K,K,K,K,K,K,K,K,K,K,K,K,W,W,0,
W,K,K,K,W,W,W,W,W,W,W,W,W,K,K,K,K,W,
W,K,K,W,K,K,K,K,K,K,K,K,K,W,W,K,K,W,
0,W,K,K,K,K,K,W,W,W,W,K,K,K,K,K,W,0,
0,0,W,W,W,W,K,K,K,K,K,K,K,W,W,W,0,0,
0,0,0,0,0,0,W,W,K,K,K,K,K,W,0,0,0,0,
0,0,0,0,0,0,0,0,W,W,K,K,K,K,W,0,0,0,
0,0,0,0,0,0,0,0,0,0,W,K,K,K,W,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,W,K,K,W,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,W,K,K,W,0,0,0,
0,0,0,0,0,0,0,0,0,0,W,K,K,W,0,0,0,0,
0,0,0,0,0,0,0,0,0,W,K,K,W,0,0,0,0,0,
0,0,0,0,0,0,0,0,W,K,K,W,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,W,K,W,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,W,K,W,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,W,K,W,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
},
10, 16,
"Twister1"
);
private static final Cursor curs2 = CursorUtils.makeCursor(
18, 18,
new int[] {
0,0,0,W,W,W,W,W,W,W,W,W,W,W,W,0,0,0,
0,W,W,K,K,K,K,K,K,K,K,K,K,K,K,W,W,0,
W,K,K,K,W,W,W,W,W,W,W,W,W,K,K,K,K,W,
W,K,K,W,K,K,K,K,K,K,K,K,K,W,W,K,K,W,
0,W,K,K,K,K,K,W,W,W,W,K,K,K,K,K,W,0,
0,0,W,W,W,W,K,K,K,K,K,K,K,W,W,W,0,0,
0,0,0,0,0,W,K,K,K,K,K,W,W,0,0,0,0,0,
0,0,0,0,W,K,K,K,K,W,W,0,0,0,0,0,0,0,
0,0,0,0,W,K,K,K,W,0,0,0,0,0,0,0,0,0,
0,0,0,0,W,K,K,W,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,W,K,K,W,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,W,K,K,W,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,W,K,K,W,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,W,K,W,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,W,K,W,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,W,K,W,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,W,K,W,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
},
9, 16,
"Twister2"
);
public ToolCategory getCategory() {
return ToolCategory.MISC;
}
protected Image getBWIcon() {
return icon;
}
private boolean altCursor = false;
private int acache = 2;
public boolean mousePressed(ToolEvent e) {
e.beginTransaction(getName());
acache = e.tc().getCustom(TwisterTool.class, "twArea", Integer.class, 2);
twist(e.getPaintSurface(), e.getX(), e.getY(), acache);
altCursor = !altCursor;
return true;
}
public boolean mouseHeld(ToolEvent e) {
twist(e.getPaintSurface(), e.getX(), e.getY(), acache);
altCursor = !altCursor;
return true;
}
public boolean mouseDragged(ToolEvent e) {
twist(e.getPaintSurface(), e.getX(), e.getY(), acache);
altCursor = !altCursor;
return true;
}
public boolean mouseReleased(ToolEvent e) {
twist(e.getPaintSurface(), e.getX(), e.getY(), acache);
altCursor = false;
e.commitTransaction();
return true;
}
private static final Random random = new Random();
private static void twist(PaintSurface p, float x, float y, int size) {
int bx = (int)x-size/2;
int by = (int)y-size/2;
int[] rgb = new int[size*size];
p.getRGB(bx, by, size, size, rgb, 0, size);
for (int i = 0, n = rgb.length; i < rgb.length && n > 0; i++, n--) {
int j = i+random.nextInt(n);
int tmp = rgb[i];
rgb[i] = rgb[j];
rgb[j] = tmp;
}
p.setRGB(bx, by, size, size, rgb, 0, size);
}
public boolean keyPressed(ToolEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_1:
e.tc().setCustom(TwisterTool.class, "twArea", 2);
break;
case KeyEvent.VK_2:
e.tc().setCustom(TwisterTool.class, "twArea", 4);
break;
case KeyEvent.VK_3:
e.tc().setCustom(TwisterTool.class, "twArea", 8);
break;
case KeyEvent.VK_4:
e.tc().setCustom(TwisterTool.class, "twArea", 16);
break;
case KeyEvent.VK_5:
e.tc().setCustom(TwisterTool.class, "twArea", 32);
break;
case KeyEvent.VK_6:
e.tc().setCustom(TwisterTool.class, "twArea", 3);
break;
case KeyEvent.VK_7:
e.tc().setCustom(TwisterTool.class, "twArea", 6);
break;
case KeyEvent.VK_8:
e.tc().setCustom(TwisterTool.class, "twArea", 12);
break;
case KeyEvent.VK_9:
e.tc().setCustom(TwisterTool.class, "twArea", 24);
break;
case KeyEvent.VK_0:
e.tc().setCustom(TwisterTool.class, "twArea", 5);
break;
case KeyEvent.VK_MINUS:
case KeyEvent.VK_SUBTRACT:
e.tc().setCustom(TwisterTool.class, "twArea", 10);
break;
case KeyEvent.VK_EQUALS:
case KeyEvent.VK_ADD:
case KeyEvent.VK_PLUS:
e.tc().setCustom(TwisterTool.class, "twArea", 20);
break;
}
return false;
}
public Cursor getCursor(ToolEvent e) {
return altCursor ? curs2 : curs1;
}
public int getMouseHeldInterval() {
return 50;
}
public boolean shiftConstrainsCoordinates() {
return true;
}
public boolean doubleClickForOptions() {
return true;
}
public Form getCustomOptionsForm(final ToolContext tc) {
Form f = new Form();
f.add(new IntegerOption() {
public String getName() { return ToolUtilities.messages.getString("twister.options.Area"); }
public int getMaximum() { return Integer.MAX_VALUE; }
public int getMinimum() { return 1; }
public int getStep() { return 1; }
public int getValue() { return tc.getCustom(TwisterTool.class, "twArea", Integer.class, 2); }
public void setValue(int v) { tc.setCustom(TwisterTool.class, "twArea", v); }
public boolean useSlider() { return false; }
});
return f;
}
}