BoxHandleKit.java
/*
* @(#)BoxHandleKit.java
*
* Project: JHotdraw - a GUI framework for technical drawings
* http://www.jhotdraw.org
* http://jhotdraw.sourceforge.net
* Copyright: © by the original author(s) and all contributors
* License: Lesser GNU Public License (LGPL)
* http://www.opensource.org/licenses/lgpl-license.html
*/
package CH.ifa.draw.standard;
import CH.ifa.draw.framework.*;
import CH.ifa.draw.util.Undoable;
import CH.ifa.draw.util.UndoableAdapter;
import java.awt.*;
import java.util.Vector;
/**
* A set of utility methods to create Handles for the common
* locations on a figure's display box.
*
* @see Handle
*
* @version <$CURRENT_VERSION$>
*/
// TBD: use anonymous inner classes (had some problems with JDK 1.1)
public class BoxHandleKit {
/**
* Fills the given Vector with handles at each corner of a
* figure.
*/
static public void addCornerHandles(Figure f, Vector handles) {
handles.addElement(southEast(f));
handles.addElement(southWest(f));
handles.addElement(northEast(f));
handles.addElement(northWest(f));
}
/**
* Fills the given Vector with handles at each corner
* and the north, south, east, and west of the figure.
*/
static public void addHandles(Figure f, Vector handles) {
addCornerHandles(f, handles);
handles.addElement(south(f));
handles.addElement(north(f));
handles.addElement(east(f));
handles.addElement(west(f));
}
static public Handle south(Figure owner) {
return new SouthHandle(owner);
}
static public Handle southEast(Figure owner) {
return new SouthEastHandle(owner);
}
static public Handle southWest(Figure owner) {
return new SouthWestHandle(owner);
}
static public Handle north(Figure owner) {
return new NorthHandle(owner);
}
static public Handle northEast(Figure owner) {
return new NorthEastHandle(owner);
}
static public Handle northWest(Figure owner) {
return new NorthWestHandle(owner);
}
static public Handle east(Figure owner) {
return new EastHandle(owner);
}
static public Handle west(Figure owner) {
return new WestHandle(owner);
}
}
class ResizeHandle extends LocatorHandle {
ResizeHandle(Figure owner, Locator loc) {
super(owner, loc);
}
public void invokeStart(int x, int y, DrawingView view) {
setUndoActivity(createUndoActivity(view));
getUndoActivity().setAffectedFigures(new SingleFigureEnumerator(owner()));
((ResizeHandle.UndoActivity)getUndoActivity()).setOldDisplayBox(owner().displayBox());
}
public void invokeEnd(int x, int y, int anchorX, int anchorY, DrawingView view) {
Rectangle oldDisplayBox = ((ResizeHandle.UndoActivity)getUndoActivity()).getOldDisplayBox();
if (owner().displayBox().equals(oldDisplayBox)) {
// display box hasn't change so there is nothing to undo
setUndoActivity(null);
}
}
/**
* Factory method for undo activity. To be overriden by subclasses.
*/
protected Undoable createUndoActivity(DrawingView view) {
return new ResizeHandle.UndoActivity(view);
}
public static class UndoActivity extends UndoableAdapter {
private Rectangle myOldDisplayBox;
public UndoActivity(DrawingView newView) {
super(newView);
setUndoable(true);
setRedoable(true);
}
public boolean undo() {
if (!super.undo()) {
return false;
}
return resetDisplayBox();
}
public boolean redo() {
// do not call execute directly as the selection might has changed
if (!isRedoable()) {
return false;
}
return resetDisplayBox();
}
private boolean resetDisplayBox() {
FigureEnumeration fe = getAffectedFigures();
if (!fe.hasMoreElements()) {
return false;
}
Figure currentFigure = fe.nextFigure();
Rectangle figureDisplayBox = currentFigure.displayBox();
currentFigure.displayBox(getOldDisplayBox());
setOldDisplayBox(figureDisplayBox);
return true;
}
protected void setOldDisplayBox(Rectangle newOldDisplayBox) {
myOldDisplayBox = newOldDisplayBox;
}
public Rectangle getOldDisplayBox() {
return myOldDisplayBox;
}
}
}
class NorthEastHandle extends ResizeHandle {
NorthEastHandle(Figure owner) {
super(owner, RelativeLocator.northEast());
}
public void invokeStep (int x, int y, int anchorX, int anchorY, DrawingView view) {
Rectangle r = owner().displayBox();
owner().displayBox(
new Point(r.x, Math.min(r.y + r.height, y)),
new Point(Math.max(r.x, x), r.y + r.height)
);
}
}
class EastHandle extends ResizeHandle {
EastHandle(Figure owner) {
super(owner, RelativeLocator.east());
}
public void invokeStep (int x, int y, int anchorX, int anchorY, DrawingView view) {
Rectangle r = owner().displayBox();
owner().displayBox(
new Point(r.x, r.y), new Point(Math.max(r.x, x), r.y + r.height)
);
}
}
class NorthHandle extends ResizeHandle {
NorthHandle(Figure owner) {
super(owner, RelativeLocator.north());
}
public void invokeStep (int x, int y, int anchorX, int anchorY, DrawingView view) {
Rectangle r = owner().displayBox();
owner().displayBox(
new Point(r.x, Math.min(r.y + r.height, y)),
new Point(r.x + r.width, r.y + r.height)
);
}
}
class NorthWestHandle extends ResizeHandle {
NorthWestHandle(Figure owner) {
super(owner, RelativeLocator.northWest());
}
public void invokeStep (int x, int y, int anchorX, int anchorY, DrawingView view) {
Rectangle r = owner().displayBox();
owner().displayBox(
new Point(Math.min(r.x + r.width, x), Math.min(r.y + r.height, y)),
new Point(r.x + r.width, r.y + r.height)
);
}
}
class SouthEastHandle extends ResizeHandle {
SouthEastHandle(Figure owner) {
super(owner, RelativeLocator.southEast());
}
public void invokeStep (int x, int y, int anchorX, int anchorY, DrawingView view) {
Rectangle r = owner().displayBox();
owner().displayBox(
new Point(r.x, r.y),
new Point(Math.max(r.x, x), Math.max(r.y, y))
);
}
}
class SouthHandle extends ResizeHandle {
SouthHandle(Figure owner) {
super(owner, RelativeLocator.south());
}
public void invokeStep (int x, int y, int anchorX, int anchorY, DrawingView view) {
Rectangle r = owner().displayBox();
owner().displayBox(
new Point(r.x, r.y),
new Point(r.x + r.width, Math.max(r.y, y))
);
}
}
class SouthWestHandle extends ResizeHandle {
SouthWestHandle(Figure owner) {
super(owner, RelativeLocator.southWest());
}
public void invokeStep (int x, int y, int anchorX, int anchorY, DrawingView view) {
Rectangle r = owner().displayBox();
owner().displayBox(
new Point(Math.min(r.x + r.width, x), r.y),
new Point(r.x + r.width, Math.max(r.y, y))
);
}
}
class WestHandle extends ResizeHandle {
WestHandle(Figure owner) {
super(owner, RelativeLocator.west());
}
public void invokeStep (int x, int y, int anchorX, int anchorY, DrawingView view) {
Rectangle r = owner().displayBox();
owner().displayBox(
new Point(Math.min(r.x + r.width, x), r.y),
new Point(r.x + r.width, r.y + r.height)
);
}
}