Spec-Zone .ru
спецификации, руководства, описания, API
001/*
002 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.  Oracle designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Oracle in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
022 * or visit www.oracle.com if you need additional information or have any
023 * questions.
024 */
025
026package javafx.scene.input;
027
028import com.sun.javafx.collections.annotations.ReturnsUnmodifiableCollection;
029import java.util.Collections;
030import java.util.List;
031import javafx.event.Event;
032import javafx.event.EventTarget;
033import javafx.event.EventType;
034
035/**
036 * Touch event indicates a touch screen action. It contains detailed information
037 * about each particular touch point.
038 * <p>
039 * Touch point represents a single touched finger and has its location,
040 * state (pressed/moved/released/stationary) and an ID unique in scope of a
041 * single gesture. For detailed reference see {@link TouchPoint}.
042 * <p>
043 * For each multi-touch action a set of touch events is generated - for each
044 * touch point one. The event has type corresponds to its touch point's state.
045 * Each of the events also contain
046 * list of all the touch points. This design allows for handling complicated
047 * multi-touch actions from one place while keeping it possible to
048 * filter/consume each touch point separately. To recognize
049 * which events belong into a single set there is {@code getEventSetId()}
050 * method.
051 * <p>
052 * Each touch point is - similarly to mouse dragging - delivered to a single
053 * node on which it was pressed, regardless of where it moves then. It is
054 * possible to change this behavior by using a grabbing mechanism described
055 * in {@link TouchPoint} documentation.
056 *
057 * @since 2.2
058 */
059public final class TouchEvent extends InputEvent {
060
061    private static final long serialVersionUID = 20121107L;
062
063    /**
064     * Common supertype for all touch event types.
065     */
066    public static final EventType<TouchEvent> ANY =
067            new EventType<TouchEvent>(InputEvent.ANY, "TOUCH");
068
069    /**
070     * This event occurs when the touch point is pressed (touched for the
071     * first time).
072     */
073    public static final EventType<TouchEvent> TOUCH_PRESSED =
074            new EventType<TouchEvent>(ANY, "TOUCH_PRESSED");
075
076    /**
077     * This event occurs when the touch point is moved.
078     */
079    public static final EventType<TouchEvent> TOUCH_MOVED =
080            new EventType<TouchEvent>(ANY, "TOUCH_MOVED");
081
082    /**
083     * This event occurs when the touch point is released.
084     */
085    public static final EventType<TouchEvent> TOUCH_RELEASED =
086            new EventType<TouchEvent>(ANY, "TOUCH_RELEASED");
087
088    /**
089     * This event occurs when the touch point is pressed and still (doesn't
090     * move).
091     */
092    public static final EventType<TouchEvent> TOUCH_STATIONARY =
093            new EventType<TouchEvent>(ANY, "TOUCH_STATIONARY");
094
095    /**
096     * Constructs new TouchEvent event.
097     * @param source the source of the event. Can be null.
098     * @param target the target of the event. Can be null.
099     * @param eventType The type of the event.
100     * @param touchPoint the touch point of this event
101     * @param touchPoints set of touch points for the multi-touch action
102     * @param eventSetId set id of the multi-touch action
103     * @param shiftDown true if shift modifier was pressed.
104     * @param controlDown true if control modifier was pressed.
105     * @param altDown true if alt modifier was pressed.
106     * @param metaDown true if meta modifier was pressed.
107     */
108    public TouchEvent(Object source, EventTarget target, EventType<TouchEvent> eventType,
109            TouchPoint touchPoint, List<TouchPoint> touchPoints, int eventSetId,
110            boolean shiftDown, boolean controlDown, boolean altDown,
111            boolean metaDown) {
112        super(source, target, eventType);
113        this.touchPoints = touchPoints != null ? Collections.unmodifiableList(touchPoints) : null;
114        this.eventSetId = eventSetId;
115        this.shiftDown = shiftDown;
116        this.controlDown = controlDown;
117        this.altDown = altDown;
118        this.metaDown = metaDown;
119        this.touchPoint = touchPoint;
120    }
121
122    /**
123     * Constructs new TouchEvent event with null source and target.
124     * @param eventType The type of the event.
125     * @param touchPoint the touch point of this event
126     * @param touchPoints set of touch points for the multi-touch action
127     * @param eventSetId set id of the multi-touch action
128     * @param shiftDown true if shift modifier was pressed.
129     * @param controlDown true if control modifier was pressed.
130     * @param altDown true if alt modifier was pressed.
131     * @param metaDown true if meta modifier was pressed.
132     * @param direct true if the event was caused by direct input device. See {@link #isDirect() }
133     */
134    public TouchEvent(EventType<TouchEvent> eventType,
135            TouchPoint touchPoint, List<TouchPoint> touchPoints, int eventSetId,
136            boolean shiftDown, boolean controlDown, boolean altDown,
137            boolean metaDown) {
138        this(null, null, eventType, touchPoint, touchPoints, eventSetId,
139                shiftDown, controlDown, altDown, metaDown);
140    }
141
142    /**
143     * Returns number of touch points represented by this touch event set.
144     * The returned number matches the size of the {@code touchPoints} list.
145     * @return The number of touch points represented by this touch event set.
146     */
147    public int getTouchCount() {
148        return touchPoints.size();
149    }
150
151    /**
152     * Recomputes touch event for the given event source object.
153     * @param event Event to modify
154     * @param oldSource Source object of the current values
155     * @param newSource Source object to compute values for
156     */
157    private static void recomputeToSource(TouchEvent event, Object oldSource,
158            Object newSource) {
159
160        for (TouchPoint tp : event.touchPoints) {
161            tp.recomputeToSource(oldSource, newSource);
162        }
163    }
164
165
166    /**
167     * @inheritDoc
168     */
169    @Override
170    public TouchEvent copyFor(Object newSource, EventTarget newTarget) {
171        TouchEvent e = (TouchEvent) super.copyFor(newSource, newTarget);
172        recomputeToSource(e, getSource(), newSource);
173        return e;
174    }
175    
176    /**
177     * Creates a copy of the given event with the given fields substituted.
178     * @param source the new source of the copied event
179     * @param target the new target of the copied event
180     * @param eventType the new eventType
181     * @return the event copy with the fields substituted
182     */
183    public TouchEvent copyFor(Object newSource, EventTarget newTarget, EventType<TouchEvent> type) {
184        TouchEvent e = copyFor(newSource, newTarget);
185        e.eventType = type;
186        return e;
187    }
188
189    @Override
190    public EventType<TouchEvent> getEventType() {
191        return (EventType<TouchEvent>) super.getEventType();
192    }
193    
194    private final int eventSetId;
195
196    /**
197     * Gets sequential number of the set of touch events representing the same
198     * multi-touch action. For a multi-touch user action, number of touch points
199     * may exist; each of them produces a touch event, each of those touch
200     * events carry the same list of touch points - and all of them return the
201     * same number from this method. Then state of some of the touch points
202     * changes and the new set of events has new id. The id is guaranteed
203     * to be sequential and unique in scope of one gesture (is reset when
204     * all touch points are released).
205     *
206     * @return Sequential id of event set unique in scope of a gesture
207     */
208    public final int getEventSetId() {
209        return eventSetId;
210    }
211
212
213    /**
214     * Whether or not the Shift modifier is down on this event.
215     */
216    private final boolean shiftDown;
217
218    /**
219     * Whether or not the Shift modifier is down on this event.
220     * @return true if the Shift modifier is down on this event
221     */
222    public final boolean isShiftDown() {
223        return shiftDown;
224    }
225
226    /**
227     * Whether or not the Control modifier is down on this event.
228     */
229    private final boolean controlDown;
230
231    /**
232     * Whether or not the Control modifier is down on this event.
233     * @return true if the Control modifier is down on this event
234     */
235    public final boolean isControlDown() {
236        return controlDown;
237    }
238
239    /**
240     * Whether or not the Alt modifier is down on this event.
241     */
242    private final boolean altDown;
243
244    /**
245     * Whether or not the Alt modifier is down on this event.
246     * @return true if the Alt modifier is down on this event
247     */
248    public final boolean isAltDown() {
249        return altDown;
250    }
251
252    /**
253     * Whether or not the Meta modifier is down on this event.
254     */
255    private final boolean metaDown;
256
257    /**
258     * Whether or not the Meta modifier is down on this event.
259     * @return true if the Meta modifier is down on this event
260     */
261    public final boolean isMetaDown() {
262        return metaDown;
263    }
264
265    private final TouchPoint touchPoint;
266
267    /**
268     * Gets the touch point of this event.
269     * @return Touch point of this event
270     */
271    public TouchPoint getTouchPoint() {
272        return touchPoint;
273    }
274
275    private final List<TouchPoint> touchPoints;
276
277    /**
278     * Gets all the touch points represented by this set of touch events,
279     * including the touch point of this event. The list is unmodifiable and 
280     * is sorted by their IDs, which means it is also sorted by the time
281     * they were pressed. To distinguish between touch points belonging to
282     * a node and unrelated touch points, TouchPoint's {@code belongsTo}
283     * method can be used.
284     * @return All current touch points in an unmodifiable list
285     */
286    @ReturnsUnmodifiableCollection 
287    public List<TouchPoint> getTouchPoints() {
288        return touchPoints;
289    }
290
291    /**
292     * Returns a string representation of this {@code TouchEvent} object.
293     * @return a string representation of this {@code TouchEvent} object.
294     */
295    @Override public String toString() {
296        final StringBuilder sb = new StringBuilder("TouchEvent [");
297
298        sb.append("source = ").append(getSource());
299        sb.append(", target = ").append(getTarget());
300        sb.append(", eventType = ").append(getEventType());
301        sb.append(", consumed = ").append(isConsumed());
302        sb.append(", touchCount = ").append(getTouchCount());
303        sb.append(", eventSetId = ").append(getEventSetId());
304
305        sb.append(", touchPoint = ").append(getTouchPoint().toString());
306
307        return sb.append("]").toString();
308    }
309
310}