/*
- * Sixth 3D engine. Copyright ©2012-2018, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 3 of the GNU Lesser General Public License
- * or later as published by the Free Software Foundation.
- *
+ * Sixth 3D engine. Author: Svjatoslav Agejenko.
+ * This project is released under Creative Commons Zero (CC0) license.
*/
-
package eu.svjatoslav.sixth.e3d.gui.humaninput;
import eu.svjatoslav.sixth.e3d.geometry.Point2D;
import java.util.List;
import java.util.Map;
+/**
+ * This class is responsible for tracking human input devices (keyboard, mouse, etc.) and
+ * forwarding those inputs to subsequent virtual components.
+ */
public class HIDInputTracker implements
MouseMotionListener, KeyListener, MouseListener, MouseWheelListener, ViewRenderListener {
/**
- * <pre>
- * Key is keyboard key code.
- * Value is system milliseconds when key was pressed.
- *
- * So by reading the map one can determine currently pressed keys as well as duration.
- * </pre>
+ * <p> Map of pressed keys. </p>
+ * <p> Key is mouse button code. </p>
+ * <p> Value is system milliseconds when button was pressed. </p>
+ * <p> So by reading the map one can determine currently pressed buttons as well as duration. </p>
*/
private final Map<Integer, Long> pressedKeysToPressedTimeMap = new HashMap<>();
- private final List<MouseClick> detectedMouseClicks = new ArrayList<>();
+ private final List<MouseEvent> detectedMouseEvents = new ArrayList<>();
private final List<KeyEvent> detectedKeyEvents = new ArrayList<>();
+ private final Point2D mouseDraggedDirection = new Point2D();
+ private final ViewPanel viewPanel;
private int wheelMovedDirection = 0;
- private Point2D mouseDraggedDirection = new Point2D();
private Point2D oldMouseCoordinatesWhenDragging;
- private ViewPanel viewPanel;
private Point2D currentMouseLocation;
private boolean mouseMoved;
private boolean mouseWithinWindow = false;
* @return <code>true</code> if view needs to be repainted.
*/
private boolean handleKeyboardEvents() {
- final UserInputHandler currentFocusOwner = viewPanel.getKeyboardFocusStack().getCurrentFocusOwner();
+ final KeyboardInputHandler currentFocusOwner = viewPanel.getKeyboardFocusStack().getCurrentFocusOwner();
ArrayList<KeyEvent> unprocessedKeyboardEvents = getUnprocessedKeyboardEvents();
return currentFocusOwner != null
* @return <code>true</code> if view update is needed.
*/
private boolean forwardKeyboardEventsToFocusOwner(
- UserInputHandler currentFocusOwner, ArrayList<KeyEvent> keyEvents) {
+ KeyboardInputHandler currentFocusOwner, ArrayList<KeyEvent> keyEvents) {
boolean viewUpdateNeeded = false;
for (KeyEvent keyEvent : keyEvents)
return viewUpdateNeeded;
}
- private boolean processKeyEvent(UserInputHandler currentFocusOwner, KeyEvent keyEvent) {
+ private boolean processKeyEvent(KeyboardInputHandler currentFocusOwner, KeyEvent keyEvent) {
switch (keyEvent.getID()) {
case KeyEvent.KEY_PRESSED:
return currentFocusOwner.keyPressed(keyEvent, viewPanel);
* @return <code>true</code> if view needs to be repainted.
*/
private synchronized boolean handleMouseClicksAndHover(final ViewPanel viewPanel) {
- MouseClick unprocessedMouseClick = findUnprocessedMouseClick();
+ boolean rerenderNeeded = false;
+ MouseEvent event = findClickLocationToTrace();
+ if (event != null) {
+ // process mouse clicks as a first priority
+ rerenderNeeded = true;
+ } else {
+ // when there are no mouse clicks, process mouse hovering
+
+ if (mouseMoved) {
+ mouseMoved = false;
+ // we would like to re-render frame when user moved mouse, to see what objects mouse is hovering over
+ rerenderNeeded = true;
+ }
+
+ if (currentMouseLocation != null) {
+ // mouse click with button 0 amounts to mouse hovering event
+ event = new MouseEvent(currentMouseLocation, 0);
+ }
+ }
+
+ if (viewPanel.getRenderingContext() != null)
+ viewPanel.getRenderingContext().setMouseEvent(event);
- if (unprocessedMouseClick != null) {
- viewPanel.getRenderingContext().mouseClick = unprocessedMouseClick;
- return false;
- } else
- return handleMouseHovering(viewPanel);
+ return rerenderNeeded;
}
- private MouseClick findUnprocessedMouseClick() {
- synchronized (detectedMouseClicks) {
- if (detectedMouseClicks.isEmpty())
+ private MouseEvent findClickLocationToTrace() {
+ synchronized (detectedMouseEvents) {
+ if (detectedMouseEvents.isEmpty())
return null;
- return detectedMouseClicks.remove(0);
+ return detectedMouseEvents.remove(0);
}
}
- private boolean handleMouseHovering(ViewPanel viewPanel) {
- if (currentMouseLocation != null)
- // mouse click with button 0 amounts to mouse hovering event
- viewPanel.getRenderingContext().mouseClick = new MouseClick(currentMouseLocation, 0);
-
- if (mouseMoved) {
- mouseMoved = false;
- return true;
- } else
- return false;
- }
-
boolean isKeyPressed(final int keyCode) {
return pressedKeysToPressedTimeMap.containsKey(keyCode);
}
}
@Override
- public void mouseClicked(final MouseEvent e) {
- synchronized (detectedMouseClicks) {
- detectedMouseClicks.add(new MouseClick(e.getX(), e.getY(), e.getButton()));
+ public void mouseClicked(final java.awt.event.MouseEvent e) {
+ synchronized (detectedMouseEvents) {
+ detectedMouseEvents.add(new MouseEvent(e.getX(), e.getY(), e.getButton()));
}
}
}
@Override
- public void mouseEntered(final MouseEvent e) {
+ public void mouseEntered(final java.awt.event.MouseEvent e) {
mouseWithinWindow = true;
}
@Override
- public synchronized void mouseExited(final MouseEvent e) {
+ public synchronized void mouseExited(final java.awt.event.MouseEvent e) {
mouseWithinWindow = false;
currentMouseLocation = null;
}
@Override
- public synchronized void mouseMoved(final MouseEvent e) {
+ public synchronized void mouseMoved(final java.awt.event.MouseEvent e) {
currentMouseLocation = new Point2D(e.getX(), e.getY());
mouseMoved = true;
}
@Override
- public void mousePressed(final MouseEvent e) {
+ public void mousePressed(final java.awt.event.MouseEvent e) {
}
@Override
* @return <code>true</code> if view needs to be repainted.
*/
private boolean handleMouseDragging() {
- // TODO: need to detect whether user moved mouse or touch screen
+ // TODO: It would be nice here to detect somehow whether user moved mouse or touch screen.
+ // in case of touch screen, we would like to reverse movement along X and Y axis.
final Avatar avatar = viewPanel.getAvatar();
// for mouse