1 /* 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javafx.scene.input; 27 28 import com.sun.javafx.collections.annotations.ReturnsUnmodifiableCollection; 29 import java.util.Collections; 30 import java.util.List; 31 import javafx.beans.NamedArg; 32 import javafx.event.Event; 33 import javafx.event.EventTarget; 34 import javafx.event.EventType; 35 36 /** 37 * Touch event indicates a touch screen action. It contains detailed information 38 * about each particular touch point. 39 * <p> 40 * Touch point represents a single touched finger and has its location, 41 * state (pressed/moved/released/stationary) and an ID unique in scope of a 42 * single gesture. For detailed reference see {@link TouchPoint}. 43 * <p> 44 * For each multi-touch action a set of touch events is generated - for each 45 * touch point one. The event has type corresponds to its touch point's state. 46 * Each of the events also contain 47 * list of all the touch points. This design allows for handling complicated 48 * multi-touch actions from one place while keeping it possible to 49 * filter/consume each touch point separately. To recognize 50 * which events belong into a single set there is {@code getEventSetId()} 51 * method. 52 * <p> 53 * Each touch point is - similarly to mouse dragging - delivered to a single 54 * node on which it was pressed, regardless of where it moves then. It is 55 * possible to change this behavior by using a grabbing mechanism described 56 * in {@link TouchPoint} documentation. 57 * 58 * @since JavaFX 2.2 59 */ 60 public final class TouchEvent extends InputEvent { 61 62 private static final long serialVersionUID = 20121107L; 63 64 /** 65 * Common supertype for all touch event types. 66 */ 67 public static final EventType<TouchEvent> ANY = 68 new EventType<TouchEvent>(InputEvent.ANY, "TOUCH"); 69 70 /** 71 * This event occurs when the touch point is pressed (touched for the 72 * first time). 73 */ 74 public static final EventType<TouchEvent> TOUCH_PRESSED = 75 new EventType<TouchEvent>(ANY, "TOUCH_PRESSED"); 76 77 /** 78 * This event occurs when the touch point is moved. 79 */ 80 public static final EventType<TouchEvent> TOUCH_MOVED = 81 new EventType<TouchEvent>(ANY, "TOUCH_MOVED"); 82 83 /** 84 * This event occurs when the touch point is released. 85 */ 86 public static final EventType<TouchEvent> TOUCH_RELEASED = 87 new EventType<TouchEvent>(ANY, "TOUCH_RELEASED"); 88 89 /** 90 * This event occurs when the touch point is pressed and still (doesn't 91 * move). 92 */ 93 public static final EventType<TouchEvent> TOUCH_STATIONARY = 94 new EventType<TouchEvent>(ANY, "TOUCH_STATIONARY"); 95 96 /** 97 * Constructs new TouchEvent event. 98 * @param source the source of the event. Can be null. 99 * @param target the target of the event. Can be null. 100 * @param eventType The type of the event. 101 * @param touchPoint the touch point of this event 102 * @param touchPoints set of touch points for the multi-touch action 103 * @param eventSetId set id of the multi-touch action 104 * @param shiftDown true if shift modifier was pressed. 105 * @param controlDown true if control modifier was pressed. 106 * @param altDown true if alt modifier was pressed. 107 * @param metaDown true if meta modifier was pressed. 108 * @since JavaFX 8.0 109 */ 110 public TouchEvent(@NamedArg("source") Object source, @NamedArg("target") EventTarget target, @NamedArg("eventType") EventType<TouchEvent> eventType, 111 @NamedArg("touchPoint") TouchPoint touchPoint, @NamedArg("touchPoints") List<TouchPoint> touchPoints, @NamedArg("eventSetId") int eventSetId, 112 @NamedArg("shiftDown") boolean shiftDown, @NamedArg("controlDown") boolean controlDown, @NamedArg("altDown") boolean altDown, 113 @NamedArg("metaDown") boolean metaDown) { 114 super(source, target, eventType); 115 this.touchPoints = touchPoints != null ? Collections.unmodifiableList(touchPoints) : null; 116 this.eventSetId = eventSetId; 117 this.shiftDown = shiftDown; 118 this.controlDown = controlDown; 119 this.altDown = altDown; 120 this.metaDown = metaDown; 121 this.touchPoint = touchPoint; 122 } 123 124 /** 125 * Constructs new TouchEvent event with null source and target. 126 * @param eventType The type of the event. 127 * @param touchPoint the touch point of this event 128 * @param touchPoints set of touch points for the multi-touch action 129 * @param eventSetId set id of the multi-touch action 130 * @param shiftDown true if shift modifier was pressed. 131 * @param controlDown true if control modifier was pressed. 132 * @param altDown true if alt modifier was pressed. 133 * @param metaDown true if meta modifier was pressed. 134 * @since JavaFX 8.0 135 */ 136 public TouchEvent(@NamedArg("eventType") EventType<TouchEvent> eventType, 137 @NamedArg("touchPoint") TouchPoint touchPoint, @NamedArg("touchPoints") List<TouchPoint> touchPoints, @NamedArg("eventSetId") int eventSetId, 138 @NamedArg("shiftDown") boolean shiftDown, @NamedArg("controlDown") boolean controlDown, @NamedArg("altDown") boolean altDown, 139 @NamedArg("metaDown") boolean metaDown) { 140 this(null, null, eventType, touchPoint, touchPoints, eventSetId, 141 shiftDown, controlDown, altDown, metaDown); 142 } 143 144 /** 145 * Returns number of touch points represented by this touch event set. 146 * The returned number matches the size of the {@code touchPoints} list. 147 * @return The number of touch points represented by this touch event set. 148 */ 149 public int getTouchCount() { 150 return touchPoints.size(); 151 } 152 153 /** 154 * Recomputes touch event for the given event source object. 155 * @param event Event to modify 156 * @param oldSource Source object of the current values 157 * @param newSource Source object to compute values for 158 */ 159 private static void recomputeToSource(TouchEvent event, Object oldSource, 160 Object newSource) { 161 162 for (TouchPoint tp : event.touchPoints) { 163 tp.recomputeToSource(oldSource, newSource); 164 } 165 } 166 167 168 /** 169 * @inheritDoc 170 */ 171 @Override 172 public TouchEvent copyFor(Object newSource, EventTarget newTarget) { 173 TouchEvent e = (TouchEvent) super.copyFor(newSource, newTarget); 174 recomputeToSource(e, getSource(), newSource); 175 return e; 176 } 177 178 /** 179 * Creates a copy of the given event with the given fields substituted. 180 * @param newSource the new source of the copied event 181 * @param newTarget the new target of the copied event 182 * @param type the new eventType 183 * @return the event copy with the fields substituted 184 * @since JavaFX 8.0 185 */ 186 public TouchEvent copyFor(Object newSource, EventTarget newTarget, EventType<TouchEvent> type) { 187 TouchEvent e = copyFor(newSource, newTarget); 188 e.eventType = type; 189 return e; 190 } 191 192 @Override 193 public EventType<TouchEvent> getEventType() { 194 return (EventType<TouchEvent>) super.getEventType(); 195 } 196 197 private final int eventSetId; 198 199 /** 200 * Gets sequential number of the set of touch events representing the same 201 * multi-touch action. For a multi-touch user action, number of touch points 202 * may exist; each of them produces a touch event, each of those touch 203 * events carry the same list of touch points - and all of them return the 204 * same number from this method. Then state of some of the touch points 205 * changes and the new set of events has new id. The id is guaranteed 206 * to be sequential and unique in scope of one gesture (is reset when 207 * all touch points are released). 208 * 209 * @return Sequential id of event set unique in scope of a gesture 210 */ 211 public final int getEventSetId() { 212 return eventSetId; 213 } 214 215 216 /** 217 * Whether or not the Shift modifier is down on this event. 218 */ 219 private final boolean shiftDown; 220 221 /** 222 * Whether or not the Shift modifier is down on this event. 223 * @return true if the Shift modifier is down on this event 224 */ 225 public final boolean isShiftDown() { 226 return shiftDown; 227 } 228 229 /** 230 * Whether or not the Control modifier is down on this event. 231 */ 232 private final boolean controlDown; 233 234 /** 235 * Whether or not the Control modifier is down on this event. 236 * @return true if the Control modifier is down on this event 237 */ 238 public final boolean isControlDown() { 239 return controlDown; 240 } 241 242 /** 243 * Whether or not the Alt modifier is down on this event. 244 */ 245 private final boolean altDown; 246 247 /** 248 * Whether or not the Alt modifier is down on this event. 249 * @return true if the Alt modifier is down on this event 250 */ 251 public final boolean isAltDown() { 252 return altDown; 253 } 254 255 /** 256 * Whether or not the Meta modifier is down on this event. 257 */ 258 private final boolean metaDown; 259 260 /** 261 * Whether or not the Meta modifier is down on this event. 262 * @return true if the Meta modifier is down on this event 263 */ 264 public final boolean isMetaDown() { 265 return metaDown; 266 } 267 268 private final TouchPoint touchPoint; 269 270 /** 271 * Gets the touch point of this event. 272 * @return Touch point of this event 273 */ 274 public TouchPoint getTouchPoint() { 275 return touchPoint; 276 } 277 278 private final List<TouchPoint> touchPoints; 279 280 /** 281 * Gets all the touch points represented by this set of touch events, 282 * including the touch point of this event. The list is unmodifiable and 283 * is sorted by their IDs, which means it is also sorted by the time 284 * they were pressed. To distinguish between touch points belonging to 285 * a node and unrelated touch points, TouchPoint's {@code belongsTo} 286 * method can be used. 287 * @return All current touch points in an unmodifiable list 288 */ 289 @ReturnsUnmodifiableCollection 290 public List<TouchPoint> getTouchPoints() { 291 return touchPoints; 292 } 293 294 /** 295 * Returns a string representation of this {@code TouchEvent} object. 296 * @return a string representation of this {@code TouchEvent} object. 297 */ 298 @Override public String toString() { 299 final StringBuilder sb = new StringBuilder("TouchEvent ["); 300 301 sb.append("source = ").append(getSource()); 302 sb.append(", target = ").append(getTarget()); 303 sb.append(", eventType = ").append(getEventType()); 304 sb.append(", consumed = ").append(isConsumed()); 305 sb.append(", touchCount = ").append(getTouchCount()); 306 sb.append(", eventSetId = ").append(getEventSetId()); 307 308 sb.append(", touchPoint = ").append(getTouchPoint().toString()); 309 310 return sb.append("]").toString(); 311 } 312 313 }