import java.util.List;
import java.util.Map;
-public class UserInputTracker
- implements MouseMotionListener, KeyListener, MouseListener, MouseWheelListener, ViewRenderListener {
+public class UserInputTracker implements
+ MouseMotionListener, KeyListener, MouseListener, MouseWheelListener, ViewRenderListener {
/**
* <pre>
@Override
public boolean beforeRender(final ViewPanel viewPanel, final int millisecondsSinceLastFrame) {
- boolean viewUpdateNeeded = handleDetectedMouseClicks(viewPanel);
-
- viewUpdateNeeded |= handleDetectedKeyEvents();
-
- viewPanel.getKeyboardFocusTracker().getCurrentFocusOwner().beforeRender(viewPanel,
- millisecondsSinceLastFrame);
-
- viewUpdateNeeded |= trackMouse();
+ boolean viewUpdateNeeded = handleKeyboardEvents();
+ viewUpdateNeeded |= handleMouseClicksAndHover(viewPanel);
+ viewUpdateNeeded |= handleMouseDragging();
+ viewUpdateNeeded |= handleMouseVerticalScrolling();
return viewUpdateNeeded;
}
panel.addMouseWheelListener(this);
}
- private boolean handleDetectedKeyEvents() {
- boolean keyEventsHandled = false;
-
+ /**
+ * @return <code>true</code> if view needs to be repainted.
+ */
+ private boolean handleKeyboardEvents() {
final UserInputHandler currentFocusOwner = viewPanel.getKeyboardFocusTracker().getCurrentFocusOwner();
+ ArrayList<KeyEvent> unprocessedKeyboardEvents = getUnprocessedKeyboardEvents();
+ return currentFocusOwner == null ? false :
+ forwardKeyboardEventsToFocusOwner(currentFocusOwner, unprocessedKeyboardEvents);
+ }
+
+ private ArrayList<KeyEvent> getUnprocessedKeyboardEvents() {
synchronized (detectedKeyEvents) {
- if (currentFocusOwner == null) {
- detectedKeyEvents.clear();
- return false;
- }
-
- while (!detectedKeyEvents.isEmpty()) {
- final KeyEvent keyEvent = detectedKeyEvents.remove(0);
-
- switch (keyEvent.getID()) {
- case KeyEvent.KEY_PRESSED:
- currentFocusOwner.keyPressed(keyEvent, viewPanel);
- keyEventsHandled = true;
- break;
-
- case KeyEvent.KEY_RELEASED:
- currentFocusOwner.keyReleased(keyEvent, viewPanel);
- keyEventsHandled = true;
- break;
- }
- }
+ ArrayList<KeyEvent> result = new ArrayList<>(detectedKeyEvents);
+ detectedKeyEvents.clear();
+ return result;
}
+ }
- return keyEventsHandled;
+ /**
+ * @return <code>true</code> if view update is needed.
+ */
+ private boolean forwardKeyboardEventsToFocusOwner(
+ UserInputHandler currentFocusOwner, ArrayList<KeyEvent> keyEvents) {
+ boolean viewUpdateNeeded = false;
+
+ for (KeyEvent keyEvent : keyEvents)
+ viewUpdateNeeded |= processKeyEvent(currentFocusOwner, keyEvent);
+
+ return viewUpdateNeeded;
+ }
+
+ private boolean processKeyEvent(UserInputHandler currentFocusOwner, KeyEvent keyEvent) {
+ switch (keyEvent.getID()) {
+ case KeyEvent.KEY_PRESSED:
+ return currentFocusOwner.keyPressed(keyEvent, viewPanel);
+
+ case KeyEvent.KEY_RELEASED:
+ return currentFocusOwner.keyReleased(keyEvent, viewPanel);
+ }
+ return false;
}
/**
* @return <code>true</code> if view needs to be repainted.
*/
- private synchronized boolean handleDetectedMouseClicks(final ViewPanel viewPanel) {
- if (detectedMouseClicks.isEmpty()) {
+ private synchronized boolean handleMouseClicksAndHover(final ViewPanel viewPanel) {
+ MouseClick unprocessedMouseClick = findUnprocessedMouseClick();
+
+ if (unprocessedMouseClick != null) {
+ viewPanel.getRenderingContext().mouseClick = unprocessedMouseClick;
+ return false;
+ } else
+ return handleMouseHovering(viewPanel);
+ }
- if (currentMouseLocation != null)
- viewPanel.getRenderingContext().mouseClick = new MouseClick(currentMouseLocation, 0);
+ private MouseClick findUnprocessedMouseClick() {
+ synchronized (detectedMouseClicks) {
+ if (detectedMouseClicks.isEmpty())
+ return null;
- if (mouseMoved) {
- mouseMoved = false;
- return true;
- } else
- return false;
+ return detectedMouseClicks.remove(0);
}
+ }
- viewPanel.getRenderingContext().mouseClick = detectedMouseClicks.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);
- return true;
+ if (mouseMoved) {
+ mouseMoved = false;
+ return true;
+ } else
+ return false;
}
boolean isKeyPressed(final int keyCode) {
synchronized (detectedKeyEvents) {
pressedKeysToPressedTimeMap.put(evt.getKeyCode(), System.currentTimeMillis());
detectedKeyEvents.add(evt);
- viewPanel.repaintDuringNextViewUpdate();
}
}
synchronized (detectedKeyEvents) {
pressedKeysToPressedTimeMap.remove(evt.getKeyCode());
detectedKeyEvents.add(evt);
- viewPanel.repaintDuringNextViewUpdate();
}
}
}
/**
- * Interpret mouse movement
+ * @return <code>true</code> if view needs to be repainted.
*/
- private boolean trackMouse() {
+ private boolean handleMouseVerticalScrolling() {
final Avatar avatar = viewPanel.getAvatar();
- trackDragging(avatar);
- trackVerticalScrolling(avatar);
-
- boolean repaintNeeded = !mouseDraggedDirection.isZero() || (wheelMovedDirection != 0);
-
- // reset movement counters
- wheelMovedDirection = 0;
- mouseDraggedDirection.zero();
-
- return repaintNeeded;
- }
-
- private void trackVerticalScrolling(Avatar avatar) {
final double actualAcceleration = 50 * avatar.avatarAcceleration * (1 + (avatar.getMovementSpeed() / 10));
avatar.getMovementVector().y += (wheelMovedDirection * actualAcceleration);
avatar.enforceSpeedLimit();
+ boolean repaintNeeded = wheelMovedDirection != 0;
+ wheelMovedDirection = 0;
+ return repaintNeeded;
}
- private void trackDragging(Avatar avatar) {
+ /**
+ * @return <code>true</code> if view needs to be repainted.
+ */
+ private boolean handleMouseDragging() {
// TODO: need to detect whether user moved mouse or touch screen
+ final Avatar avatar = viewPanel.getAvatar();
// for mouse
avatar.setAngleXZ(avatar.getAngleXZ() - ((float) mouseDraggedDirection.x / 50));
avatar.setAngleYZ(avatar.getAngleYZ() - ((float) mouseDraggedDirection.y / 50));
// mouseDraggedDirection.x / 50));
// avatar.setAngleYZ(avatar.getAngleYZ() + ((float)
// mouseDraggedDirection.y / 50));
+
+ boolean viewUpdateNeeded = !mouseDraggedDirection.isZero();
+ mouseDraggedDirection.zero();
+ return viewUpdateNeeded;
}
}