/* * ****************************************************************************** * * 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.ui.followers; import com.badlogic.ashley.core.Entity; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.Group; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.Touchable; import com.badlogic.gdx.scenes.scene2d.ui.Image; import com.commons.MsgAPI; import com.kotcrab.vis.ui.VisUI; import com.puremvc.patterns.observer.Notification; import com.uwsoft.editor.view.ui.widget.actors.basic.PixelRect; import com.uwsoft.editor.Overlap2DFacade; import com.uwsoft.editor.proxy.CursorManager; import com.uwsoft.editor.proxy.EditorTextureManager; import com.uwsoft.editor.view.stage.tools.TransformTool; import com.uwsoft.editor.view.ui.box.UIToolBoxMediator; import com.uwsoft.editor.view.ui.widget.EmptyTarget; /** * Created by azakhary on 5/20/2015. */ public class NormalSelectionFollower extends BasicFollower { private Overlap2DFacade facade; private EditorTextureManager tm; private CursorManager cursorManager; protected PixelRect pixelRect; protected Group transformGroup; protected Actor[] miniRects; public static final int LT = 0; public static final int T = 1; public static final int RT = 2; public static final int R = 3; public static final int RB = 4; public static final int B = 5; public static final int LB = 6; public static final int L = 7; public static final int ORIGIN = 8; public static final int ROTATION_LT = 9; public static final int ROTATION_RT = 10; public static final int ROTATION_RB = 11; public static final int ROTATION_LB = 12; public enum SelectionMode { normal, transform } protected SelectionMode mode = SelectionMode.normal; public NormalSelectionFollower(Entity entity) { super(entity); } @Override public void create() { facade = Overlap2DFacade.getInstance(); tm = facade.retrieveProxy(EditorTextureManager.NAME); cursorManager = Overlap2DFacade.getInstance().retrieveProxy(CursorManager.NAME); transformGroup = new Group(); transformGroup.setVisible(false); pixelRect = new PixelRect(); pixelRect.setOpacity(0.4f); pixelRect.setTouchable(Touchable.disabled); addActor(pixelRect); addActor(transformGroup); initTransformGroup(); hide(); } private Actor getRotationAnchor() { EmptyTarget emptyTarget = new EmptyTarget(20, 20); transformGroup.addActor(emptyTarget); return emptyTarget; } private Image getMiniRect() { Image rect = new Image(VisUI.getSkin().getDrawable("selection-anchor")); int w = (int) (rect.getWidth()/2); int h = (int) (rect.getHeight()/2); rect.setOrigin(w, h); transformGroup.addActor(rect); return rect; } private void positionTransformables() { int w = (int) (miniRects[LT].getWidth()/2); int h = (int) (miniRects[LT].getHeight()/2); miniRects[LT].setX(-w); miniRects[LT].setY(getHeight() - h); miniRects[T].setX((int) (getWidth() / 2) - w); miniRects[T].setY(getHeight() - h); miniRects[RT].setX(getWidth() - w); miniRects[RT].setY(getHeight() - h); miniRects[R].setX(getWidth() - w); miniRects[R].setY((int) (getHeight() / 2) - h); miniRects[RB].setX(getWidth() - w); miniRects[RB].setY(-h); miniRects[B].setX((int) (getWidth() / 2) - w); miniRects[B].setY(-h); miniRects[LB].setX(-w); miniRects[LB].setY(-h); miniRects[L].setX(-w); miniRects[L].setY((int) (getHeight() / 2) - h); miniRects[ORIGIN].setX((int) (transformComponent.originX*transformComponent.scaleX) - w); miniRects[ORIGIN].setY((int) (transformComponent.originY*transformComponent.scaleY) - h); miniRects[ROTATION_LT].setX(-w*2); miniRects[ROTATION_LT].setY(getHeight()); miniRects[ROTATION_RT].setX(getWidth()); miniRects[ROTATION_RT].setY(getHeight()); miniRects[ROTATION_RB].setX(getWidth()); miniRects[ROTATION_RB].setY(-h*2); miniRects[ROTATION_LB].setX(-w * 2); miniRects[ROTATION_LB].setY(-h*2); } private void initTransformGroup() { miniRects = new Actor[13]; // rotation miniRects[ROTATION_LT] = getRotationAnchor(); miniRects[ROTATION_RT] = getRotationAnchor(); miniRects[ROTATION_RB] = getRotationAnchor(); miniRects[ROTATION_LB] = getRotationAnchor(); //scale miniRects[LT] = getMiniRect(); miniRects[T] = getMiniRect(); miniRects[RT] = getMiniRect(); miniRects[R] = getMiniRect(); miniRects[RB] = getMiniRect(); miniRects[B] = getMiniRect(); miniRects[LB] = getMiniRect(); miniRects[L] = getMiniRect(); // origin point Image originAnchor = new Image(VisUI.getSkin().getDrawable("origin-anchor")); transformGroup.addActor(originAnchor); miniRects[ORIGIN] = originAnchor; //TODO: till it works bad, let's hide it miniRects[ORIGIN].setVisible(false); } @Override public void setFollowerListener(FollowerTransformationListener listener) { for(int i = 0; i < miniRects.length; i++) { final int rectId = i; miniRects[i].clearListeners(); miniRects[i].addListener(new AnchorListener(this, listener, rectId) { @Override public void touchDragged(InputEvent event, float x, float y, int pointer) { super.touchDragged(event, x, y, pointer); update(); } @Override public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) { super.enter(event, x, y, pointer, fromActor); } @Override public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) { super.exit(event, x, y, pointer, toActor); } }); } } @Override public void clearFollowerListener() { for(int i = 0; i < miniRects.length; i++) { miniRects[i].clearListeners(); } } @Override public void update() { super.update(); //Update actor dimensions and positions, according to this actor width and height pixelRect.setWidth(getWidth()); pixelRect.setHeight(getHeight()); positionTransformables(); for(int i = 0; i <= 7; i++) { miniRects[i].setRotation(-getRotation()); } } @Override public void handleNotification(Notification notification) { super.handleNotification(notification); switch (notification.getName()) { case MsgAPI.TOOL_SELECTED: if(notification.getBody().equals(TransformTool.NAME)) { setMode(SelectionMode.transform); } else { setMode(SelectionMode.normal); } break; } } public void setMode(SelectionMode mode) { this.mode = mode; if(mode == SelectionMode.normal) { transformGroup.setVisible(false); } else { transformGroup.setVisible(true); } } public SelectionMode getMode() { return mode; } }