}
@Override
- public boolean mouseClicked() {
+ public boolean mouseClicked(int button) {
return viewPanel.getKeyboardFocusStack().pushFocusOwner(this);
}
/**
* UI component that mouse is currently hovering over.
*/
- private MouseInteractionController currentMouseOverComponent;
+ private MouseInteractionController objectPreviouslyUnderMouseCursor;
public void prepareForNewFrameRendering(){
mouseEvent = null;
- objectUnderMouse = null;
+ currentObjectUnderMouseCursor = null;
}
/**
/**
* Item that user clicked on.
*/
- private MouseInteractionController objectUnderMouse;
+ private MouseInteractionController currentObjectUnderMouseCursor;
/**
* Called when given object was detected under mouse cursor, while processing {@link #mouseEvent}.
* Because objects are rendered back to front. The last method caller will set the top-most object, if
* there are multiple objects under mouse cursor.
*/
- public void setObjectUnderMouse(MouseInteractionController objectUnderMouse) {
- this.objectUnderMouse = objectUnderMouse;
+ public void setCurrentObjectUnderMouseCursor(MouseInteractionController currentObjectUnderMouseCursor) {
+ this.currentObjectUnderMouseCursor = currentObjectUnderMouseCursor;
}
public RenderingContext(final int width, final int height) {
/**
* @return <code>true</code> if view repaint is needed.
*/
- public boolean handleDetectedComponentMouseEvents() {
- if (objectUnderMouse != null) {
- if (mouseEvent.button == 0) {
- // mouse over
- if (currentMouseOverComponent == null) {
- currentMouseOverComponent = objectUnderMouse;
- return currentMouseOverComponent.mouseEntered();
- } else if (currentMouseOverComponent != objectUnderMouse) {
- boolean viewRepaintNeeded = currentMouseOverComponent.mouseExited();
- currentMouseOverComponent = objectUnderMouse;
- return viewRepaintNeeded | currentMouseOverComponent.mouseEntered();
- }
- } else {
- // mouse click
- return objectUnderMouse.mouseClicked();
- }
- } else if (currentMouseOverComponent != null) {
- boolean viewRepaintNeeded = currentMouseOverComponent.mouseExited();
- currentMouseOverComponent = null;
- return viewRepaintNeeded;
+ public boolean handlePossibleComponentMouseEvent() {
+ if (mouseEvent == null) return false;
+
+ boolean viewRepaintNeeded = false;
+
+ if (objectPreviouslyUnderMouseCursor != currentObjectUnderMouseCursor) {
+ // Mouse cursor has just entered or left component.
+ viewRepaintNeeded = objectPreviouslyUnderMouseCursor != null && objectPreviouslyUnderMouseCursor.mouseExited();
+ viewRepaintNeeded |= currentObjectUnderMouseCursor != null && currentObjectUnderMouseCursor.mouseEntered();
+ objectPreviouslyUnderMouseCursor = currentObjectUnderMouseCursor;
}
- return false;
+
+ if (mouseEvent.button != 0 && currentObjectUnderMouseCursor != null) {
+ // Mouse button was clicked on some component.
+ viewRepaintNeeded |= currentObjectUnderMouseCursor.mouseClicked(mouseEvent.button);
+ }
+
+ return viewRepaintNeeded;
}
}
// abort rendering if window size is invalid
if ((getWidth() > 0) && (getHeight() > 0) && renderFrame) {
renderFrame();
- viewRepaintNeeded = renderingContext.handleDetectedComponentMouseEvents();
+ viewRepaintNeeded = renderingContext.handlePossibleComponentMouseEvent();
}
}
import java.util.Map;
/**
- * Human input device input tracker.
- * <p>
- * Idea is to capture all keyboard and mouse inputs from underlying operating system in this class
- * and forward those as needed to subsequent virtual components.
+ * 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<MouseEvent> detectedMouseEvents = new ArrayList<>();
private final List<KeyEvent> detectedKeyEvents = new ArrayList<>();
private int wheelMovedDirection = 0;
- private Point2D mouseDraggedDirection = new Point2D();
+ private final Point2D mouseDraggedDirection = new Point2D();
private Point2D oldMouseCoordinatesWhenDragging;
- private ViewPanel viewPanel;
+ private final ViewPanel viewPanel;
private Point2D currentMouseLocation;
private boolean mouseMoved;
private boolean mouseWithinWindow = false;
import eu.svjatoslav.sixth.e3d.geometry.Point2D;
+/**
+ * Represents mouse event.
+ */
public class MouseEvent {
+ /**
+ * Mouse coordinate in screen space (pixels) relative to top left corner of the screen
+ * when mouse button was clicked.
+ */
public Point2D coordinate;
/**
- * Indicates pressed mouse button. Except 0 that simply means mouse over
- * given region.
+ * <pre>
+ * 0 - mouse over (no button pressed)
+ * 1 - left mouse button
+ * 2 - middle mouse button
+ * 3 - right mouse button
+ * </pre>
*/
public int button;
* Called when mouse is clicked on component.
* @return <code>true</code> if view update is needed as a consequence of this mouse click.
*/
- boolean mouseClicked();
+ boolean mouseClicked(int button);
/**
* Called when mouse gets over given component.
if (context.getMouseEvent() != null)
if (pointWithinPolygon(context.getMouseEvent().coordinate,
onScreenPoint1, onScreenPoint2, onScreenPoint3))
- context.setObjectUnderMouse(mouseInteractionController);
+ context.setCurrentObjectUnderMouseCursor(mouseInteractionController);
if (color.isTransparent())
return;
* Polygon texture coordinates.
*/
public Point2D texturePoint1, texturePoint2, texturePoint3;
- private boolean showBorders = false;
+
+ /**
+ * If <code>true</code> then polygon borders will be drawn.
+ * It is used for debugging purposes.
+ */
+ public boolean showBorders = false;
private double totalTextureDistance = -1;
public TexturedPolygon(final Point3D p1, final Point3D p2,
if (pointWithinPolygon(
renderBuffer.getMouseEvent().coordinate, projectedPoint1,
projectedPoint2, projectedPoint3))
- renderBuffer.setObjectUnderMouse(mouseInteractionController);
+ renderBuffer.setCurrentObjectUnderMouseCursor(mouseInteractionController);
// Show polygon boundaries (for debugging)
if (showBorders)