package com.clearlyspam23.GLE.basic.layers.tile.edit.commands; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.piccolo2d.PCamera; import org.piccolo2d.PNode; import org.piccolo2d.event.PDragSequenceEventHandler; import org.piccolo2d.event.PInputEvent; import org.piccolo2d.util.PPickPath; import com.clearlyspam23.GLE.GUI.util.FixedWidthOutlineRectNode; import com.clearlyspam23.GLE.basic.layers.tile.TileData; import com.clearlyspam23.GLE.basic.layers.tile.TileLocation; import com.clearlyspam23.GLE.basic.layers.tile.edit.TileLayerEditManager; import com.clearlyspam23.GLE.basic.layers.tile.edit.actions.AddToSelectionAction; import com.clearlyspam23.GLE.basic.layers.tile.edit.actions.MoveSelectionAction; import com.clearlyspam23.GLE.basic.layers.tile.edit.actions.RemoveFromSelectionAction; import com.clearlyspam23.GLE.basic.layers.tile.gui.BasePNode; import com.clearlyspam23.GLE.basic.layers.tile.gui.ImmovableTileSelection; import com.clearlyspam23.GLE.basic.layers.tile.gui.MovableTileSelection; import com.clearlyspam23.GLE.basic.layers.tile.gui.TileLayerPNode; import com.clearlyspam23.GLE.basic.layers.tile.gui.TilePNode; public class TileSelectCommand extends PDragSequenceEventHandler { protected TileLayerEditManager data; protected TilePNode startNode; protected TilePNode lastNode; protected FixedWidthOutlineRectNode outlineBoxNode; private TilePNode grabbed; private static final int SELECTING = 1; private static final int MOVING = 2; private int state; private MovableTileSelection movingSelection; private TileLocation startLocation; private TileLocation relativeLocation = new TileLocation(); public TileSelectCommand(TileLayerEditManager data){ this.data = data; } private void floodSelect(TilePNode node, TileData target, TilePNode[][] grid, List<TileLocation> out){ if(!target.equals(node.getTileData())||out.contains(node.getTileLocation())) return; if(node.isSilentlyIgnoringInput()) return; out.add(node.getTileLocation()); int x = node.getGridX(); int y = node.getGridY(); if(x-1>=0) floodSelect(grid[x-1][y], target, grid, out); if(x+1<grid.length) floodSelect(grid[x+1][y], target, grid, out); if(y-1>=0) floodSelect(grid[x][y-1], target, grid, out); if(y+1<grid[x].length) floodSelect(grid[x][y+1], target, grid, out); } private void createSelection(List<TileLocation> selectedLocations, TileLayerPNode parent, PCamera camera){ ImmovableTileSelection selection = new ImmovableTileSelection(selectedLocations, parent, camera); if(parent.getBase().hasSelection()){ anchorSelection(parent.getBase()); } parent.getBase().setSelectionWithAction(selection, data); } private void anchorSelection(BasePNode base){ base.anchorSelectionWithAction(data); } private void selectSimilar(PInputEvent event, TilePNode node){ if(!node.getTileData().equals(new TileData())){ TileLayerPNode parent = node.getTilePNodeLayer(); List<TileLocation> selectedLocations = new ArrayList<TileLocation>(); floodSelect(node, node.getTileData(), node.getTilePNodeLayer().getNodeGrid(), selectedLocations); if(!selectedLocations.isEmpty()){ createSelection(selectedLocations, parent, event.getCamera()); } } } public void mouseClicked(PInputEvent event){ super.mouseClicked(event); //tile flood fill selection if(event.isLeftMouseButton()&&!event.isAltDown()&&!event.isControlDown()&&event.getClickCount()==2){ TilePNode node = tryGrabNode(event.getCanvasPosition(), event.getCamera()); if(node!=null){ selectSimilar(event, node); } } //deselect selection else if(event.isRightMouseButton()){ TilePNode node = tryGrabNode(event.getCanvasPosition(), event.getCamera()); if(node!=null){ BasePNode base = ((TileLayerPNode) node.getParent()).getBase(); if(base.getSelection()!=null&&!base.getSelection().isNodeInSelection(node)){ base.anchorSelectionWithAction(data); } } } } public void mousePressed(PInputEvent event){ super.mousePressed(event); //control clicking grabbed = tryGrabNode(event.getCanvasPosition(), event.getCamera()); } public void mouseReleased(PInputEvent event){ super.mouseReleased(event); //double checking the control click if(grabbed==tryGrabNode(event.getCanvasPosition(), event.getCamera())){ if(event.isLeftMouseButton()&&event.isControlDown()){ TilePNode node = tryGrabNode(event.getCanvasPosition(), event.getCamera()); if(node!=null){ BasePNode base = ((TileLayerPNode) node.getParent()).getBase(); if(base.getSelection() instanceof ImmovableTileSelection){ ImmovableTileSelection selection = ((ImmovableTileSelection) base.getSelection()); if(base.getSelection().isNodeInSelection(node)){ List<TileLocation> locations = Arrays.asList(node.getTileLocation()); selection.removeFromSelection(locations); data.registerEditAction(new RemoveFromSelectionAction(selection, locations)); } else{ List<TileLocation> locations = Arrays.asList(node.getTileLocation()); selection.addToSelection(locations); data.registerEditAction(new AddToSelectionAction(selection, locations)); } } } } } } @Override protected boolean shouldStartDragInteraction(PInputEvent event) { if (super.shouldStartDragInteraction(event)) { return event.isLeftMouseButton()&&!event.isAltDown()&&!event.isControlDown()&&event.getClickCount()==1; } return false; } private PNode getPickedNode(Point2D pos, PCamera cam){ final PPickPath p = cam.pick(pos.getX(), pos.getY(), 1); if(p==null) return null; return p.getPickedNode(); } protected void startDrag(PInputEvent event){ super.startDrag(event); lastNode = startNode = tryGrabNode(event.getCanvasPosition(), event.getCamera()); if(startNode!=null){ BasePNode base = startNode.getTilePNodeLayer().getBase(); if(base.getSelection() instanceof MovableTileSelection&&base.getSelection().isNodeInSelection(startNode)){ movingSelection = (MovableTileSelection) base.getSelection(); startLocation = movingSelection.getOffset(); relativeLocation.set(startNode.getGridX()-startLocation.gridX, startNode.getGridY()-startLocation.gridY); state = MOVING; } else{ base.anchorSelectionWithAction(data); state = SELECTING; } } } @Override protected void endDrag(PInputEvent event){ super.endDrag(event); if(state==SELECTING){ if(startNode!=null&&lastNode!=null&&outlineBoxNode!=null){ int startX = Math.min(startNode.getGridX(), lastNode.getGridX()); int startY = Math.min(startNode.getGridY(), lastNode.getGridY()); int endX = Math.max(startNode.getGridX(), lastNode.getGridX()); int endY = Math.max(startNode.getGridY(), lastNode.getGridY()); int width = endX - startX + 1; int height = endY - startY + 1; TileLayerPNode parent = startNode.getTilePNodeLayer(); List<TileLocation> selectedLocations = new ArrayList<TileLocation>(); for(int i = 0; i < width; i++){ for(int j = 0; j < height; j++){ System.out.println(i+startX + ", " + (j+startY)); selectedLocations.add(new TileLocation(i+startX, j+startY)); } } createSelection(selectedLocations, parent, event.getCamera()); } else{ TilePNode node = tryGrabNode(event.getCanvasPosition(), event.getCamera()); if(node!=null){ BasePNode base = ((TileLayerPNode) node.getParent()).getBase(); if(base.getSelection()!=null&&!base.getSelection().isNodeInSelection(node)){ base.anchorSelectionWithAction(data); } } } } else if(state==MOVING){ if(movingSelection!=null) data.registerEditAction(new MoveSelectionAction(startLocation, movingSelection.getOffset(), movingSelection)); } startNode = null; lastNode = null; movingSelection = null; state = 0; if(outlineBoxNode!=null){ outlineBoxNode.removeFromParent(); outlineBoxNode = null; } } protected void drag(PInputEvent event) { super.drag(event); if(startNode!=null){ TilePNode currentNode = tryGrabNode(event.getCanvasPosition(), event.getCamera()); if(state==SELECTING){ if(currentNode!=null&¤tNode.getParent()==startNode.getParent()){ lastNode = currentNode; TileLayerPNode parent = (TileLayerPNode) currentNode.getParent(); if(outlineBoxNode == null){ outlineBoxNode = new FixedWidthOutlineRectNode(1, event.getCamera()); outlineBoxNode.setBounds(0, 0, startNode.getWidth(), startNode.getHeight()); outlineBoxNode.setPickable(false); parent.getLayer().getOverlayGUI().addChild(outlineBoxNode); } int startX = Math.min(currentNode.getGridX(), startNode.getGridX()); int endX = Math.max(currentNode.getGridX(), startNode.getGridX()); int startY = Math.min(currentNode.getGridY(), startNode.getGridY()); int endY = Math.max(currentNode.getGridY(), startNode.getGridY()); double x = startX*parent.getGridWidth(); double y = startY * parent.getGridHeight(); double width = Math.min((endX-startX+1)*parent.getGridWidth(), parent.getWidth()-x); double height = Math.min((endY-startY+1)*parent.getGridHeight(), parent.getHeight()-y); if(outlineBoxNode.setBounds(x, y, width, height)){ outlineBoxNode.repaint(); parent.repaint(); } } } else if(state==MOVING){ if(currentNode!=null){ movingSelection.setToOffset(new TileLocation(currentNode.getGridX()-relativeLocation.gridX, currentNode.getGridY()-relativeLocation.gridY)); currentNode.getTilePNodeLayer().getBase().repaint(); } } } } protected TilePNode tryGrabNode(Point2D pos, PCamera cam) { PNode p = getPickedNode(pos, cam); if(p instanceof TilePNode){ TilePNode tile = (TilePNode)p; return tile; } // else{ // if(p instanceof TileLayerPNode){ // System.out.println(p.getWidth() + ", " + p.getHeight()); // } // System.out.println(p.getClass()); // } return null; } }