diff options
author | Scott Kovatch <skovatch> | 2011-01-17 22:46:48 +0000 |
---|---|---|
committer | Scott Kovatch <skovatch> | 2011-01-17 22:46:48 +0000 |
commit | 92ca57cf28cccc9ff516d24846fb2cf295e0276b (patch) | |
tree | 1bec47a08bccedba135ebeae2b85ab0c243de5a9 /bundles/org.eclipse.swt/Eclipse SWT | |
parent | f2baed61eb63d2f361e0bcedf8f5898e1419dca7 (diff) | |
download | eclipse.platform.swt-92ca57cf28cccc9ff516d24846fb2cf295e0276b.tar.gz eclipse.platform.swt-92ca57cf28cccc9ff516d24846fb2cf295e0276b.tar.xz eclipse.platform.swt-92ca57cf28cccc9ff516d24846fb2cf295e0276b.zip |
279884 - Add support for touch events. Also some gesture code cleanup.
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT')
11 files changed, 624 insertions, 117 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java index 5f583dd9bb..5e92411a18 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java @@ -981,6 +981,30 @@ public class SWT { public static final int GESTURE_PAN = 1 << 6; /** + * A constant indicating that a finger touched the device. + * + * @see org.eclipse.swt.widgets.Touch.state + * @since 3.7 + */ + public static final int TOUCHSTATE_DOWN = 1 << 0; + + /** + * A constant indicating that a finger moved on the device. + * + * @see org.eclipse.swt.widgets.Touch.state + * @since 3.7 + */ + public static final int TOUCHSTATE_MOVE = 1 << 1; + + /** + * A constant indicating that a finger was lifted from the device. + * + * @see org.eclipse.swt.widgets.Touch.state + * @since 3.7 + */ + public static final int TOUCHSTATE_UP = 1 << 2; + + /** * A constant indicating that widgets have changed. * (value is 1<<1). * diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/GestureAdapter.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/GestureAdapter.java deleted file mode 100644 index 3f8eecec85..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/GestureAdapter.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.events; - -/** - * This adapter class provides default implementations for the - * methods described by the <code>GestureListener</code> interface. - * <p> - * Classes that wish to deal with <code>GestureEvent</code>s can - * extend this class and override only the methods which they are - * interested in. - * </p> - * - * @see GestureListener - * @see GestureEvent - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - * @since 3.7 - */ -public abstract class GestureAdapter implements GestureListener { - -/** - * Sent when a recognized gesture has occurred. - * - * @param e an event containing information about the gesture. - */ -public void gesture(GestureEvent e) { -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TouchEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TouchEvent.java new file mode 100644 index 0000000000..13965e1573 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TouchEvent.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2010 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.events; + +import org.eclipse.swt.widgets.*; + +/** + * Instances of this class are sent as a result of + * a touch-based input source being touched. + * <p> + * </p> + * + * @see TouchListener + * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> + * @since 3.7 + */ + +public class TouchEvent extends TypedEvent { + + /** + * the set of touches that represent the state of all contacts with touch input device + * at the time the event was generated. + * + * @see org.eclipse.swt.widgets.Touch + */ + public Touch[] touches; + + /** + * the state of the keyboard modifier keys and mouse masks + * at the time the event was generated. + * + * @see org.eclipse.swt.SWT#MODIFIER_MASK + * @see org.eclipse.swt.SWT#BUTTON_MASK + */ + public int stateMask; + + /** + * the widget-relative, x coordinate of the pointer + * at the time the touch occurred + */ + public int x; + + /** + * the widget-relative, y coordinate of the pointer + * at the time the touch occurred + */ + public int y; + + static final long serialVersionUID = -8348741538373572182L; + +/** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ +public TouchEvent(Event e) { + super(e); + this.touches = e.touches; + this.stateMask = e.stateMask; + this.x = e.x; + this.y = e.y; +} + +/** + * Returns a string containing a concise, human-readable + * description of the receiver. + * + * @return a string representation of the event + */ +public String toString() { + String string = super.toString(); + string = string.substring (0, string.length() - 1); // remove trailing '}' + string += " stateMask=" + stateMask + + " x=" + x + + " y=" + y; + if (touches != null) { + for (int i = 0; i < touches.length; i++) { + string += "\n " + touches[i].toString(); + } + string += "\n"; + } + string += "}"; + return string; +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TouchListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TouchListener.java new file mode 100644 index 0000000000..7d1fb2f030 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TouchListener.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2010 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.events; + + +import org.eclipse.swt.internal.*; + +/** + * Classes which implement this interface provide methods + * that deal with the events that are generated as touches + * occur on a touch-aware input surface. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a control using the + * <code>addTouchListener</code> method and removed using + * the <code>removeTouchListener</code> method. When a + * touch occurs or changes state, the <code>touch</code> method + * will be invoked. + * </p> + * + * @see TouchAdapter + * @see TouchEvent + * @since 3.7 + */ +public interface TouchListener extends SWTEventListener { + +/** + * Sent when a touch sequence begins, changes state, or ends. + * + * @param e an event containing information about the touch + */ +public void touch(TouchEvent e); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Event.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Event.java index 34667a8044..2abaf703de 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Event.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Event.java @@ -219,7 +219,7 @@ public class Event { * An array of the touch states for the current touch event. * @since 3.7 */ - //public Touch[] touches; + public Touch[] touches; /** * If nonzero, a positive value indicates a swipe to the right, diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Touch.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Touch.java new file mode 100644 index 0000000000..a70fb80547 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Touch.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2010 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.widgets; + +import org.eclipse.swt.events.*; + + +/** + * Instances of this class are created as a result of + * a touch-based input device being touched. They are found + * in the <code>touches</code> field of an Event or TouchEvent. + * <p> + * </p> + * + * @see TouchEvent + * @see Event + * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> + * @since 3.7 + */ + +public final class Touch { + + /** + * unique identity of the touch. Use this value to track changes to a touch during + * the touch's life. Two touches may have the same identity even though they came + * from different sources. + */ + public long id; + + /** + * object representing the input source that generated the touch + */ + public TouchSource source; + + /** + * the state of this touch at the time it was generated. If this field is 0 + * the finger is still touching the device but has not otherwise moved + * since the last TouchEvent was generated. + * + * @see org.eclipse.swt.SWT#TOUCHSTATE_DOWN + * @see org.eclipse.swt.SWT#TOUCHSTATE_MOVED + * @see org.eclipse.swt.SWT#TOUCHSTATE_UP + */ + public int state; + + /** + * a flag indicating that the touch is the first touch from a previous state + * of no touch points. Once designated as such, the touch remains the + * primary touch until all fingers are removed from the device. + */ + public boolean primary; + + /** + * the X location of the touch in TouchSource coordinates + */ + public int x; + + /** + * the Y location of the touch in TouchSource coordinates + */ + public int y; + +/** + * Constructs a new touch state from the given inputs. + * + * @param identity Identity of the touch. + * @param source Object representing the device that generated the touch. + * @param state One of the state constants representing the state of this touch. + * @param x X location of the touch in screen coordinates + * @param y Y location of the touch in screen coordinates + */ +public Touch(long identity, TouchSource source, int state, boolean primary, int x, int y) { + this.id = identity; + this.source = source; + this.state = state; + this.primary = primary; + this.x = x; + this.y = y; +} + +/** + * Returns a string containing a concise, human-readable + * description of the receiver. + * + * @return a string representation of the event + */ +public String toString() { + return "{id=" + id + + " source=" + source + + " state=" + state + + " primary=" + primary + + " x=" + x + + " y=" + y + + "}"; +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/TouchSource.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/TouchSource.java new file mode 100644 index 0000000000..5b8cf1276f --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/TouchSource.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2010 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.widgets; + +import org.eclipse.swt.graphics.*; + + +/** + * Instances of this class represent a source of touch input. It is used to identify which input source + * generated a <code>Touch</code> object. It also provides information about the input source, which is important + * when deciding how to interpret the information in the <code>Touch</code> object. + * <p> + * Instances of this class can be marked as direct or indirect: + * <ul> + * <li>When an instance is marked as <em>direct</em> the touch source is a touch-sensitive digitizer surface such + * as a tablet or a touch screen. There is a one-to-one mapping between a touch point and a location in a window. + * </li><li> + * When an instance is marked as <em>indirect</em> (or, more precisely, not direct) the touch source is a track pad + * or other device that normally moves the cursor, but can also interpret multiple touches on its surface. In this + * case, there is not a one-to-one map between the location of the touch on the device and a location on the display + * because the user can remove their finger or stylus and touch another part of the device and resume what they were + * doing. + * </li> + * </ul> + * <p> + * IMPORTANT: This class is not intended to be subclassed. + * </p> + * + * @see Touch + * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> + * + * @since 3.7 + */ + +public final class TouchSource { + + boolean direct; + Rectangle bounds; + +/** + * Constructs a new touch source from the given inputs. + * + * @param direct Is the touch source direct or indirect? + * @param height height of the source in pixels. + * @param width width of the source in pixels. + */ +TouchSource(boolean direct, Rectangle bounds) { + this.direct = direct; + this.bounds = bounds; +} + +/** + * Returns the type of touch input this source generates; true for direct, false for indirect. + */ +public boolean isDirect() { + return direct; +} + +/** + * Returns the bounding rectangle of the device. For a direct source, this corresponds to the bounds of the display + * device in pixels. For an indirect source, this contains the size of the device in pixels. + * <p> + * Note that the x and y values may not necessarily be zero if the TouchSource is a direct source. + */ +public Rectangle getBounds() { + return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height); +} + +/** + * Returns a string containing a concise, human-readable + * description of the receiver. + * + * @return a string representation of the event + */ +public String toString() { + return "{direct=" + direct + + " bounds=" + bounds; +} +}
\ No newline at end of file diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/TypedListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/TypedListener.java index f87a010434..2d2fc4f4c8 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/TypedListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/TypedListener.java @@ -144,7 +144,9 @@ public void handleEvent (Event e) { break; } case SWT.Gesture: { - ((GestureListener)eventListener).gesture(new GestureEvent(e)); + GestureEvent event = new GestureEvent(e); + ((GestureListener)eventListener).gesture(event); + e.doit = event.doit; break; } case SWT.Help: { @@ -245,6 +247,10 @@ public void handleEvent (Event e) { ((MenuListener) eventListener).menuShown(new MenuEvent(e)); break; } + case SWT.Touch: { + ((TouchListener)eventListener).touch(new TouchEvent(e)); + break; + } case SWT.Traverse: { /* Fields set by Control */ TraverseEvent event = new TraverseEvent (e); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java index a550d916b1..9793137f15 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java @@ -11,6 +11,7 @@ package org.eclipse.swt.widgets; +import org.eclipse.swt.internal.*; import org.eclipse.swt.internal.gdip.*; import org.eclipse.swt.internal.win32.*; import org.eclipse.swt.graphics.*; @@ -451,6 +452,34 @@ public void addPaintListener (PaintListener listener) { /** * Adds the listener to the collection of listeners who will + * be notified when touch events occur, by sending it + * one of the messages defined in the <code>TouchListener</code> + * interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @since 3.7 + * + * @see TouchListener + * @see #removeTouchListener + */ +public void addTouchListener (TouchListener listener) { + checkWidget(); + if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); + TypedListener typedListener = new TypedListener (listener); + addListener (SWT.Touch,typedListener); +} + +/** + * Adds the listener to the collection of listeners who will * be notified when traversal events occur, by sending it * one of the messages defined in the <code>TraverseListener</code> * interface. @@ -1842,6 +1871,27 @@ boolean isTabItem () { } /** + * Returns <code>true</code> if this control is receiving OS-level touch events, + * otherwise <code>false</code> + * <p> + * Note that this method will return false if the current platform does not support touch-based input. + * If this method does return true, gesture events will not be sent to the control. + * + * @return <code>true</code> if the widget is currently receiving touch events; <code>false</code> otherwise. + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @since 3.7 + */ +public boolean isTouchEnabled() { + checkWidget(); + return OS.IsTouchWindow(handle, null); +} + +/** * Returns <code>true</code> if the receiver is visible and all * ancestors up to and including the receiver's nearest ancestor * shell are visible. Otherwise, <code>false</code> is returned. @@ -2679,6 +2729,32 @@ public void removePaintListener(PaintListener listener) { /** * Removes the listener from the collection of listeners who will + * be notified when touch events occur. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @since 3.7 + * + * @see TouchListener + * @see #addTouchListener +*/ +public void removeTouchListener(TouchListener listener) { + checkWidget(); + if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); + if (eventTable == null) return; + eventTable.unhook (SWT.Touch, listener); +} + +/** + * Removes the listener from the collection of listeners who will * be notified when traversal events occur. * * @param listener the listener which should no longer be notified @@ -2749,6 +2825,84 @@ boolean sendFocusEvent (int type) { return true; } +boolean sendGestureEvent (GESTUREINFO gi) { + /** + * Feature in Windows 7. GID_BEGIN and GID_END events bubble up through the window + * hierarchy for legacy support. Ignore events not targeted for this control. + */ + if (gi.hwndTarget != handle) return true; + Event event = new Event (); + int type = 0; + Point globalPt = new Point(gi.x, gi.y); + Point point = toControl(globalPt); + event.x = point.x; + event.y = point.y; + switch (gi.dwID) { + case OS.GID_ZOOM: + type = SWT.Gesture; + event.detail = SWT.GESTURE_MAGNIFY; + int fingerDistance = OS.LODWORD (gi.ullArguments); + if ((gi.dwFlags & OS.GF_BEGIN) != 0) { + event.detail = SWT.GESTURE_BEGIN; + display.magStartDistance = display.lastDistance = fingerDistance; + } else if ((gi.dwFlags & OS.GF_END) != 0) { + event.detail = SWT.GESTURE_END; + } + + /* + * The gi.ullArguments is the distance between the fingers. + * Scale factor is relative to that original value. + */ + if (fingerDistance == display.lastDistance && event.detail == SWT.GESTURE_MAGNIFY) return true; + if (fingerDistance != 0) event.magnification = fingerDistance / display.magStartDistance; + display.lastDistance = fingerDistance; + break; + case OS.GID_PAN: + type = SWT.Gesture; + event.detail = SWT.GESTURE_PAN; + if ((gi.dwFlags & OS.GF_BEGIN) != 0) { + event.detail = SWT.GESTURE_BEGIN; + display.lastX = point.x; + display.lastY = point.y; + } else if ((gi.dwFlags & OS.GF_END) != 0) { + event.detail = SWT.GESTURE_END; + } + if (display.lastX == point.x && display.lastY == point.y && event.detail == SWT.GESTURE_PAN) return true; + event.xDirection = point.x - display.lastX; + event.yDirection = point.y - display.lastY; + display.lastX = point.x; + display.lastY = point.y; + break; + case OS.GID_ROTATE: + type = SWT.Gesture; + event.detail = SWT.GESTURE_ROTATE; + double rotationInRadians = OS.GID_ROTATE_ANGLE_FROM_ARGUMENT (OS.LODWORD (gi.ullArguments)); + if ((gi.dwFlags & OS.GF_BEGIN) != 0) { + event.detail = SWT.GESTURE_BEGIN; + display.rotationAngle = rotationInRadians; + } else if ((gi.dwFlags & OS.GF_END) != 0) { + event.detail = SWT.GESTURE_END; + } + + /* + * Feature in Win32. Rotation events are sent even when the fingers are at rest. + * If the current rotation is the same as the last one received don't send the event. + */ + if (display.rotationAngle == rotationInRadians && event.detail == SWT.GESTURE_ROTATE) return true; + event.rotation = rotationInRadians * 180.0 / Compatibility.PI; + display.rotationAngle = rotationInRadians; + break; + default: + // Unknown gesture -- ignore. + break; + } + + if (type == 0) return true; + setInputState (event, type); + sendEvent (type, event); + return true;// event.doit; +} + void sendMove () { sendEvent (SWT.Move); } @@ -2757,6 +2911,35 @@ void sendResize () { sendEvent (SWT.Resize); } +boolean sendTouchEvent (int /*long*/ hWnd, TOUCHINPUT touchInput[]) { + Event event = new Event (); + Point cursorLoc = display.getCursorLocation(); + cursorLoc = toControl(cursorLoc); + event.x = cursorLoc.x; + event.y = cursorLoc.y; + + Touch[] touches = new Touch[touchInput.length]; + + for (int i = 0; i < touchInput.length; i++) { + TOUCHINPUT touch = touchInput[i]; + int identity = touch.dwID; + int /*long*/ source = touch.hSource; + TouchSource inputSource = display.findTouchSource(source, getMonitor()); + int state = 0; + boolean primary = false; + if ((touch.dwFlags & OS.TOUCHEVENTF_DOWN) != 0) state = SWT.TOUCHSTATE_DOWN; + if ((touch.dwFlags & OS.TOUCHEVENTF_UP) != 0) state = SWT.TOUCHSTATE_UP; + if ((touch.dwFlags & OS.TOUCHEVENTF_MOVE) != 0) state = SWT.TOUCHSTATE_MOVE; + if ((touch.dwFlags & OS.TOUCHEVENTF_PRIMARY) != 0) primary = true; + touches[i] = new Touch(identity, inputSource, state, primary, (int)OS.TOUCH_COORD_TO_PIXEL(touch.x), (int)OS.TOUCH_COORD_TO_PIXEL(touch.y)); + } + + event.touches = touches; + setInputState (event, SWT.Touch); + postEvent (SWT.Touch, event); + return event.doit; +} + void setBackground () { Control control = findBackgroundControl (); if (control == null) control = this; @@ -3481,6 +3664,27 @@ void setToolTipText (Shell shell, String string) { } /** + * Sets whether the receiver should accept touch events. By default, a Control does not accept touch + * events. No error or exception is thrown if the underlying hardware does not support touch input. + * + * @param enabled the new touch-enabled state + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * + * @since 3.7 + */ +public void setTouchEventsEnabled(boolean enabled) { + checkWidget(); + if (enabled) { + OS.RegisterTouchWindow(handle, 0); + } else { + OS.UnregisterTouchWindow(handle); + } +} + +/** * Marks the receiver as visible if the argument is <code>true</code>, * and marks it invisible otherwise. * <p> @@ -4383,6 +4587,7 @@ int /*long*/ windowProc (int /*long*/ hwnd, int msg, int /*long*/ wParam, int /* case OS.WM_SYSKEYUP: result = WM_SYSKEYUP (wParam, lParam); break; case OS.WM_TABLET_FLICK: result = WM_TABLET_FLICK (wParam, lParam); break; case OS.WM_TIMER: result = WM_TIMER (wParam, lParam); break; + case OS.WM_TOUCH: result = WM_TOUCH (wParam, lParam); break; case OS.WM_UNDO: result = WM_UNDO (wParam, lParam); break; case OS.WM_UPDATEUISTATE: result = WM_UPDATEUISTATE (wParam, lParam); break; case OS.WM_VSCROLL: result = WM_VSCROLL (wParam, lParam); break; @@ -4503,9 +4708,10 @@ LRESULT WM_GESTURE (int /*long*/ wParam, int /*long*/ lParam) { GESTUREINFO gi = new GESTUREINFO (); gi.cbSize = GESTUREINFO.sizeof; if (OS.GetGestureInfo (lParam, gi)) { - boolean result = sendGestureEvent (gi); - OS.CloseGestureInfoHandle (lParam); - if (result) return LRESULT.ZERO; + if (!sendGestureEvent (gi)) { + OS.CloseGestureInfoHandle (lParam); + return LRESULT.ZERO; + } } } return null; @@ -5159,6 +5365,30 @@ LRESULT WM_TABLET_FLICK (int /*long*/ wParam, int /*long*/ lParam) { return event.doit ? null : LRESULT.ONE; } +LRESULT WM_TOUCH (int /*long*/ wParam, int /*long*/ lParam) { + LRESULT result = null; + + if (hooks(SWT.Touch) || filters(SWT.Touch)) { + int cInputs = OS.LOWORD(wParam); + int /*long*/ hHeap = OS.GetProcessHeap (); + int /*long*/ pInputs = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, cInputs * TOUCHINPUT.sizeof); + + if (pInputs != 0){ + if (OS.GetTouchInputInfo(lParam, cInputs, pInputs, OS.TOUCHINPUT_sizeof())) { + TOUCHINPUT ti[] = new TOUCHINPUT[cInputs]; + for (int i = 0; i < cInputs; i++){ + ti[i] = new TOUCHINPUT(); + OS.MoveMemory(ti[i], pInputs + i * OS.TOUCHINPUT_sizeof(), OS.TOUCHINPUT_sizeof()); + } + if (!sendTouchEvent(handle, ti)) + OS.HeapFree(hHeap, 0, pInputs); + result = LRESULT.ZERO; + } + } + } + return result; +} + LRESULT WM_TIMER (int /*long*/ wParam, int /*long*/ lParam) { return null; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java index 263e5907e9..4a77580334 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.swt.widgets; - +import java.util.*; import org.eclipse.swt.internal.*; import org.eclipse.swt.internal.win32.*; import org.eclipse.swt.*; @@ -251,6 +251,9 @@ public class Display extends Device { double rotationAngle; int lastX, lastY; + /* Touch state */ + Hashtable touchSourceMap; + /* Tool Tips */ int nextToolTipId; @@ -1427,6 +1430,21 @@ public static Display findDisplay (Thread thread) { } } +TouchSource findTouchSource(int /*long*/ touchDevice, Monitor sourceMonitor) { + if (touchSourceMap == null) { + touchSourceMap = new Hashtable(); + } + LONG touchDeviceObj = new LONG(touchDevice); + TouchSource returnVal = (TouchSource) touchSourceMap.get(touchDeviceObj); + + if (returnVal == null) { + returnVal = new TouchSource(true, sourceMonitor.getBounds()); + touchSourceMap.put(touchDeviceObj, returnVal); + } + + return returnVal; +} + /** * Returns the currently active <code>Shell</code>, or null * if no shell belonging to the currently running application @@ -2788,6 +2806,20 @@ public void internal_dispose_GC (int /*long*/ hDC, GCData data) { OS.ReleaseDC (0, hDC); } +/** + * Returns true if a touch-aware input device is attached to the system, + * enabled, and ready for use. + * + * @since 3.7 + */ +public boolean isTouchEnabled() { + int value = OS.GetSystemMetrics(OS.SM_DIGITIZER); + if ((value & (OS.NID_READY | OS.NID_MULTI_INPUT)) != 0) { + return true; + } + return false; +} + boolean isXMouseActive () { /* * NOTE: X-Mouse is active when bit 1 of the UserPreferencesMask is set. diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java index 1ad7fea292..5828334bab 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java @@ -1080,80 +1080,6 @@ void sendEvent (int eventType, Event event, boolean send) { } } -boolean sendGestureEvent (GESTUREINFO gi) { - Event event = new Event (); - int type = 0; - POINT point = new POINT (); - point.x = gi.x; - point.y = gi.y; - OS.MapWindowPoints (0, gi.hwndTarget, point, 1); - event.x = point.x; - event.y = point.y; - switch (gi.dwID) { - case OS.GID_ZOOM: - type = SWT.Gesture; - event.detail = SWT.GESTURE_MAGNIFY; - int fingerDistance = OS.LODWORD (gi.ullArguments); - if ((gi.dwFlags & OS.GF_BEGIN) != 0) { - event.detail = SWT.GESTURE_BEGIN; - display.magStartDistance = display.lastDistance = fingerDistance; - } else if ((gi.dwFlags & OS.GF_END) != 0) { - event.detail = SWT.GESTURE_END; - } - - /* - * The gi.ullArguments is the distance between the fingers. - * Scale factor is relative to that original value. - */ - if (fingerDistance == display.lastDistance && event.detail == SWT.GESTURE_MAGNIFY) return false; - if (fingerDistance != 0) event.magnification = fingerDistance / display.magStartDistance; - display.lastDistance = fingerDistance; - break; - case OS.GID_PAN: - type = SWT.Gesture; - event.detail = SWT.GESTURE_PAN; - if ((gi.dwFlags & OS.GF_BEGIN) != 0) { - event.detail = SWT.GESTURE_BEGIN; - display.lastX = point.x; - display.lastY = point.y; - } else if ((gi.dwFlags & OS.GF_END) != 0) { - event.detail = SWT.GESTURE_END; - } - if (display.lastX == point.x && display.lastY == point.y && event.detail == SWT.GESTURE_PAN) return false; - event.xDirection = point.x - display.lastX; - event.yDirection = point.y - display.lastY; - display.lastX = point.x; - display.lastY = point.y; - break; - case OS.GID_ROTATE: - type = SWT.Gesture; - event.detail = SWT.GESTURE_ROTATE; - double rotationInRadians = OS.GID_ROTATE_ANGLE_FROM_ARGUMENT (OS.LODWORD (gi.ullArguments)); - if ((gi.dwFlags & OS.GF_BEGIN) != 0) { - event.detail = SWT.GESTURE_BEGIN; - display.rotationAngle = rotationInRadians; - } else if ((gi.dwFlags & OS.GF_END) != 0) { - event.detail = SWT.GESTURE_END; - } - - /* - * Feature in Win32. Rotation events are sent even when the fingers are at rest. - * If the current rotation is the same as the last one received don't send the event. - */ - if (display.rotationAngle == rotationInRadians && event.detail == SWT.GESTURE_ROTATE) return false; - event.rotation = rotationInRadians * 180.0 / Compatibility.PI; - display.rotationAngle = rotationInRadians; - break; - default: - // Unknown gesture -- ignore. - break; - } - - if (type == 0) return false; - setInputState (event, type); - sendEvent (type, event); - return event.doit; -} void sendSelectionEvent (int type) { sendSelectionEvent (type, null, false); |