// **********************************************************************
//
// <copyright>
//
// BBN Technologies
// 10 Moulton Street
// Cambridge, MA 02138
// (617) 873-8000
//
// Copyright (C) BBNT Solutions LLC. All rights reserved.
//
// </copyright>
// **********************************************************************
//
// $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/omGraphics/EditableOMGraphicList.java,v $
// $RCSfile: EditableOMGraphicList.java,v $
// $Revision: 1.2.2.2 $
// $Date: 2006/08/09 21:01:12 $
// $Author: dietrick $
//
// **********************************************************************
package com.bbn.openmap.omGraphics;
import java.awt.event.MouseEvent;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import com.bbn.openmap.omGraphics.editable.*;
import com.bbn.openmap.proj.Projection;
import com.bbn.openmap.tools.drawing.OMDrawingTool;
import com.bbn.openmap.util.Debug;
/**
* An EditableOMGraphic list encapsulates an OMGraphicList to move the
* editable ones around when they are selected as a group.
*/
public class EditableOMGraphicList extends EditableOMGraphic {
/**
* For grabing the list objects and moving them.
*/
protected OffsetGrabPoint gpm;
/**
* The list of OMGraphics being selected and moved.
*/
protected OMGraphicList list;
/**
* The list of editables wrapping the list contents.
*/
protected List editables;
/**
* Create an empty EditableOMGraphicList, ready to have OMGraphics
* added to it.
*/
public EditableOMGraphicList() {
this(new OMGraphicList());
}
/**
* Create the EditableOMGraphicList with an OMGraphicList already
* defined, ready for editing.
*
* @param oml OMGraphicList that should be handled.
*/
public EditableOMGraphicList(OMGraphicList oml) {
setGraphic(oml);
}
public List getEditables() {
if (editables == null) {
editables = new LinkedList();
}
return editables;
}
/**
* Create and initialize the state machine that interprets the
* modifying gestures/commands, as well as ititialize the grab
* points. Also allocates the grab point array needed by the
* EditableOMGraphicList.
*/
public void init() {
Debug.message("eomg", "EditableOMGraphicList.init()");
getEditables();
setStateMachine(new ListStateMachine(this));
}
/**
* Must be called on a EditableOMGraphicList that is created from
* an OMGraphicList containing OMGraphics.
*
* @param drawingTool OMDrawingTool used to create
* EditableOMGraphics for other OMGraphics on the list,
* which will in turn be managed by this
* EditableOMGraphicList. If this is null, nothing will get
* done. If this drawing tool doesn't know how to create an
* EditableOMGraphic for anything on the list, those things
* will not be managed.
*/
public void init(OMDrawingTool drawingTool) {
if (list != null) {
for (Iterator it = list.iterator(); it.hasNext();) {
OMGraphic omg = (OMGraphic) it.next();
// Do we need to handle OMGraphicLists in a special
// way?
if (omg.isVisible()) {
add(omg, drawingTool);
}
}
}
}
public GrabPoint[] getGrabPoints() {
return new GrabPoint[] { gpm };
}
/**
* Set the graphic within the state machine. If the graphic is
* null, then one shall be created, and located off screen until
* the gestures driving the state machine place it on the map.
*/
public void setGraphic(OMGraphic graphic) {
init();
if (graphic instanceof OMGraphicList) {
list = (OMGraphicList) graphic;
list.setProcessAllGeometries(true);
stateMachine.setSelected();
gpm = new OffsetGrabPoint(-10, -10);
} else {
createGraphic(null);
}
}
/**
* Create and set the graphic within the state machine. The
* GraphicAttributes describe the type of line to create.
*/
public void createGraphic(GraphicAttributes ga) {
init();
stateMachine.setUndefined();
OMGraphicList tmpList = new OMGraphicList();
if (ga != null) {
ga.setTo(tmpList);
}
setGraphic(tmpList);
}
/**
* Get the OMGraphic being created/modified by the
* EditableOMGraphicList.
*/
public OMGraphic getGraphic() {
return list;
}
public void add(OMGraphicList list, OMDrawingTool drawingTool) {
for (Iterator it = list.iterator(); it.hasNext();) {
add((OMGraphic) it.next(), drawingTool);
}
}
/**
* Create an EditableOMGraphic and add it to the list.
*
* @param omg OMGraphic to add.
* @param drawingTool to use to figure out what EditableOMGraphic
* to use for the OMGraphic.
* @return EditableOMGraphic if successful, null if not.
*/
public EditableOMGraphic add(OMGraphic omg, OMDrawingTool drawingTool) {
EditableOMGraphic editable = null;
if (omg instanceof OMGraphicList) {
add((OMGraphicList) omg, drawingTool);
return editable;
}
if (omg != null && drawingTool != null) {
// The OMDrawingTool knows how to create an
// EditableOMGraphic for the omg
editable = drawingTool.getEditableGraphic(omg);
if (editable != null) {
add(editable);
} else {
if (Debug.debugging("eomg")) {
Debug.output("EditableOMGraphicList can't handle "
+ omg.getClass().getName());
}
}
} else {
if (Debug.debugging("eomg")) {
Debug.output("EditableOMGraphicList told to add null OMGraphic or null OMDrawingTool");
}
}
return editable;
}
/**
* Add the EditableOMGraphic to the list.
*/
public void add(EditableOMGraphic editable) {
if (editable == null) {
if (Debug.debugging("eomg")) {
Debug.output("EditableOMGraphicList adding null EditableOMGraphic");
}
return;
}
if (Debug.debugging("eomg")) {
Debug.output("EditableOMGraphicList adding "
+ editable.getClass().getName() + " " + editable);
}
OMGraphic graphic = editable.getGraphic();
if (!list.contains(graphic)) {
getEditables().add(editable);
editable.setProjection(getProjection());
// Need this for distance measurements.
list.add(graphic);
editable.attachToMovingGrabPoint(gpm);
} else {
if (Debug.debugging("eomg")) {
Debug.output("EditableOMGraphicList.add("
+ editable.getClass().getName()
+ ") not added, duplicate");
}
}
}
/**
* Remove an OMGraphic from being moved.
*/
public void remove(OMGraphic omg) {
EditableOMGraphic eomg = null;
for (Iterator it = getEditables().iterator(); it.hasNext();) {
eomg = (EditableOMGraphic) it.next();
if (eomg.getGraphic() == omg) {
break;
}
eomg = null;
}
// If we found the eomg for the omg, we broke out of the loop above and
// eomg is set to something.
if (eomg != null) {
remove(eomg);
list.remove(omg);
}
}
/**
* Remove the EditableOMGraphic from the list.
*/
public boolean remove(EditableOMGraphic editable) {
if (editable == null) {
if (Debug.debugging("eomg")) {
Debug.output("EditableOMGraphicList removing null EditableOMGraphic");
}
return false;
}
if (Debug.debugging("eomg")) {
Debug.output("EditableOMGraphicList removing "
+ editable.getClass().getName());
}
editable.setProjection(null);
editable.detachFromMovingGrabPoint(gpm);
boolean ret = getEditables().remove(editable);
return ret;
}
/**
* Remove all EditableOMGraphics and clear out.
*/
public void clear() {
// list.processAllGeometries(false);
// list.clear();
// list = null;
getEditables().clear();
gpm.clear();
}
/**
* Set the current projection.
*/
public void setProjection(Projection proj) {
if (Debug.debugging("eomg")) {
Debug.output("EOMGL: setProjection(" + proj + ")");
}
super.setProjection(proj);
for (Iterator it = getEditables().iterator(); it.hasNext();) {
((EditableOMGraphic) it.next()).setProjection(proj);
}
}
/**
* Take the current location of the GrabPoints, and modify the
* location parameters of the OMLine with them. Called when you
* want the graphic to change according to the grab points.
*/
public void setGrabPoints() {
for (Iterator it = getEditables().iterator(); it.hasNext();) {
EditableOMGraphic editable = (EditableOMGraphic) it.next();
editable.setGrabPoints();
// if (Debug.debugging("eomg")) {
// Debug.output(" -- setting GrabPoints on " +
// editable.getClass().getName());
// }
}
}
public GrabPoint getMovingPoint(MouseEvent me) {
// For the EdtiableOMGraphicList, this should just go ahead
// and test for contact for anything on the OMGraphicList, and
// return the gpm for that point.
if (list != null) {
float distance = list.distance(me.getX(), me.getY());
if (distance <= 4) {
// will set movingPoint
move(me);
} else {
// int count = 0;
// for (Iterator it = list.iterator(); it.hasNext();)
// {
// OMGraphic omg = (OMGraphic)it.next();
// Debug.output(" graphic " + (count++) + " distance("
// +
// omg.distance(me.getX(), me.getY()) + ") ntbr: " +
// omg.getNeedToRegenerate());
// }
movingPoint = null;
}
} else {
// Debug.output("EOMGL.getMovingPoint() null list");
movingPoint = null;
}
return movingPoint;
}
/**
* Called to set the OffsetGrabPoint to the current mouse
* location, and update the OffsetGrabPoint with all the other
* GrabPoint locations, so everything can shift smoothly. Should
* also set the OffsetGrabPoint to the movingPoint. Should be
* called only once at the beginning of the general movement, in
* order to set the movingPoint. After that, redraw(e) should just
* be called, and the movingPoint will make the adjustments to the
* graphic that are needed.
*/
public void move(MouseEvent e) {
if (gpm != null) {
gpm.set(e.getX(), e.getY());
gpm.updateOffsets();
movingPoint = gpm;
}
}
/**
* Use the current projection to place the graphics on the screen.
* Has to be called to at least assure the graphics that they are
* ready for rendering. Called when the graphic position changes.
*
* @param proj com.bbn.openmap.proj.Projection
* @return true
*/
public boolean generate(Projection proj) {
Debug.message("eomg", "EditableOMGraphicList.generate()");
for (Iterator it = getEditables().iterator(); it.hasNext();) {
((EditableOMGraphic) it.next()).generate(proj);
}
if (gpm != null)
gpm.generate(proj);
return true;
}
/**
* Given a new projection, the grab points may need to be
* repositioned off the current position of the graphic. Called
* when the projection changes.
*/
public void regenerate(Projection proj) {
Debug.message("eomg", "EditableOMGraphicList.regenerate()");
for (Iterator it = getEditables().iterator(); it.hasNext();) {
((EditableOMGraphic) it.next()).regenerate(proj);
}
if (gpm != null)
gpm.generate(proj);
}
/**
* Draw the EditableOMGraphicList parts into the java.awt.Graphics
* object. The grab points are only rendered if the line machine
* state is LineSelectedState.LINE_SELECTED.
*
* @param graphics java.awt.Graphics.
*/
public void render(java.awt.Graphics graphics) {
for (Iterator it = getEditables().iterator(); it.hasNext();) {
((EditableOMGraphic) it.next()).render(graphics);
}
}
}