/******************************************************************************* * Copyright (c) 2016 comtel inc. * * Licensed under the Apache License, version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. *******************************************************************************/ package org.jfxvnc.ui; import org.jfxvnc.net.rfb.codec.encoder.InputEventListener; import org.jfxvnc.net.rfb.codec.encoder.KeyButtonMap; import org.jfxvnc.net.rfb.codec.encoder.PointerEvent; import javafx.beans.property.BooleanProperty; import javafx.beans.property.DoubleProperty; import javafx.beans.property.ReadOnlyIntegerProperty; import javafx.beans.property.ReadOnlyIntegerWrapper; import javafx.beans.property.SimpleBooleanProperty; import javafx.event.EventHandler; import javafx.scene.Node; import javafx.scene.input.MouseEvent; import javafx.scene.input.ScrollEvent; public class PointerEventHandler implements KeyButtonMap { private double zoomLevel = 1.0; private InputEventListener listener; private final BooleanProperty enabled = new SimpleBooleanProperty(false); private final EventHandler<MouseEvent> mouseEventHandler; private final EventHandler<ScrollEvent> scrollEventHandler; private final ReadOnlyIntegerWrapper xPosProperty = new ReadOnlyIntegerWrapper(0); private final ReadOnlyIntegerWrapper yPosProperty = new ReadOnlyIntegerWrapper(0); public PointerEventHandler() { mouseEventHandler = (e) -> { if (enabled.get()) { sendMouseEvents(e); e.consume(); } }; scrollEventHandler = (e) -> { if (enabled.get()) { sendScrollEvents(e); e.consume(); } }; } public void setInputEventListener(InputEventListener listener) { this.listener = listener; } public BooleanProperty enabledProperty() { return enabled; } public void registerZoomLevel(DoubleProperty zoom) { zoom.addListener(l -> zoomLevel = zoom.get()); } public void register(Node node) { node.addEventFilter(ScrollEvent.SCROLL, scrollEventHandler); node.addEventFilter(MouseEvent.MOUSE_PRESSED, mouseEventHandler); node.addEventFilter(MouseEvent.MOUSE_MOVED, mouseEventHandler); node.addEventFilter(MouseEvent.MOUSE_DRAGGED, mouseEventHandler); node.addEventFilter(MouseEvent.MOUSE_RELEASED, mouseEventHandler); } public void unregister(Node node) { node.removeEventFilter(ScrollEvent.SCROLL, scrollEventHandler); node.removeEventFilter(MouseEvent.MOUSE_PRESSED, mouseEventHandler); node.removeEventFilter(MouseEvent.MOUSE_MOVED, mouseEventHandler); node.removeEventFilter(MouseEvent.MOUSE_DRAGGED, mouseEventHandler); node.removeEventFilter(MouseEvent.MOUSE_RELEASED, mouseEventHandler); } private void sendMouseEvents(MouseEvent event) { xPosProperty.set((int) Math.floor(event.getX() / zoomLevel)); yPosProperty.set((int) Math.floor(event.getY() / zoomLevel)); byte buttonMask = 0; if (event.getEventType() == MouseEvent.MOUSE_PRESSED || event.getEventType() == MouseEvent.MOUSE_DRAGGED) { if (event.isMiddleButtonDown()) { buttonMask = 2; } else if (event.isSecondaryButtonDown()) { buttonMask = 4; } else { buttonMask = 1; } fire(new PointerEvent(buttonMask, xPosProperty.get(), yPosProperty.get())); } else if (event.getEventType() == MouseEvent.MOUSE_RELEASED || event.getEventType() == MouseEvent.MOUSE_MOVED) { buttonMask = 0; } fire(new PointerEvent(buttonMask, xPosProperty.get(), yPosProperty.get())); } private void sendScrollEvents(ScrollEvent event) { fire( new PointerEvent(event.getDeltaY() > 0 ? (byte) 8 : (byte) 16, (int) Math.floor(event.getX() / zoomLevel), (int) Math.floor(event.getY() / zoomLevel))); } private synchronized void fire(PointerEvent msg) { if (listener != null) { listener.sendInputEvent(msg); } } public ReadOnlyIntegerProperty xPosProperty() { return xPosProperty.getReadOnlyProperty(); } public ReadOnlyIntegerProperty yPosProperty() { return yPosProperty.getReadOnlyProperty(); } }