/*
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.javafx.webkit.drt;
import com.sun.webkit.WebPage;
import com.sun.javafx.webkit.KeyCodeMap;
import com.sun.webkit.event.WCKeyEvent;
import com.sun.webkit.event.WCMouseEvent;
import com.sun.webkit.event.WCMouseWheelEvent;
import java.util.HashMap;
import java.util.Map;
import javafx.scene.input.KeyCode;
Event sender for DRT tests.
/**
* Event sender for DRT tests.
*/
final class EventSender {
private static final int ALT = 1;
private static final int CTRL = 2;
private static final int META = 4;
private static final int SHIFT = 8;
private static final int PRESSED = 16;
private static final int CAPS_LOCK = 32;
private static final float ZOOM = 1.2f;
private static final float SCROLL = 40f;
private static final Map<Object, KeyCode> MAP = new HashMap<Object, KeyCode>();
static {
MAP.put("\r", KeyCode.ENTER);
MAP.put("pageUp", KeyCode.PAGE_UP);
MAP.put("pageDown", KeyCode.PAGE_DOWN);
MAP.put("leftArrow", KeyCode.LEFT);
MAP.put("upArrow", KeyCode.UP);
MAP.put("rightArrow", KeyCode.RIGHT);
MAP.put("downArrow", KeyCode.DOWN);
MAP.put("printScreen", KeyCode.PRINTSCREEN);
MAP.put("menu", KeyCode.CONTEXT_MENU);
for (KeyCode code : KeyCode.values()) {
MAP.put(code.getCode(), code);
MAP.put(code.getName().toLowerCase(), code);
MAP.put(code.getName(), code);
}
}
The web page to send events to.
/**
* The web page to send events to.
*/
private final WebPage webPage;
The current state of the drag mode.
/**
* The current state of the drag mode.
*/
private boolean dragMode = true;
The current X position of the mouse.
/**
* The current X position of the mouse.
*/
private int mousePositionX;
The current Y position of the mouse.
/**
* The current Y position of the mouse.
*/
private int mousePositionY;
The current state of mouse buttons.
/**
* The current state of mouse buttons.
*/
private boolean mousePressed;
The type of mouse button.
/**
* The type of mouse button.
*/
private int mouseButton = WCMouseEvent.NOBUTTON;
The time offset for events.
/**
* The time offset for events.
*/
private long timeOffset;
The current modifiers for touch events.
/**
* The current modifiers for touch events.
*/
private int modifiers;
Following states are used to send double click
/**
* Following states are used to send double click
*/
private long lastClickTime;
private int lastMouseClickPositionX, lastMouseClickPositionY;
private int clickCount = 1;
Creates a new EventSender
. /**
* Creates a new {@code EventSender}.
*/
EventSender(WebPage webPage) {
this.webPage = webPage;
}
Implements the keyDown
method of the DRT event sender object. /**
* Implements the {@code keyDown}
* method of the DRT event sender object.
*/
private void keyDown(String key, int modifiers) {
String keyChar = null;
KeyCode code = MAP.get(key);
if (1 == key.length()) {
if (code == null) {
code = MAP.get(Integer.valueOf(Character.toUpperCase(
key.charAt(0))));
}
keyChar = key;
}
if (code == null) {
System.err.println("unexpected key = " + key);
}
else {
KeyCodeMap.Entry keyCodeEntry = KeyCodeMap.lookup(code);
String keyIdentifier = keyCodeEntry.getKeyIdentifier();
int windowsVirtualKeyCode = keyCodeEntry.getWindowsVirtualKeyCode();
dispatchKeyEvent(WCKeyEvent.KEY_PRESSED, null, keyIdentifier,
windowsVirtualKeyCode, modifiers);
dispatchKeyEvent(WCKeyEvent.KEY_TYPED, keyChar, null,
0, modifiers);
dispatchKeyEvent(WCKeyEvent.KEY_RELEASED, null, keyIdentifier,
windowsVirtualKeyCode, modifiers);
}
}
private void updateClickCountForButton(int buttonNumber) {
if ((getEventTime() - lastClickTime >= 1000) ||
!(mousePositionX == lastMouseClickPositionX && mousePositionY == lastMouseClickPositionY) ||
mouseButton != buttonNumber) {
clickCount = 1;
} else {
clickCount++;
}
}
Implements the mouseUp
and mouseDown
methods of the DRT event sender object. /**
* Implements the {@code mouseUp} and {@code mouseDown}
* methods of the DRT event sender object.
*/
private void mouseUpDown(int button, int modifiers) {
mousePressed = isSet(modifiers, PRESSED);
if (mousePressed) {
updateClickCountForButton(button);
}
mouseButton = button;
dispatchMouseEvent(mousePressed
? WCMouseEvent.MOUSE_PRESSED
: WCMouseEvent.MOUSE_RELEASED, button, clickCount, modifiers);
if (mousePressed) {
lastClickTime = getEventTime();
lastMouseClickPositionX = mousePositionX;
lastMouseClickPositionY = mousePositionY;
}
}
Implements the mouseMoveTo
method of the DRT event sender object. /**
* Implements the {@code mouseMoveTo}
* method of the DRT event sender object.
*/
private void mouseMoveTo(int x, int y) {
mousePositionX = x;
mousePositionY = y;
dispatchMouseEvent(mousePressed
? WCMouseEvent.MOUSE_DRAGGED
: WCMouseEvent.MOUSE_MOVED,
(mousePressed ? mouseButton : WCMouseEvent.NOBUTTON), 0, 0);
}
Implements the mouseScrollBy
and continuousMouseScrollBy
methods of the DRT event sender object. /**
* Implements the {@code mouseScrollBy} and {@code continuousMouseScrollBy}
* methods of the DRT event sender object.
*/
private void mouseScroll(float x, float y, boolean continuous) {
if (continuous) {
x /= SCROLL;
y /= SCROLL;
}
webPage.dispatchMouseWheelEvent(new WCMouseWheelEvent(
mousePositionX, mousePositionY,
mousePositionX, mousePositionY,
getEventTime(),
false,
false,
false,
false,
x, y
));
}
Implements the leapForward
method of the DRT event sender object. /**
* Implements the {@code leapForward}
* method of the DRT event sender object.
*/
private void leapForward(int timeOffset) {
this.timeOffset += timeOffset;
}
Implements the contextClick
method of the DRT event sender object. /**
* Implements the {@code contextClick}
* method of the DRT event sender object.
*/
private void contextClick() {
dispatchMouseEvent(WCMouseEvent.MOUSE_PRESSED, WCMouseEvent.BUTTON2, 1, 0);
dispatchMouseEvent(WCMouseEvent.MOUSE_RELEASED, WCMouseEvent.BUTTON2, 1, 0);
}
Implements the scheduleAsynchronousClick
method of the DRT event sender object. /**
* Implements the {@code scheduleAsynchronousClick}
* method of the DRT event sender object.
*/
private void scheduleAsynchronousClick() {
dispatchMouseEvent(WCMouseEvent.MOUSE_PRESSED, WCMouseEvent.BUTTON1, 1, 0);
dispatchMouseEvent(WCMouseEvent.MOUSE_RELEASED, WCMouseEvent.BUTTON1, 1, 0);
}
Implements the touchStart
method of the DRT event sender object. /**
* Implements the {@code touchStart}
* method of the DRT event sender object.
*/
private void touchStart() {
throw new UnsupportedOperationException("touchStart");
}
Implements the touchCancel
method of the DRT event sender object. /**
* Implements the {@code touchCancel}
* method of the DRT event sender object.
*/
private void touchCancel() {
throw new UnsupportedOperationException("touchCancel");
}
Implements the touchMove
method of the DRT event sender object. /**
* Implements the {@code touchMove}
* method of the DRT event sender object.
*/
private void touchMove() {
throw new UnsupportedOperationException("touchMove");
}
Implements the touchEnd
method of the DRT event sender object. /**
* Implements the {@code touchEnd}
* method of the DRT event sender object.
*/
private void touchEnd() {
throw new UnsupportedOperationException("touchEnd");
}
Implements the addTouchPoint
method of the DRT event sender object. /**
* Implements the {@code addTouchPoint}
* method of the DRT event sender object.
*/
private void addTouchPoint(int x, int y) {
throw new UnsupportedOperationException("addTouchPoint");
}
Implements the updateTouchPoint
method of the DRT event sender object. /**
* Implements the {@code updateTouchPoint}
* method of the DRT event sender object.
*/
private void updateTouchPoint(int i, int x, int y) {
throw new UnsupportedOperationException("updateTouchPoint");
}
Implements the cancelTouchPoint
method of the DRT event sender object. /**
* Implements the {@code cancelTouchPoint}
* method of the DRT event sender object.
*/
private void cancelTouchPoint(int i) {
throw new UnsupportedOperationException("cancelTouchPoint");
}
Implements the releaseTouchPoint
method of the DRT event sender object. /**
* Implements the {@code releaseTouchPoint}
* method of the DRT event sender object.
*/
private void releaseTouchPoint(int i) {
throw new UnsupportedOperationException("releaseTouchPoint");
}
Implements the clearTouchPoints
method of the DRT event sender object. /**
* Implements the {@code clearTouchPoints}
* method of the DRT event sender object.
*/
private void clearTouchPoints() {
throw new UnsupportedOperationException("clearTouchPoints");
}
Implements the setTouchModifier
method of the DRT event sender object. /**
* Implements the {@code setTouchModifier}
* method of the DRT event sender object.
*/
private void setTouchModifier(int modifier, boolean set) {
modifiers = set ? (modifiers | modifier) : (modifiers & ~modifier);
}
Implements the scalePageBy
method of the DRT event sender object. /**
* Implements the {@code scalePageBy}
* method of the DRT event sender object.
*/
private void scalePageBy(float scale, int x, int y) {
throw new UnsupportedOperationException("scalePageBy(" + scale + "); x=" + x + "; y=" + y);
}
Implements the textZoomIn
, textZoomOut
zoomPageInt
, and zoomPageOut
methods of the DRT event sender object. /**
* Implements the {@code textZoomIn}, {@code textZoomOut}
* {@code zoomPageInt}, and {@code zoomPageOut}
* methods of the DRT event sender object.
*/
private void zoom(boolean in, boolean textOnly) {
float factor = webPage.getZoomFactor(textOnly);
webPage.setZoomFactor(in ? (factor * ZOOM) : (factor / ZOOM), textOnly);
}
Implements the beginDragWithFiles
method of the DRT event sender object. /**
* Implements the {@code beginDragWithFiles}
* method of the DRT event sender object.
*/
private void beginDragWithFiles(String[] names) {
StringBuilder sb = new StringBuilder("beginDragWithFiles");
for (String name : names) {
sb.append(", ").append(name);
}
throw new UnsupportedOperationException(sb.append('.').toString());
}
Returns the dragMode
variable of the DRT event sender object. /**
* Returns the {@code dragMode}
* variable of the DRT event sender object.
*/
private boolean getDragMode() {
return dragMode;
}
Sets the dragMode
variable of the DRT event sender object. /**
* Sets the {@code dragMode}
* variable of the DRT event sender object.
*/
private void setDragMode(boolean mode) {
dragMode = mode;
}
private long getEventTime() {
return timeOffset + System.currentTimeMillis();
}
private void dispatchKeyEvent(int type, String text, String keyIdentifier,
int windowsVirtualKeyCode, int modifiers)
{
webPage.dispatchKeyEvent(new WCKeyEvent(
type, text, keyIdentifier, windowsVirtualKeyCode,
isSet(modifiers, SHIFT),
isSet(modifiers, CTRL),
isSet(modifiers, ALT),
isSet(modifiers, META),
getEventTime()
));
}
private void dispatchMouseEvent(int type, int button, int clicks, int modifiers) {
webPage.dispatchMouseEvent(new WCMouseEvent(
type, button, clicks,
mousePositionX, mousePositionY,
mousePositionX, mousePositionY,
getEventTime(),
isSet(modifiers, SHIFT),
isSet(modifiers, CTRL),
isSet(modifiers, ALT),
isSet(modifiers, META),
false
));
}
private static boolean isSet(int modifiers, int modifier) {
return modifier == (modifier & modifiers);
}
}