Class PieceMover

All Implemented Interfaces:
MouseListener, MouseMotionListener, Comparator<GamePiece>, EventListener, Buildable, GameComponent, PropertyNameSource, ValidityChecker, Auditable, ImageSearchTarget

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 KeyBufferer.
  • Field Details

    • AUTO_REPORT

      public static final String AUTO_REPORT
      The Preferences key for auto-reporting moves.
      See Also:
    • NAME

      public static final String NAME
      See Also:
    • HOTKEY

      public static final String HOTKEY
      See Also:
    • map

      protected Map map
    • dragBegin

      protected Point dragBegin
    • breachedThreshold

      protected boolean breachedThreshold
    • dragging

      protected GamePiece dragging
    • markUnmovedButton

      protected LaunchButton markUnmovedButton
    • markUnmovedText

      protected String markUnmovedText
    • markUnmovedIcon

      protected String markUnmovedIcon
    • markUnmovedHotkey

      protected NamedKeyStroke markUnmovedHotkey
    • markUnmovedReport

      protected String markUnmovedReport
    • ICON_NAME

      public static final String ICON_NAME
      See Also:
    • iconName

      protected String iconName
    • dragTargetSelector

      protected PieceFinder dragTargetSelector
    • dropTargetSelector

      protected PieceFinder dropTargetSelector
    • loadedCargoDropTargetSelector

      protected VASSAL.build.module.map.PieceMover.LoadedCargoDropTargetSelector loadedCargoDropTargetSelector
    • matDropTargetSelector

      protected VASSAL.build.module.map.PieceMover.MatDropTargetSelector matDropTargetSelector
    • selectionProcessor

      protected PieceVisitorDispatcher selectionProcessor
    • pieceSorter

      protected Comparator<GamePiece> 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

      public void addTo(Buildable b)
      Adds this component to its parent map. Add ourselves as a mouse listener, drag gesture listener, etc.
      Specified by:
      addTo in interface Buildable
      Parameters:
      b - Map to add to
    • createMovementReporter

      protected MovementReporter createMovementReporter(Command c)
      Creates a MovementReporter 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

      public void addLocalImageNames(Collection<String> s)
      Reports the image files we use (forremove-unwanted-image-files and/or search)
      Specified by:
      addLocalImageNames in interface ImageSearchTarget
      Overrides:
      addLocalImageNames in class AbstractImageFinder
      Parameters:
      s - Collection to add image names to
    • getDropTargetSelector

      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.

      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's PieceFinder.select(VASSAL.build.module.Map, VASSAL.counters.GamePiece, java.awt.Point) method provides the map and location, and the PieceMover's dragging 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's Map.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 mover
      cargo - The MatCargo trait of the piece being moved
      mat - The Mat the piece is loaded on, if it is cargo
      Returns:
      a PieceFinder instance that determines which GamePiece (if any) to combine the being-dragged pieces with.
    • createDropTargetSelector

      protected PieceFinder createDropTargetSelector()
    • createSelectionProcessor

      protected PieceVisitorDispatcher 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 the PieceVisitorDispatcher 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

      protected PieceFinder createDragTargetSelector()
      Returns the PieceFinder instance that will select a GamePiece 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 interface GameComponent
      Parameters:
      gameStarting - if true, a game is starting. If false, then a game is ending
    • getRestoreCommand

      public Command getRestoreCommand()
      PieceMover has nothing to save/restore in a save file.
      Specified by:
      getRestoreCommand in interface GameComponent
      Returns:
      null
    • initButton

      protected void initButton()
      PieceMover manages the "Mark All Pieces Unmoved" button for the map.
    • getAttributeNames

      public String[] getAttributeNames()
      Description copied from class: AbstractBuildable
      Lists all the buildFile (XML) attribute names for this component. If this component is ALSO an AbstractConfigurable, then this list of attributes determines the appropriate attribute order for AbstractConfigurable.getAttributeDescriptions() and AbstractConfigurable.getAttributeTypes().
      Specified by:
      getAttributeNames in class AbstractBuildable
      Returns:
      a list of all buildFile (XML) attribute names for this component
    • getAttributeValueString

      public String getAttributeValueString(String key)
      Specified by:
      getAttributeValueString in class AbstractBuildable
      Parameters:
      key - the name of the attribute. Will be one of those listed in AbstractBuildable.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

      public void setAttribute(String key, Object value)
      Description copied from class: AbstractBuildable
      Sets a buildFile (XML) attribute value for this component. The key parameter will be one of those listed in AbstractBuildable.getAttributeNames(). If the value parameter is a String, it will be the value returned by AbstractBuildable.getAttributeValueString(java.lang.String) for the same key. If the implementing class extends AbstractConfigurable, then value will be an instance of the corresponding Class listed in AbstractConfigurable.getAttributeTypes()
      Specified by:
      setAttribute in class AbstractBuildable
      Parameters:
      key - the name of the attribute. Will be one of those listed in AbstractBuildable.getAttributeNames()
      value - If the value parameter is a String, it will be the value returned by AbstractBuildable.getAttributeValueString(java.lang.String) for the same key. If the implementing class extends AbstractConfigurable, then value can also be an instance of the corresponding Class listed in AbstractConfigurable.getAttributeTypes()
    • isMultipleSelectionEvent

      protected boolean isMultipleSelectionEvent(MouseEvent e)
    • movedPiece

      protected Command movedPiece(GamePiece p, Point loc)
      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

      protected Command setOldLocations(GamePiece p)
      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

      public Command markMoved(GamePiece p, boolean hasMoved)
    • markMoved

      public Command markMoved(GamePiece p, boolean hasMoved, boolean locDefinitelyChanged)
      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 status
      locDefinitelyChanged - 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

      public Command movePieces(Map map, Point p)
      This is the key method for handling the "Drop" part of Drag and Drop.
      (1) Moves each piece in the DragBuffer 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 - Map
      p - Point mouse released
      Returns:
      Command encapsulating all changes, for replay in log file or on other clients.
    • checkTrueMoved

      public Command checkTrueMoved(GamePiece p)
      For a piece, mark it moved IF it changed locations or mats
      Parameters:
      p - piece or stack
      Returns:
      command to replicate any actions taken on another VASSAL instance
    • doTrueMovedSupport

      protected Command doTrueMovedSupport(List<GamePiece> pieces)
      For a list of pieces, mark them moved IF they changed locations or mats
      Parameters:
      pieces - list of pieces
      Returns:
      command to replicate any actions taken on another Vassal instance
    • applyKeyAfterMove

      protected Command applyKeyAfterMove(List<GamePiece> pieces, KeyStroke key)
      Applies a key command to each of a list of pieces.
      Parameters:
      pieces - List of pieces
      key - keystroke to apply
      Returns:
      Command that encapsulates the effects of the key command applied.
    • mousePressed

      public void mousePressed(MouseEvent e)
      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 interface MouseListener
      Parameters:
      e - Event
    • selectMovablePieces

      protected void selectMovablePieces(MouseEvent e)
      When starting a drag-and-drop, place the clicked-on piece into the DragBuffer
    • canHandleEvent

      protected boolean canHandleEvent(MouseEvent e)
      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

      public boolean isClick(Point pt)
      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

      public void mouseReleased(MouseEvent e)
      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 interface MouseListener
      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

      public void mouseMoved(MouseEvent e)
      Specified by:
      mouseMoved in interface MouseMotionListener
    • mouseDragged

      public void mouseDragged(MouseEvent e)
      Check if we have breached our drag threshold during a drag. Only meaningful in legacy DnD situations.
      Specified by:
      mouseDragged in interface MouseMotionListener
      Parameters:
      e - mouse event.
    • performDrop

      protected void performDrop(Point p)
      Moves the group of dragged (in the DragBuffer) pieces to the target point (p).
      Parameters:
      p - Point that mouse has been dragged to.
    • mouseEntered

      public void mouseEntered(MouseEvent e)
      Specified by:
      mouseEntered in interface MouseListener
    • mouseExited

      public void mouseExited(MouseEvent e)
      Specified by:
      mouseExited in interface MouseListener
    • mouseClicked

      public void mouseClicked(MouseEvent e)
      Specified by:
      mouseClicked in interface MouseListener
    • compare

      public int compare(GamePiece p1, GamePiece p2)
      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 interface Comparator<GamePiece>
    • isMandatory

      public boolean isMandatory()
      Description copied from interface: Buildable
      Is this component a reqired component within its parent?
      Specified by:
      isMandatory in interface Buildable
      Returns:
      true if component is mandatory
    • isUnique

      public boolean isUnique()
      Description copied from interface: Buildable
      Does this component need to be unique within it's parent?
      Specified by:
      isUnique in interface Buildable
      Returns: