/*
* ******************************************************************************
* * Copyright 2015 See AUTHORS file.
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
* *****************************************************************************
*/
package com.uwsoft.editor.view.stage.tools;
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.math.Vector2;
import com.commons.MsgAPI;
import com.puremvc.patterns.observer.Notification;
import com.uwsoft.editor.Overlap2DFacade;
import com.uwsoft.editor.proxy.CursorManager;
import com.uwsoft.editor.renderer.components.TransformComponent;
import com.uwsoft.editor.renderer.factory.EntityFactory;
import com.uwsoft.editor.renderer.utils.ComponentRetriever;
import com.uwsoft.editor.view.stage.tools.transformStrategy.BasicStrategy;
import com.uwsoft.editor.view.stage.tools.transformStrategy.CompositeStrategy;
import com.uwsoft.editor.view.stage.tools.transformStrategy.ITransformStrategy;
import com.uwsoft.editor.view.stage.tools.transformStrategy.NinePatchStrategy;
import com.uwsoft.editor.utils.TransformCommandBuilder;
import com.uwsoft.editor.utils.runtime.EntityUtils;
import com.uwsoft.editor.view.stage.Sandbox;
import com.uwsoft.editor.view.ui.FollowersUIMediator;
import com.uwsoft.editor.view.ui.followers.FollowerTransformationListener;
import com.uwsoft.editor.view.ui.followers.NormalSelectionFollower;
import java.util.HashSet;
import java.util.Set;
/**
* Created by azakhary on 4/30/2015.
*/
public class TransformTool extends SelectionTool implements FollowerTransformationListener {
public static final String NAME = "TRANSFORM_TOOL";
private float lastTransformAngle = 0;
private float lastEntityAngle = 0;
private final Vector2 mouseInitialCoordinates = new Vector2();
private CursorManager cursorManager;
private TransformCommandBuilder commandBuilder = new TransformCommandBuilder();
private final BasicStrategy basicStrategy = new BasicStrategy();
private final CompositeStrategy compositeStrategy = new CompositeStrategy();
private final NinePatchStrategy ninePatchStrategy = new NinePatchStrategy();
private ITransformStrategy transformStrategy;
public void execute(Vector2 mouseInitialCoordinates, Vector2 mousePointStage, int anchor, Entity entity) {
float mouseDx = mousePointStage.x - mouseInitialCoordinates.x;
float mouseDy = mousePointStage.y - mouseInitialCoordinates.y;
transformStrategy.calculate(mouseDx, mouseDy, anchor, entity, commandBuilder, mousePointStage, lastTransformAngle, lastEntityAngle);
}
@Override
public String getName() {
return NAME;
}
@Override
public void initTool() {
sandbox = Sandbox.getInstance();
if (!sandbox.getSelector().selectionIsOneItem()) {
sandbox.getSelector().clearSelections();
}
updateListeners();
// set cursor
cursorManager = Overlap2DFacade.getInstance().retrieveProxy(CursorManager.NAME);
cursorManager.setCursor(CursorManager.CROSS);
}
@Override
public void handleNotification(Notification notification) {
switch (notification.getName()) {
case MsgAPI.NEW_ITEM_ADDED:
updateListeners((Entity) notification.getBody());
break;
}
}
@Override
public void stageMouseUp(float x, float y) {
super.stageMouseUp(x, y);
updateListeners();
}
@Override
public void itemMouseUp(Entity entity, float x, float y) {
super.itemMouseUp(entity, x, y);
updateListeners();
}
private void updateListeners() {
Sandbox sandbox = Sandbox.getInstance();
Set<Entity> selectedEntities = sandbox.getSelector().getSelectedItems();
updateListeners(selectedEntities);
}
private void updateListeners(Entity entity) {
Set<Entity> entities = new HashSet<>();
entities.add(entity);
updateListeners(entities);
}
private void updateListeners(Set<Entity> entities) {
FollowersUIMediator followersUIMediator = Overlap2DFacade.getInstance().retrieveMediator(FollowersUIMediator.NAME);
followersUIMediator.clearAllListeners();
for (Entity entity : entities) {
followersUIMediator.getFollower(entity).setFollowerListener(this);
}
}
@Override
public void anchorDown(NormalSelectionFollower follower, int anchor, float x, float y) {
Sandbox sandbox = Sandbox.getInstance();
commandBuilder.begin(follower.getEntity());
TransformComponent transformComponent = ComponentRetriever.get(follower.getEntity(), TransformComponent.class);
Vector2 mousePoint = sandbox.screenToWorld(x, y);
mouseInitialCoordinates.set(mousePoint.x, mousePoint.y);
switch (EntityUtils.getType(follower.getEntity())) {
case EntityFactory.COMPOSITE_TYPE:
transformStrategy = compositeStrategy;
compositeStrategy.getInitialPositions(follower.getEntity());
break;
case EntityFactory.NINE_PATCH:
transformStrategy = ninePatchStrategy;
break;
default:
transformStrategy = basicStrategy;
break;
}
commandBuilder.begin(follower.getEntity());
if (anchor == NormalSelectionFollower.ROTATION_LT ||
anchor == NormalSelectionFollower.ROTATION_RT ||
anchor == NormalSelectionFollower.ROTATION_RB ||
anchor == NormalSelectionFollower.ROTATION_LB) {
// get mouse stage coordinates
Vector2 originPoint = new Vector2(transformComponent.x + transformComponent.originX, transformComponent.y + transformComponent.originY);
mousePoint.sub(originPoint);
//origin related
lastTransformAngle = mousePoint.angle();
lastEntityAngle = transformComponent.rotation;
}
}
@Override
public void anchorUp(NormalSelectionFollower follower, int anchor, float x, float y) {
commandBuilder.execute();
if (transformStrategy == compositeStrategy) {
compositeStrategy.swapItemFinalAndInitialStates(follower.getEntity());
}
}
@Override
public void anchorDragged(NormalSelectionFollower follower, int anchor, float x, float y) {
Sandbox sandbox = Sandbox.getInstance();
Vector2 mousePointStage = sandbox.screenToWorld(x, y);
execute(mouseInitialCoordinates, mousePointStage, anchor, follower.getEntity());
mouseInitialCoordinates.set(mousePointStage.x, mousePointStage.y);
Overlap2DFacade.getInstance().sendNotification(MsgAPI.ITEM_DATA_UPDATED);
}
@Override
public void anchorMouseEnter(NormalSelectionFollower follower, int anchor, float x, float y) {
switch (anchor) {
case NormalSelectionFollower.ROTATION_LB:
cursorManager.setCursor(CursorManager.ROTATION_LB);
break;
case NormalSelectionFollower.ROTATION_LT:
cursorManager.setCursor(CursorManager.ROTATION_LT);
break;
case NormalSelectionFollower.ROTATION_RT:
cursorManager.setCursor(CursorManager.ROTATION_RT);
break;
case NormalSelectionFollower.ROTATION_RB:
cursorManager.setCursor(CursorManager.ROTATION_RB);
break;
case NormalSelectionFollower.LB:
cursorManager.setCursor(CursorManager.TRANSFORM_LEFT_RIGHT);
break;
case NormalSelectionFollower.L:
cursorManager.setCursor(CursorManager.TRANSFORM_HORIZONTAL);
break;
case NormalSelectionFollower.LT:
cursorManager.setCursor(CursorManager.TRANSFORM_RIGHT_LEFT);
break;
case NormalSelectionFollower.T:
cursorManager.setCursor(CursorManager.TRANSFORM_VERTICAL);
break;
case NormalSelectionFollower.RT:
cursorManager.setCursor(CursorManager.TRANSFORM_LEFT_RIGHT);
break;
case NormalSelectionFollower.R:
cursorManager.setCursor(CursorManager.TRANSFORM_HORIZONTAL);
break;
case NormalSelectionFollower.RB:
cursorManager.setCursor(CursorManager.TRANSFORM_RIGHT_LEFT);
break;
case NormalSelectionFollower.B:
cursorManager.setCursor(CursorManager.TRANSFORM_VERTICAL);
break;
default:
cursorManager.setCursor(CursorManager.NORMAL);
break;
}
}
@Override
public void anchorMouseExit(NormalSelectionFollower follower, int anchor, float x, float y) {
cursorManager.setCursor(CursorManager.CROSS);
}
}