package com.uwsoft.editor.view.stage.tools.transformStrategy; import com.badlogic.ashley.core.ComponentMapper; import com.badlogic.ashley.core.Entity; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.SnapshotArray; import com.commons.MsgAPI; import com.uwsoft.editor.Overlap2DFacade; import com.uwsoft.editor.renderer.components.CompositeTransformComponent; import com.uwsoft.editor.renderer.components.DimensionsComponent; import com.uwsoft.editor.renderer.components.NodeComponent; import com.uwsoft.editor.renderer.components.TransformComponent; import com.uwsoft.editor.renderer.utils.ComponentRetriever; import com.uwsoft.editor.utils.TransformCommandBuilder; import com.uwsoft.editor.utils.runtime.EntityUtils; import com.uwsoft.editor.view.ui.followers.NormalSelectionFollower; import java.util.*; /** * Created by Sasun Poghosyan on 4/13/2016. */ public class CompositeStrategy extends AbstractTransformStrategy { private ComponentMapper<NodeComponent> nodeMapper = ComponentMapper.getFor(NodeComponent.class); private HashMap<Integer, Vector2> childrenInitialPositions = new HashMap<>(); private HashMap<Integer, Vector2> childrenFinalPositions = new HashMap<>(); private final Array<Object[]> payloads = new Array<>(); private final Vector2 parentInitialPosition = new Vector2(); private final Vector2 parentInitialSize = new Vector2(); private final Vector2 parentFinalPosition = new Vector2(); private final Vector2 parentFinalSize = new Vector2(); public void getInitialPositions(Entity entity) { getParentState(entity, parentInitialPosition, parentInitialSize); childrenInitialPositions.clear(); getChildrenPositions(entity, childrenInitialPositions); } public void swapItemFinalAndInitialStates(Entity entity) { childrenFinalPositions.clear(); getChildrenPositions(entity, childrenFinalPositions); getParentState(entity, parentFinalPosition, parentFinalSize); setEntityChildrenAtPositions(childrenInitialPositions); setParentState(entity, parentInitialPosition, parentInitialSize); sendResizePositionNotification(entity); } private void sendResizePositionNotification(Entity entity) { payloads.clear(); payloads.add(parentEntity(entity)); for (Map.Entry<Integer, Vector2> entrySet : childrenFinalPositions.entrySet()) { Object[] payload = new Object[2]; payload[0] = EntityUtils.getByUniqueId(entrySet.getKey()); payload[1] = entrySet.getValue(); payloads.add(payload); } Overlap2DFacade.getInstance().sendNotification(MsgAPI.ACTION_ITEM_AND_CHILDREN_TO, payloads); } private void setParentState(Entity entity, Vector2 position, Vector2 size) { EntityUtils.setPosition(entity, position); EntityUtils.setSize(entity, size); } private void getParentState(Entity entity, Vector2 position, Vector2 size) { EntityUtils.getPosition(entity, position); EntityUtils.getSize(entity, size); } private Object[] parentEntity(Entity entity) { Object[] obj = new Object[3]; obj[0] = entity; obj[1] = new Vector2(parentFinalPosition); obj[2] = new Vector2(parentFinalSize); return obj; } private void getChildrenPositions(Entity parentEntity, HashMap<Integer, Vector2> entityPos) { NodeComponent nodeComponent = nodeMapper.get(parentEntity); if (nodeComponent != null) { for (Entity entity : nodeComponent.children) { TransformComponent transformComponent = ComponentRetriever.get(entity, TransformComponent.class); Vector2 currentEntityPos = new Vector2(transformComponent.x, transformComponent.y); entityPos.put(EntityUtils.getEntityId(entity), currentEntityPos); } } } private void setEntityChildrenAtPositions(HashMap<Integer, Vector2> posMap) { for (Map.Entry<Integer, Vector2> entrySet : posMap.entrySet()) { Integer id = entrySet.getKey(); Vector2 position = entrySet.getValue(); Entity entity = EntityUtils.getByUniqueId(id); EntityUtils.setPosition(entity, position); } } @Override public void calculate(float mouseDx, float mouseDy, int anchor, Entity entity, TransformCommandBuilder transformCommandBuilder, Vector2 mousePointStage, float lastTransformAngle, float lastEntityAngle) { CompositeTransformComponent component = entity.getComponent(CompositeTransformComponent.class); TransformComponent transformComponent = ComponentRetriever.get(entity, TransformComponent.class); if (!component.automaticResize) { DimensionsComponent dimensionsComponent = ComponentRetriever.get(entity, DimensionsComponent.class); float newWidth = dimensionsComponent.width; float newHeight = dimensionsComponent.height; float[] horizontal = calculateSizeAndXyAmount(mouseDx, mouseDy, transformComponent.rotation); float[] vertical = calculateSizeAndXyAmount(mouseDx, mouseDy, transformComponent.rotation + 90); float deltaW = horizontal[0] / transformComponent.scaleX; float deltaH = vertical[0] / transformComponent.scaleY; switch (anchor) { case NormalSelectionFollower.L: float x = horizontal[1]; float y = horizontal[2]; move(entity, -deltaW, 0); if (Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT)) { deltaW *= 2; } newWidth = dimensionsComponent.width - deltaW; transformComponent.x += x; transformComponent.y += y; break; case NormalSelectionFollower.R: if (Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT)) { move(entity, deltaW, 0); deltaW *= 2; transformComponent.x -= horizontal[1]; transformComponent.y -= horizontal[2]; } newWidth = dimensionsComponent.width + deltaW; break; case NormalSelectionFollower.B: float x1 = vertical[1]; float y1 = vertical[2]; move(entity, 0, -deltaH); if (Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT)) { deltaH *= 2; } newHeight = dimensionsComponent.height - deltaH; transformComponent.x += x1; transformComponent.y += y1; break; case NormalSelectionFollower.T: if (Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT)) { move(entity, 0, deltaH); deltaH *= 2; transformComponent.x -= vertical[1]; transformComponent.y -= vertical[2]; } newHeight = dimensionsComponent.height + deltaH; break; case NormalSelectionFollower.LT: if (Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT)) { move(entity, -deltaW, deltaH); deltaW *= 2; deltaH *= 2; transformComponent.x -= vertical[1]; transformComponent.y -= vertical[2]; } else { move(entity, -deltaW, 0); } newWidth = dimensionsComponent.width - deltaW; newHeight = dimensionsComponent.height + deltaH; transformComponent.x += horizontal[1]; transformComponent.y += horizontal[2]; break; case NormalSelectionFollower.RT: if (Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT)) { move(entity, deltaW, deltaH); deltaH *= 2; deltaW *= 2; transformComponent.x -= horizontal[1]; transformComponent.y -= horizontal[2]; transformComponent.x -= vertical[1]; transformComponent.y -= vertical[2]; } newWidth = dimensionsComponent.width + deltaW; newHeight = dimensionsComponent.height + deltaH; break; case NormalSelectionFollower.RB: if (Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT)) { move(entity, deltaW, -deltaH); deltaW *= 2; deltaH *= 2; transformComponent.x -= horizontal[1]; transformComponent.y -= horizontal[2]; } else { move(entity, 0, -deltaH); } newWidth = dimensionsComponent.width + deltaW; newHeight = dimensionsComponent.height - deltaH; transformComponent.x += vertical[1]; transformComponent.y += vertical[2]; break; case NormalSelectionFollower.LB: move(entity, -deltaW, -deltaH); if (Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT)) { deltaW *= 2; deltaH *= 2; } newWidth = dimensionsComponent.width - deltaW; newHeight = dimensionsComponent.height - deltaH; transformComponent.x += horizontal[1]; transformComponent.y += horizontal[2]; transformComponent.x += vertical[1]; transformComponent.y += vertical[2]; break; } dimensionsComponent.width = newWidth; dimensionsComponent.height = newHeight; dimensionsComponent.boundBox.width = newWidth; dimensionsComponent.boundBox.height = newHeight; } else { System.out.println("Automatic resize is enabled. Uncheck and try again."); } // Rotating rotating(anchor, transformCommandBuilder, mousePointStage, lastTransformAngle, lastEntityAngle, transformComponent); } private void move(Entity node, float x, float y) { ComponentMapper<TransformComponent> transMapper = ComponentMapper.getFor(TransformComponent.class); SnapshotArray<Entity> nodeEntity = node.getComponent(NodeComponent.class).children; for (Entity child : nodeEntity) { TransformComponent transformComponent = transMapper.get(child); transformComponent.x += x; transformComponent.y += y; } } }