Hi,
here are classes, which support grouping. To use them create a groupmap an add a groupcommand. Enjoy!
Next Step is a GroupRotator with the described effect above.
GroupStackMetrics .java
[code]package VASSAL.counters;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import VASSAL.build.module.map.StackMetrics;
/**
- GroupStackMetrics just displays the pieces as they are as we are only
- interrested in grouping them, and not doing anything fancy with them
-
@author tmi
-
/
public class GroupStackMetrics extends StackMetrics {
/*
* Fill the argument arrays with the positions, selection bounds and bounding boxes of the pieces in the argument stack
* @param parent The parent Stack
* @param positions If non-null will contain a {@link Point} giving the position of each piece in parent
* @param shapes If non-null will contain a {@link Shape} giving the shape of for each piece in parent
* @param boundingBoxes If non-null will contain a {@link Rectangle} giving the bounding box for each piece in parent
* @param x the x-location of the parent
* @param y the y-location of the parent
* @return the number of pieces processed in the stack
*/
@Override
public int getContents(Stack parent, Point[] positions, Shape[] shapes, Rectangle[] boundingBoxes, int x, int y) {
int count = parent.getMaximumVisiblePieceCount();
Point orgPos = null;
if (positions != null) {
count = Math.min(count, positions.length);
}
if (boundingBoxes != null) {
count = Math.min(count, boundingBoxes.length);
}
if (shapes != null) {
count = Math.min(count,shapes.length);
}
for (int index = 0; index <count>= 0)
return new Point(before[i]);
else
return getPosition();
}
public void insertChild(GamePiece child, int index) {
if ( child.getParent() != null) {
child.getParent().remove(child);
child.setParent(null);
}
else if (child.getMap() != null) {
child.getMap().removePiece(child);
}
lastPos = child.getPosition();
child.setParent(this);
insertPieceAt(child, index);
lastPos = null;
}
protected void insertPieceAt(GamePiece p, int index) {
if (pieceCount >= contents.length) {
GamePiece[] newContents = new GamePiece[contents.length + INCR];
System.arraycopy(contents, 0, newContents, 0, pieceCount);
contents = newContents;
Point[] newPoints = new Point[contents.length + INCR];
System.arraycopy(before, 0, newPoints, 0, pieceCount);
before = newPoints;
}
for (int i = pieceCount; i > index; --i) {
contents[i] = contents[i - 1];
before[i] = before[i - 1];
}
contents[index] = p;
before[index] = new Point(lastPos.x-pos.x,lastPos.y-pos.y);
lastPos =null;
pieceCount++;
}
protected void removePieceAt(int index) {
if (index >= 0 && index < pieceCount) {
//set pos relative to us otherwise the piece will drop to the center of teh group
contents[index].setPosition(new Point(pos.x +before[index].x, pos.y +before[index].y));
pieceCount–;
for (int i = index; i 1);
}
}
public void insert(GamePiece p, int pos) {
if (p == null) {
return;
}
pos = Math.max(pos, 0);
pos = Math.min(pos, pieceCount);
int index = indexOf(p);
if (index >= 0) {
if (pos > index) {
insertPieceAt(p, pos + 1);
removePieceAt(index);
}
else {
removePieceAt(index);
insertPieceAt(p, pos);
}
}
else {
insertChild(p, pos);
}
}
}
[/code]
GroupCommand.java
[code]package VASSAL.counters;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Iterator;
import VASSAL.build.GameModule;
import VASSAL.build.module.Map;
import VASSAL.build.module.map.MassKeyCommand;
/**
-
Just create a stack out of the pieces the user has selected throwing away
-
any previous stack the pieces may have belonged to.
*/
public class GroupCommand extends MassKeyCommand {
public void apply(Map m) {
if(m == null)
return;
GamePiece[] p = m.getAllPieces();
if(p.length <= 1)
return;
ArrayList selected = new ArrayList();
//collect all selected
for(int i=0; i
0) {
//collect positions before
Point before = null;
Point summ = new Point(0,0);
for (int i=0; i<selected.size(); i++) {
GamePiece s = selected.get(i);
before = s.getPosition();
summ.translate(before.x, before.y);
}
//create new group
Group grp = new Group();
grp.setMap(selected.get(0).getMap());
//position group on map
summ.x /= selected.size();
summ.y /= selected.size();
grp.setPosition(summ);
System.out.println(“grp x:”+summ.x+" y:"+summ.y);
//add to new group
for (int i=0; i<selected.size(); i++) {
GamePiece s = selected.get(i);
grp.add(s);
}
//add group to game
grp.getMap().addPiece(grp);
GameModule.getGameModule().getGameState().addPiece(grp);
grp.getMap().repaint();
}
}
private ArrayList getSelected(Group grp) {
ArrayList l = new ArrayList();
GamePiece p = null;
for(Iterator it = grp.getPiecesIterator();it.hasNext() {
p=it.next();
if(Boolean.TRUE.equals(p.getProperty(Properties.SELECTED))) {
l.add(p);
}
}
return l;
}
}
[/code]
GroupingMap.java
[code]package VASSAL.build.module;
import java.awt.AlphaComposite;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import VASSAL.build.module.map.StackMetrics;
import VASSAL.counters.GamePiece;
import VASSAL.counters.GroupStackMetrics;
import VASSAL.counters.Properties;
import VASSAL.counters.Stack;
public class GroupingMap extends Map {
public StackMetrics getStackMetrics() {
if (metrics == null) {
metrics = new GroupStackMetrics();
metrics.build(null);
add(metrics);
metrics.addTo(this);
}
return metrics;
}
public void drawPiecesInRegion(Graphics g,
Rectangle visibleRect,
Component c) {
if (!hideCounters) {
Graphics2D g2d = (Graphics2D) g;
Composite oldComposite = g2d.getComposite();
g2d.setComposite(
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, pieceOpacity));
GamePiece[] stack = pieces.getPieces();
for (int i = 0; i < stack.length; ++i) {
Point pt = componentCoordinates(stack[i].getPosition());
if (stack[i] instanceof Stack) {
getStackMetrics().draw(
(Stack) stack[i], pt, g, this, getZoom(), visibleRect);
}
else {
stack[i].draw(g, pt.x, pt.y, c, getZoom());
if (Boolean.TRUE.equals(stack[i].getProperty(Properties.SELECTED))) {
highlighter.draw(stack[i], g, pt.x, pt.y, c, getZoom());
}
}
}
g2d.setComposite(oldComposite);
}
}
}
[/code]