All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.piccolo2d.PInputManager Maven / Gradle / Ivy

There is a newer version: 3.0.1
Show newest version
/*
 * Copyright (c) 2008-2011, Piccolo2D project, http://piccolo2d.org
 * Copyright (c) 1998-2008, University of Maryland
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list of conditions
 * and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
 * and the following disclaimer in the documentation and/or other materials provided with the
 * distribution.
 *
 * None of the name of the University of Maryland, the name of the Piccolo2D project, or the names of its
 * contributors may be used to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.piccolo2d;

import java.awt.event.FocusEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.geom.Point2D;

import org.piccolo2d.event.PBasicInputEventHandler;
import org.piccolo2d.event.PInputEvent;
import org.piccolo2d.event.PInputEventListener;
import org.piccolo2d.util.PPickPath;


/**
 * PInputManager is responsible for dispatching PInputEvents to node's
 * event listeners. Events are dispatched from PRoot's processInputs method.
 * 

* * @see org.piccolo2d.event.PInputEvent * @see PRoot * @version 1.0 * @author Jesse Grosjean */ public class PInputManager extends PBasicInputEventHandler implements PRoot.InputSource { /** Records the last known mouse position on the canvas. */ private final Point2D lastCanvasPosition; /** Records the current known mouse position on the canvas. */ private final Point2D currentCanvasPosition; /** The next InputEvent that needs to be processed. */ private InputEvent nextInput; /** The type of the next InputEvent that needs to be processed. */ private int nextType; /** The Input Source the next event to process came from. */ private PCamera nextInputSource; /** The current mouse focus. */ private PPickPath mouseFocus; /** The previous mouse focus. */ private PPickPath previousMouseFocus; /** Tracks where the mouse is right now on the canvas. */ private PPickPath mouseOver; /** Tracks the previous location of the mouse on the canvas. */ private PPickPath previousMouseOver; /** Tracks the input event listener that should receive keyboard events. */ private PInputEventListener keyboardFocus; /** Tracks the number mouse buttons currently pressed. */ private int buttonsPressed; /** * Creates a PInputManager and sets positions (last, current) to the origin * (0,0). */ public PInputManager() { lastCanvasPosition = new Point2D.Double(); currentCanvasPosition = new Point2D.Double(); } /** * Return the node that currently has the keyboard focus. This node receives * the key events. * * @return the current keyboard focus */ public PInputEventListener getKeyboardFocus() { return keyboardFocus; } /** * Set the node that should receive key events. * * @param eventHandler sets the keyboard event focus, may be null */ public void setKeyboardFocus(final PInputEventListener eventHandler) { final PInputEvent focusEvent = new PInputEvent(this, null); if (keyboardFocus != null) { dispatchEventToListener(focusEvent, FocusEvent.FOCUS_LOST, keyboardFocus); } keyboardFocus = eventHandler; if (keyboardFocus != null) { dispatchEventToListener(focusEvent, FocusEvent.FOCUS_GAINED, keyboardFocus); } } /** * Return the current Pick Path under the mouse focus. This will return the * path that received the current mouse pressed event, or null if the mouse * is not pressed. The mouse focus gets mouse dragged events even what the * mouse is not over the mouse focus. * * @return the current Pick Path under the mouse focus */ public PPickPath getMouseFocus() { return mouseFocus; } /** * Sets the current Pick Path under the mouse focus. The mouse focus gets * mouse dragged events even when the mouse is not over the mouse focus. * * @param path the new mouse focus */ public void setMouseFocus(final PPickPath path) { previousMouseFocus = mouseFocus; mouseFocus = path; } /** * Return the node the the mouse is currently over. * * @return the path over which the mouse currently is */ public PPickPath getMouseOver() { return mouseOver; } /** * Records the path which is directly below the mouse. * * @param path path over which the mouse has been moved */ public void setMouseOver(final PPickPath path) { mouseOver = path; } /** * Returns the position on the Canvas of the last event. * * @return position of last canvas event */ public Point2D getLastCanvasPosition() { return lastCanvasPosition; } /** * Returns the position of the current canvas event. * * @return position of current canvas event */ public Point2D getCurrentCanvasPosition() { return currentCanvasPosition; } // **************************************************************** // Event Handling - Methods for handling events // // The dispatch manager updates the focus nodes based on the // incoming events, and dispatches those events to the appropriate // focus nodes. // **************************************************************** /** {@inheritDoc} */ public void keyPressed(final PInputEvent event) { dispatchEventToListener(event, KeyEvent.KEY_PRESSED, keyboardFocus); } /** {@inheritDoc} */ public void keyReleased(final PInputEvent event) { dispatchEventToListener(event, KeyEvent.KEY_RELEASED, keyboardFocus); } /** {@inheritDoc} */ public void keyTyped(final PInputEvent event) { dispatchEventToListener(event, KeyEvent.KEY_TYPED, keyboardFocus); } /** {@inheritDoc} */ public void mouseClicked(final PInputEvent event) { dispatchEventToListener(event, MouseEvent.MOUSE_CLICKED, previousMouseFocus); } /** {@inheritDoc} */ public void mouseWheelRotated(final PInputEvent event) { setMouseFocus(getMouseOver()); dispatchEventToListener(event, MouseWheelEvent.WHEEL_UNIT_SCROLL, mouseOver); } /** {@inheritDoc} */ public void mouseWheelRotatedByBlock(final PInputEvent event) { setMouseFocus(getMouseOver()); dispatchEventToListener(event, MouseWheelEvent.WHEEL_BLOCK_SCROLL, mouseOver); } /** {@inheritDoc} */ public void mouseDragged(final PInputEvent event) { checkForMouseEnteredAndExited(event); dispatchEventToListener(event, MouseEvent.MOUSE_DRAGGED, mouseFocus); } /** {@inheritDoc} */ public void mouseEntered(final PInputEvent event) { dispatchEventToListener(event, MouseEvent.MOUSE_ENTERED, mouseOver); } /** {@inheritDoc} */ public void mouseExited(final PInputEvent event) { dispatchEventToListener(event, MouseEvent.MOUSE_EXITED, previousMouseOver); } /** {@inheritDoc} */ public void mouseMoved(final PInputEvent event) { checkForMouseEnteredAndExited(event); dispatchEventToListener(event, MouseEvent.MOUSE_MOVED, mouseOver); } /** {@inheritDoc} */ public void mousePressed(final PInputEvent event) { if (buttonsPressed == 0) { setMouseFocus(getMouseOver()); } buttonsPressed++; dispatchEventToListener(event, MouseEvent.MOUSE_PRESSED, mouseFocus); if (buttonsPressed < 1 || buttonsPressed > 3) { System.err.println("invalid pressedCount on mouse pressed: " + buttonsPressed); } } /** {@inheritDoc} */ public void mouseReleased(final PInputEvent event) { buttonsPressed--; checkForMouseEnteredAndExited(event); dispatchEventToListener(event, MouseEvent.MOUSE_RELEASED, mouseFocus); if (buttonsPressed == 0) { setMouseFocus(null); } if (buttonsPressed < 0 || buttonsPressed > 2) { System.err.println("invalid pressedCount on mouse released: " + buttonsPressed); } } /** * Fires events whenever the mouse moves from PNode to PNode. * * @param event to check to see if the top node has changed. */ protected void checkForMouseEnteredAndExited(final PInputEvent event) { final PNode currentNode = getPickedNode(mouseOver); final PNode previousNode = getPickedNode(previousMouseOver); if (currentNode != previousNode) { dispatchEventToListener(event, MouseEvent.MOUSE_EXITED, previousMouseOver); dispatchEventToListener(event, MouseEvent.MOUSE_ENTERED, mouseOver); previousMouseOver = mouseOver; } } /** * Returns picked node on pickPath if pickPath is not null, or null. * * @param pickPath from which to extract picked node * * @return the picked node or null if pickPath is null */ private PNode getPickedNode(final PPickPath pickPath) { if (pickPath == null) { return null; } else { return pickPath.getPickedNode(); } } // **************************************************************** // Event Dispatch. // **************************************************************** /** {@inheritDoc} */ public void processInput() { if (nextInput == null) { return; } final PInputEvent e = new PInputEvent(this, nextInput); Point2D newCurrentCanvasPosition = null; Point2D newLastCanvasPosition = null; if (e.isMouseEvent()) { if (e.isMouseEnteredOrMouseExited()) { final PPickPath aPickPath = nextInputSource.pick(((MouseEvent) nextInput).getX(), ((MouseEvent) nextInput).getY(), 1); setMouseOver(aPickPath); previousMouseOver = aPickPath; newCurrentCanvasPosition = (Point2D) currentCanvasPosition.clone(); newLastCanvasPosition = (Point2D) lastCanvasPosition.clone(); } else { lastCanvasPosition.setLocation(currentCanvasPosition); currentCanvasPosition.setLocation(((MouseEvent) nextInput).getX(), ((MouseEvent) nextInput).getY()); final PPickPath aPickPath = nextInputSource.pick(currentCanvasPosition.getX(), currentCanvasPosition .getY(), 1); setMouseOver(aPickPath); } } nextInput = null; nextInputSource = null; processEvent(e, nextType); if (newCurrentCanvasPosition != null && newLastCanvasPosition != null) { currentCanvasPosition.setLocation(newCurrentCanvasPosition); lastCanvasPosition.setLocation(newLastCanvasPosition); } } /** * Flags the given event as needing to be processed. * * @param event the event to be processed * @param type type of event to be processed * @param camera camera from which the event was dispatched */ public void processEventFromCamera(final InputEvent event, final int type, final PCamera camera) { // queue input nextInput = event; nextType = type; nextInputSource = camera; // tell root to process queued inputs camera.getRoot().processInputs(); } /** * Dispatches the given event to the listener, or does nothing if listener * is null. * * @param event event to be dispatched * @param type type of event to dispatch * @param listener target of dispatch */ private void dispatchEventToListener(final PInputEvent event, final int type, final PInputEventListener listener) { if (listener != null) { // clear the handled bit since the same event object is used to send // multiple events such as mouseEntered/mouseExited and mouseMove. event.setHandled(false); listener.processEvent(event, type); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy