• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright 2011 See AUTHORS file.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  ******************************************************************************/
16 
17 package com.badlogic.gdx.scenes.scene2d.utils;
18 
19 import com.badlogic.gdx.input.GestureDetector;
20 import com.badlogic.gdx.input.GestureDetector.GestureAdapter;
21 import com.badlogic.gdx.math.Vector2;
22 import com.badlogic.gdx.scenes.scene2d.Actor;
23 import com.badlogic.gdx.scenes.scene2d.Event;
24 import com.badlogic.gdx.scenes.scene2d.EventListener;
25 import com.badlogic.gdx.scenes.scene2d.InputEvent;
26 
27 /** Detects tap, long press, fling, pan, zoom, and pinch gestures on an actor. If there is only a need to detect tap, use
28  * {@link ClickListener}.
29  * @see GestureDetector
30  * @author Nathan Sweet */
31 public class ActorGestureListener implements EventListener {
32 	static final Vector2 tmpCoords = new Vector2(), tmpCoords2 = new Vector2();
33 
34 	private final GestureDetector detector;
35 	InputEvent event;
36 	Actor actor, touchDownTarget;
37 
38 	/** @see GestureDetector#GestureDetector(com.badlogic.gdx.input.GestureDetector.GestureListener) */
ActorGestureListener()39 	public ActorGestureListener () {
40 		this(20, 0.4f, 1.1f, 0.15f);
41 	}
42 
43 	/** @see GestureDetector#GestureDetector(float, float, float, float, com.badlogic.gdx.input.GestureDetector.GestureListener) */
ActorGestureListener(float halfTapSquareSize, float tapCountInterval, float longPressDuration, float maxFlingDelay)44 	public ActorGestureListener (float halfTapSquareSize, float tapCountInterval, float longPressDuration, float maxFlingDelay) {
45 		detector = new GestureDetector(halfTapSquareSize, tapCountInterval, longPressDuration, maxFlingDelay, new GestureAdapter() {
46 			private final Vector2 initialPointer1 = new Vector2(), initialPointer2 = new Vector2();
47 			private final Vector2 pointer1 = new Vector2(), pointer2 = new Vector2();
48 
49 			public boolean tap (float stageX, float stageY, int count, int button) {
50 				actor.stageToLocalCoordinates(tmpCoords.set(stageX, stageY));
51 				ActorGestureListener.this.tap(event, tmpCoords.x, tmpCoords.y, count, button);
52 				return true;
53 			}
54 
55 			public boolean longPress (float stageX, float stageY) {
56 				actor.stageToLocalCoordinates(tmpCoords.set(stageX, stageY));
57 				return ActorGestureListener.this.longPress(actor, tmpCoords.x, tmpCoords.y);
58 			}
59 
60 			public boolean fling (float velocityX, float velocityY, int button) {
61 				stageToLocalAmount(tmpCoords.set(velocityX, velocityY));
62 				ActorGestureListener.this.fling(event, tmpCoords.x, tmpCoords.y, button);
63 				return true;
64 			}
65 
66 			public boolean pan (float stageX, float stageY, float deltaX, float deltaY) {
67 				stageToLocalAmount(tmpCoords.set(deltaX, deltaY));
68 				deltaX = tmpCoords.x;
69 				deltaY = tmpCoords.y;
70 				actor.stageToLocalCoordinates(tmpCoords.set(stageX, stageY));
71 				ActorGestureListener.this.pan(event, tmpCoords.x, tmpCoords.y, deltaX, deltaY);
72 				return true;
73 			}
74 
75 			public boolean zoom (float initialDistance, float distance) {
76 				ActorGestureListener.this.zoom(event, initialDistance, distance);
77 				return true;
78 			}
79 
80 			public boolean pinch (Vector2 stageInitialPointer1, Vector2 stageInitialPointer2, Vector2 stagePointer1,
81 				Vector2 stagePointer2) {
82 				actor.stageToLocalCoordinates(initialPointer1.set(stageInitialPointer1));
83 				actor.stageToLocalCoordinates(initialPointer2.set(stageInitialPointer2));
84 				actor.stageToLocalCoordinates(pointer1.set(stagePointer1));
85 				actor.stageToLocalCoordinates(pointer2.set(stagePointer2));
86 				ActorGestureListener.this.pinch(event, initialPointer1, initialPointer2, pointer1, pointer2);
87 				return true;
88 			}
89 
90 			private void stageToLocalAmount (Vector2 amount) {
91 				actor.stageToLocalCoordinates(amount);
92 				amount.sub(actor.stageToLocalCoordinates(tmpCoords2.set(0, 0)));
93 			}
94 		});
95 	}
96 
handle(Event e)97 	public boolean handle (Event e) {
98 		if (!(e instanceof InputEvent)) return false;
99 		InputEvent event = (InputEvent)e;
100 
101 		switch (event.getType()) {
102 		case touchDown:
103 			actor = event.getListenerActor();
104 			touchDownTarget = event.getTarget();
105 			detector.touchDown(event.getStageX(), event.getStageY(), event.getPointer(), event.getButton());
106 			actor.stageToLocalCoordinates(tmpCoords.set(event.getStageX(), event.getStageY()));
107 			touchDown(event, tmpCoords.x, tmpCoords.y, event.getPointer(), event.getButton());
108 			return true;
109 		case touchUp:
110 			if (event.isTouchFocusCancel()) return false;
111 			this.event = event;
112 			actor = event.getListenerActor();
113 			detector.touchUp(event.getStageX(), event.getStageY(), event.getPointer(), event.getButton());
114 			actor.stageToLocalCoordinates(tmpCoords.set(event.getStageX(), event.getStageY()));
115 			touchUp(event, tmpCoords.x, tmpCoords.y, event.getPointer(), event.getButton());
116 			return true;
117 		case touchDragged:
118 			this.event = event;
119 			actor = event.getListenerActor();
120 			detector.touchDragged(event.getStageX(), event.getStageY(), event.getPointer());
121 			return true;
122 		}
123 		return false;
124 	}
125 
touchDown(InputEvent event, float x, float y, int pointer, int button)126 	public void touchDown (InputEvent event, float x, float y, int pointer, int button) {
127 	}
128 
touchUp(InputEvent event, float x, float y, int pointer, int button)129 	public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
130 	}
131 
tap(InputEvent event, float x, float y, int count, int button)132 	public void tap (InputEvent event, float x, float y, int count, int button) {
133 	}
134 
135 	/** If true is returned, additional gestures will not be triggered. No event is provided because this event is triggered by time
136 	 * passing, not by an InputEvent. */
longPress(Actor actor, float x, float y)137 	public boolean longPress (Actor actor, float x, float y) {
138 		return false;
139 	}
140 
fling(InputEvent event, float velocityX, float velocityY, int button)141 	public void fling (InputEvent event, float velocityX, float velocityY, int button) {
142 	}
143 
144 	/** The delta is the difference in stage coordinates since the last pan. */
pan(InputEvent event, float x, float y, float deltaX, float deltaY)145 	public void pan (InputEvent event, float x, float y, float deltaX, float deltaY) {
146 	}
147 
zoom(InputEvent event, float initialDistance, float distance)148 	public void zoom (InputEvent event, float initialDistance, float distance) {
149 	}
150 
pinch(InputEvent event, Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2)151 	public void pinch (InputEvent event, Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2) {
152 	}
153 
getGestureDetector()154 	public GestureDetector getGestureDetector () {
155 		return detector;
156 	}
157 
getTouchDownTarget()158 	public Actor getTouchDownTarget () {
159 		return touchDownTarget;
160 	}
161 }
162