package uk.ac.leeds.ccg.geotools;
import uk.ac.leeds.ccg.geotools.*;
import java.awt.*;
/**
* An abstract implemtation of the Tool interface.
* This class provides some base functionality that might be useful to a wide range of tools
* and extending it would make the life of a tool developer much easier.
* Essentialy this call splits the update(reason) method into seperate calls, defalt versions of
* which are provided.
* The class also provides some simple rubber band tools that can be used by extending classes automaticaly.
* In order to make a concrete extention of this class all that is needed is a getCursor and a getRubberBandShape method
* although such a tool would not actualy do anything.
*
* @author James Macgill JM
* @since 0.7.7.2 07 June 2000
*/
public abstract class SimpleTool implements uk.ac.leeds.ccg.geotools.Tool
{
/**
* All tools only operate on one viewer at a time. This variable holds a reference to
* that viewer.
*/
protected Viewer context;
/**
* A reference to a Graphics object onto which tools can place tempory graphics.
*/
Graphics toolGraphics;
/**
* Tracks at all times, the mouse status for the viewer this tool is attached to.
* Provides information on mouse movments and drag regions in screen, geographic and projected space.
*/
protected MouseStatus mouse;
/**
* RubberBandShape constant
*/
public static final int NONE=-1,CIRCLE=1,RECTANGLE=2,LINE=3;
/**
* Locks the rubber bands to boxes and circles instead of ellipes and rectangles.
*/
protected boolean lockAspect = false;
public void setLockAspect(boolean flag){
lockAspect = flag;
}
public boolean isLockAspect(){
return lockAspect;
}
/**
* Retun one of the above constants to specify which rubber band should be
* automaticaly displayed during mouse drag events.
* @return int A value from above representing a circle, rectangle or line (or none)
*/
public abstract int getRubberBandShape();
/**
* called by the viewer which has recived this tool in order to set that viewer
* as the context for this tool.
*
It also initalizes the mouse status object. Once set up mouse provides useful features for
* querying user acctions. e.g. mouse.getScreenDragBox() mouse.getMapDragBox();
* @param v The viewer to which this tool should now be attached.
*/
public void setContext(Viewer v)
{
context = v;
mouse = context.getMouseStatus();
}
/**
* Called by the viewer to which the tool is attached (context)
* The tool uses this to update its display and behavior based on the reason code passed in
* and current mouse status.
*
* The method rebradcasts the reason code to seperate methods:
* clear()
* drag()
* release()
* click()
*
* @author James Macgill JM
* @since 0.7.7.2 07 June 2000
*
* @param g A Graphics object that cen be used for transient tool graphics. It is pre set to XORMode.
* @param reason An int that references the reason why this method has been called.
*/
public void update(Graphics g,int reason)
{
toolGraphics = g;
switch(reason){
case CLEAR:
clear();
break;
case M_DRAG:
drag();
break;
case M_RELEASE:
release();
break;
case M_CLICK:
clear();
click();
break;
}
}
/**
* A default implemention of the percistent paint method.
* most tools will NOT need to overide this method and can instead use the
* toolGraphics object set up in the update method.
*
* @author James Macgill JM
* @since 0.7.7.2 07 June 2000
* @param g A Graphics object that references the viewers static buffer.
*/
public void paint(Graphics g){
//do nothing
}
/**
* Called by update when the reason code is DRAG.
* Provides automatic suport for drawing a 'rubber band' of the shape specified by getRubberBandShape().
* @author James Macgill JM
* @since 0.7.7.2 07 june 2000
*/
public void drag(){
if(!mouse.isDragStart()){
clear();
}
drawRubberBand(context.getMouseStatus().getScreenDragBox());
}
/**
* Called when update is called with reason code CLICK.
* This default implementation does nothing, overide to add behavior.
* @author James Macgill
* @since 0.7.7.2 07 June 2000
*/
public void click(){
//do nothing
}
/**
* Called when update is called with reason code RELEASE.
* This default implementaion calls clear() to remove any rubberBand marks, overide to add behavior but try to call clean
* @author James Macgill
* @since 0.7.7.2 07 June 2000
*/
public void release(){
clear();
//do nothing
}
/**
* Called when update is called with reason code CLEAR whenever the old rubber band needs to be removed.
*
* @author James Macgill
* @since 0.7.7.2 07 June 2000
*/
public void clear(){
drawRubberBand(context.getMouseStatus().getOldScreenDragBox());
}
/**
* Uses XOR painting (preset in the toolGraphics) to draw a removable shape to the screen.
* @author James Macgill
* @since 0.7.7.2 07 June 2000
* @param box A Rectangle defining the start and finish points of the rubber band to draw.
*/
public void drawRubberBand(Rectangle box){
toolGraphics.setColor(Color.red);
toolGraphics.setXORMode(Color.blue);
int x,y,width,height;
x = box.x;
y = box.y;
if(lockAspect){
width = height = Math.max(box.width,box.height);
}
else{
width = box.width;
height = box.height;
}
switch(getRubberBandShape()){
case RECTANGLE:
toolGraphics.drawRect(x,y,width,height);
break;
case CIRCLE:
toolGraphics.drawOval(x-width,y-height,width*2,height*2);
break;
case LINE:
toolGraphics.drawLine(x,y,width,height);
break;
}
toolGraphics.setPaintMode();
}
}