Package VASSAL.build.module.map
Class PieceMover
java.lang.Object
VASSAL.search.AbstractImageFinder
VASSAL.build.AbstractBuildable
VASSAL.build.module.map.PieceMover
- All Implemented Interfaces:
MouseListener
,MouseMotionListener
,Comparator<GamePiece>
,EventListener
,Buildable
,GameComponent
,PropertyNameSource
,ValidityChecker
,Auditable
,ImageSearchTarget
public class PieceMover
extends AbstractBuildable
implements MouseListener, MouseMotionListener, GameComponent, Comparator<GamePiece>
PieceMover handles the "Drag and Drop" of pieces and stacks, onto or within a Map window. It implements
MouseListener and handles dragging and dropping of both individual pieces, stacks, and groups of
pieces/stacks. It is a subcomponent of Map.
For the selection/deselection of pieces and band-selecting pieces by "dragging a lasso around them", see
For the selection/deselection of pieces and band-selecting pieces by "dragging a lasso around them", see
KeyBufferer
.-
Nested Class Summary
Modifier and TypeClassDescriptionstatic class
Common functionality for DragHandler for cases with and without drag image support.static class
VASSAL's front-line drag handler for drag-and-drop of pieces.static class
Special MacOSX variant of DragHandler, because of differences in how device scaling is handled.static class
Fallback drag-handler when DragImage not supported by JRE. -
Field Summary
Modifier and TypeFieldDescriptionstatic final String
The Preferences key for auto-reporting moves.protected boolean
protected int
protected int
protected Point
protected GamePiece
protected PieceFinder
protected PieceFinder
static final String
static final String
protected String
protected VASSAL.build.module.map.PieceMover.LoadedCargoDropTargetSelector
protected Map
protected LaunchButton
protected NamedKeyStroke
protected String
protected String
protected String
protected VASSAL.build.module.map.PieceMover.MatDropTargetSelector
static final String
protected Comparator
<GamePiece> protected PieceVisitorDispatcher
Fields inherited from class VASSAL.build.AbstractBuildable
buildComponents, validator
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionvoid
Reports the image files we use (forremove-unwanted-image-files and/or search)void
Adds this component to its parent map.protected Command
applyKeyAfterMove
(List<GamePiece> pieces, KeyStroke key) Applies a key command to each of a list of pieces.protected boolean
Checks if event has already been consumed -- so we will return false if this event has already been handled by one of the fancier Drag Gesture Recognizers.For a piece, mark it moved IF it changed locations or matsint
Implement Comparator to sort the contents of the drag buffer before completing the drag.protected PieceFinder
Returns thePieceFinder
instance that will select aGamePiece
for processing when the user clicks on the map.protected PieceFinder
protected MovementReporter
Creates aMovementReporter
for a collection of commands containing AddPiece and MovePiece commands, which will supply auto-report messages corresponding to those commandsprotected PieceVisitorDispatcher
When the user *starts* a potential drag-and-drop operation by clicking on the map, a piece from the map is selected by the dragTargetSelector.protected Command
doTrueMovedSupport
(List<GamePiece> pieces) For a list of pieces, mark them moved IF they changed locations or matsString[]
Lists all the buildFile (XML) attribute names for this component.boolean
protected PieceFinder
getDropTargetSelector
(GamePiece piece, MatCargo cargo, Mat mat) Return a DropTargetSelector suitable for the type of piece being moved When the user *completes* a drag-and-drop operation, the pieces being dragged will either be:
(1) combined in a stack with an existing piece (or stack, or deck) on the map
(2) placed alone in a brand new stack
(3) or, in the case of non-stacking pieces, placed on the map without stack.PieceMover has nothing to save/restore in a save file.protected void
PieceMover manages the "Mark All Pieces Unmoved" button for the map.boolean
boolean
Is this component a reqired component within its parent?protected boolean
boolean
isUnique()
Does this component need to be unique within it's parent?Handles marking pieces as "moved" or "not moved", based on Global Options settings.void
void
Check if we have breached our drag threshold during a drag.void
void
void
void
When mouse first pressed, set up for doing a possible drag-and-drop with them.void
Mouse button has been released -- if we can still handle the event (i.e. we haven't picked up some exotic modifier key during the drag, etc), then we perform the drop.protected Command
movedPiece
(GamePiece p, Point loc) Invoked just BEFORE a piece is moved.movePieces
(Map map, Point p) This is the key method for handling the "Drop" part of Drag and Drop.protected void
performDrop
(Point p) Moves the group of dragged (in the DragBuffer) pieces to the target point (p).protected void
When starting a drag-and-drop, place the clicked-on piece into theDragBuffer
void
setAttribute
(String key, Object value) Sets a buildFile (XML) attribute value for this component.void
setBreachedThreshold
(boolean breachedThreshold) void
setCurPieceOffset
(int x, int y) protected Command
Populates the "OldLocations" properties (e.g.void
setup
(boolean gameStarting) Detects when a game is starting, for purposes of managing the mark-unmoved button.protected boolean
Checks Global Options settings (and if necessary, the user preference) about whether we mark moved pieces as "moved" or not.Methods inherited from class VASSAL.build.AbstractBuildable
add, addImageNamesRecursively, build, buildString, getAllDescendantComponentsOf, getAncestor, getBuildables, getBuildComponents, getBuildElement, getComponents, getComponentsOf, getNonFolderAncestor, getPropertyNames, setAncestor, validate
Methods inherited from class VASSAL.search.AbstractImageFinder
getAllImageNames, getLocalImageNames
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface VASSAL.script.expression.Auditable
getComponentName, getComponentTypeName
Methods inherited from interface java.util.Comparator
equals, reversed, thenComparing, thenComparing, thenComparing, thenComparingDouble, thenComparingInt, thenComparingLong
-
Field Details
-
AUTO_REPORT
-
NAME
- See Also:
-
HOTKEY
- See Also:
-
map
-
dragBegin
-
breachedThreshold
protected boolean breachedThreshold -
dragging
-
markUnmovedButton
-
markUnmovedText
-
markUnmovedIcon
-
markUnmovedHotkey
-
markUnmovedReport
-
ICON_NAME
- See Also:
-
iconName
-
dragTargetSelector
-
dropTargetSelector
-
loadedCargoDropTargetSelector
protected VASSAL.build.module.map.PieceMover.LoadedCargoDropTargetSelector loadedCargoDropTargetSelector -
matDropTargetSelector
protected VASSAL.build.module.map.PieceMover.MatDropTargetSelector matDropTargetSelector -
selectionProcessor
-
pieceSorter
-
curPieceOffsetX
protected int curPieceOffsetX -
curPieceOffsetY
protected int curPieceOffsetY
-
-
Constructor Details
-
PieceMover
public PieceMover()
-
-
Method Details
-
setCurPieceOffset
public void setCurPieceOffset(int x, int y) -
setBreachedThreshold
public void setBreachedThreshold(boolean breachedThreshold) -
getBreachedThreshold
public boolean getBreachedThreshold() -
addTo
-
createMovementReporter
Creates aMovementReporter
for a collection of commands containing AddPiece and MovePiece commands, which will supply auto-report messages corresponding to those commands- Parameters:
c
- Command -- presumably including some AddPiece and MovePiece commands.- Returns:
- MovementReporter to auto-report the command(s)
-
addLocalImageNames
Reports the image files we use (forremove-unwanted-image-files and/or search)- Specified by:
addLocalImageNames
in interfaceImageSearchTarget
- Overrides:
addLocalImageNames
in classAbstractImageFinder
- Parameters:
s
- Collection to add image names to
-
getDropTargetSelector
Return a DropTargetSelector suitable for the type of piece being moved When the user *completes* a drag-and-drop operation, the pieces being dragged will either be:
(1) combined in a stack with an existing piece (or stack, or deck) on the map
(2) placed alone in a brand new stack
(3) or, in the case of non-stacking pieces, placed on the map without stack.
For each of the stacks/pieces being dragged, we need to determine which of those outcomes applies. This "drop target selector" will be fed, one by one, all of the pieces on the map, and for each one must check whether it would make a valid "merge target" for the current dragged piece under consideration (the PieceFinder'sPieceFinder.select(VASSAL.build.module.Map, VASSAL.counters.GamePiece, java.awt.Point)
method provides the map and location, and the PieceMover'sdragging
field tells the "dragged piece under consideration". Each method is to returns the target piece/stack/deck to merge with if it has been passed a valid target, or null if it is not a valid match.
The Map'sMap.findAnyPiece(Point, PieceFinder)
method, which feeds this, will be responsible for iterating through the list of possible pieces in proper visual order so that we check the pieces "visually on top" first.- Parameters:
piece
- The Piece being movercargo
- The MatCargo trait of the piece being movedmat
- The Mat the piece is loaded on, if it is cargo- Returns:
- a
PieceFinder
instance that determines whichGamePiece
(if any) to combine the being-dragged pieces with.
-
createDropTargetSelector
-
createSelectionProcessor
When the user *starts* a potential drag-and-drop operation by clicking on the map, a piece from the map is selected by the dragTargetSelector. What happens to that piece is determined by thePieceVisitorDispatcher
instance returned by this method. The default implementation does the following:
(1) If a Deck, add the (single) top piece to the drag buffer
(2) If a stack, add it to the drag buffer. If the stack is a member of the "currently selected pieces" (i.e.KeyBuffer
), then add any other already-selected pieces and stacks to the drag buffer as well.
(3) Otherwise, add the piece and any other multi-selected pieces and stacks to the drag buffer.- Returns:
- Dispatcher
- See Also:
-
createDragTargetSelector
Returns thePieceFinder
instance that will select aGamePiece
for processing when the user clicks on the map. The default implementation is to return the first piece whose shape contains the point clicked on.- Returns:
- Piece Finder
-
setup
public void setup(boolean gameStarting) Detects when a game is starting, for purposes of managing the mark-unmoved button.- Specified by:
setup
in interfaceGameComponent
- Parameters:
gameStarting
- if true, a game is starting. If false, then a game is ending
-
getRestoreCommand
PieceMover has nothing to save/restore in a save file.- Specified by:
getRestoreCommand
in interfaceGameComponent
- Returns:
- null
-
initButton
protected void initButton()PieceMover manages the "Mark All Pieces Unmoved" button for the map. -
getAttributeNames
Description copied from class:AbstractBuildable
Lists all the buildFile (XML) attribute names for this component. If this component is ALSO anAbstractConfigurable
, then this list of attributes determines the appropriate attribute order forAbstractConfigurable.getAttributeDescriptions()
andAbstractConfigurable.getAttributeTypes()
.- Specified by:
getAttributeNames
in classAbstractBuildable
- Returns:
- a list of all buildFile (XML) attribute names for this component
-
getAttributeValueString
- Specified by:
getAttributeValueString
in classAbstractBuildable
- Parameters:
key
- the name of the attribute. Will be one of those listed inAbstractBuildable.getAttributeNames()
- Returns:
- a String representation of the XML buildFile attribute with the given name. When initializing a module,
this String value will loaded from the XML and passed to
AbstractBuildable.setAttribute(java.lang.String, java.lang.Object)
. It is also frequently used for checking the current value of an attribute.
-
setAttribute
Description copied from class:AbstractBuildable
Sets a buildFile (XML) attribute value for this component. Thekey
parameter will be one of those listed inAbstractBuildable.getAttributeNames()
. If thevalue
parameter is a String, it will be the value returned byAbstractBuildable.getAttributeValueString(java.lang.String)
for the samekey
. If the implementing class extendsAbstractConfigurable
, thenvalue
will be an instance of the corresponding Class listed inAbstractConfigurable.getAttributeTypes()
- Specified by:
setAttribute
in classAbstractBuildable
- Parameters:
key
- the name of the attribute. Will be one of those listed inAbstractBuildable.getAttributeNames()
value
- If thevalue
parameter is a String, it will be the value returned byAbstractBuildable.getAttributeValueString(java.lang.String)
for the samekey
. If the implementing class extendsAbstractConfigurable
, thenvalue
can also be an instance of the corresponding Class listed inAbstractConfigurable.getAttributeTypes()
-
isMultipleSelectionEvent
-
movedPiece
Invoked just BEFORE a piece is moved. Sets the "OldLocations" properties for the piece. Marks the piece as "moved" if it has changed positions, and removes the piece from its old stack, if any.- Returns:
- Command encapsulating anything this method did, for replay in log file or on other clients
-
setOldLocations
Populates the "OldLocations" properties (e.g. OldMap, OldZone, etc) for the piece (or for a stack, for all the pieces contained in it), based on their present locations, in preparation for moving them to a new location.- Parameters:
p
- Piece (could be a stack)- Returns:
- Command encapsulating any changes made, for replay in log file or on other clients
-
markMoved
-
markMoved
Handles marking pieces as "moved" or "not moved", based on Global Options settings. Updates the "moved" property of the pieces, if they have one.- Parameters:
p
- Piece (could be a Stack)hasMoved
- True if piece has just moved, false if it is to be reset to not-moved statuslocDefinitelyChanged
- true if piece definitely changed locations or mats (for possibly ignoring small moves)- Returns:
- Command encapsulating any changes made, for replay in log file or on other clients
-
shouldMarkMoved
protected boolean shouldMarkMoved()Checks Global Options settings (and if necessary, the user preference) about whether we mark moved pieces as "moved" or not.- Returns:
- true if we should mark a moved piece as "moved", false if not.
-
movePieces
This is the key method for handling the "Drop" part of Drag and Drop.
(1) Moves each piece in theDragBuffer
to its proper destination, based on the mouse having been released at point "p" (if multiple pieces were being dragged after being e.g. band-selected, each individual piece's destination point will vary with the piece's offset from the anhor point that started the drag). This also involves removing each piece from any stacks/decks it was part of, and possibly removing it from its old map if it is changing maps.
(2) As each piece is moved, finds appropriate "merge targets" (pieces that should be combined with it in a stack) if they exist, or forms new stacks where needed. Adds the piece to old or new stacks as appropriate, or directly to the map if non-stacking. If the piece has been moved between maps (or onto a map for the first time), the piece is also added to the map's piece collection.
(3) If auto-reporting of moves is enabled, creates the report.
(4) Applies any apply-on-move keystroke (from the "Key command to apply to all units ending movement on this map" field of the map) to each piece, as appropriate.
(5) Returns a command to encapsulate any and all changes made, for replay in log file or on other clients- Parameters:
map
- Mapp
- Point mouse released- Returns:
- Command encapsulating all changes, for replay in log file or on other clients.
-
checkTrueMoved
-
doTrueMovedSupport
-
applyKeyAfterMove
-
mousePressed
When mouse first pressed, set up for doing a possible drag-and-drop with them. On most systems, most of the drag-and-drop will be performed by the Drag Gesture Recognizer, but this part runs for everyone, including setting an "anchor point" for the drag.- Specified by:
mousePressed
in interfaceMouseListener
- Parameters:
e
- Event
-
selectMovablePieces
When starting a drag-and-drop, place the clicked-on piece into theDragBuffer
-
canHandleEvent
Checks if event has already been consumed -- so we will return false if this event has already been handled by one of the fancier Drag Gesture Recognizers. Also screens out double-clicks and anything with modifier keys down.- Parameters:
e
- mouse event- Returns:
- Should we treat this event as part of a "deep legacy" drag and drop?
-
isClick
- Returns:
- true if this point is "close enough" to the point at which the user initially pressed the mouse button to be considered a mouse click (such that no drag-and-drop moves are processed)
-
mouseReleased
Mouse button has been released -- if we can still handle the event (i.e. we haven't picked up some exotic modifier key during the drag, etc), then we perform the drop.- Specified by:
mouseReleased
in interfaceMouseListener
- Parameters:
e
- Mouse Event -> NOTE that the supplied point is not the actual mouse position but rather it has been offset by how far off-center the drag point on the piece was/is.
-
mouseMoved
- Specified by:
mouseMoved
in interfaceMouseMotionListener
-
mouseDragged
Check if we have breached our drag threshold during a drag. Only meaningful in legacy DnD situations.- Specified by:
mouseDragged
in interfaceMouseMotionListener
- Parameters:
e
- mouse event.
-
performDrop
Moves the group of dragged (in the DragBuffer) pieces to the target point (p).- Parameters:
p
- Point that mouse has been dragged to.
-
mouseEntered
- Specified by:
mouseEntered
in interfaceMouseListener
-
mouseExited
- Specified by:
mouseExited
in interfaceMouseListener
-
mouseClicked
- Specified by:
mouseClicked
in interfaceMouseListener
-
compare
Implement Comparator to sort the contents of the drag buffer before completing the drag. This sorts the contents to be in the same order as the pieces were in their original parent stack.- Specified by:
compare
in interfaceComparator<GamePiece>
-
isMandatory
public boolean isMandatory()Description copied from interface:Buildable
Is this component a reqired component within its parent?- Specified by:
isMandatory
in interfaceBuildable
- Returns:
- true if component is mandatory
-
isUnique
-