From a377e3094d304bbc815b36edc2eb303ec023ea48 Mon Sep 17 00:00:00 2001 From: Svjatoslav Agejenko Date: Fri, 24 Feb 2023 23:57:39 +0200 Subject: [PATCH] Improved code readability. Components now aware of what mouse button was clicked. --- .../sixth/e3d/gui/GuiComponent.java | 2 +- .../sixth/e3d/gui/RenderingContext.java | 48 +++++++++---------- .../svjatoslav/sixth/e3d/gui/ViewPanel.java | 2 +- .../e3d/gui/humaninput/HIDInputTracker.java | 20 ++++---- .../sixth/e3d/gui/humaninput/MouseEvent.java | 15 +++++- .../MouseInteractionController.java | 2 +- .../basic/solidpolygon/SolidPolygon.java | 2 +- .../texturedpolygon/TexturedPolygon.java | 9 +++- 8 files changed, 54 insertions(+), 46 deletions(-) diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/GuiComponent.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/GuiComponent.java index 0fc1f11..e72de54 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/gui/GuiComponent.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/gui/GuiComponent.java @@ -94,7 +94,7 @@ public class GuiComponent extends AbstractCompositeShape implements } @Override - public boolean mouseClicked() { + public boolean mouseClicked(int button) { return viewPanel.getKeyboardFocusStack().pushFocusOwner(this); } diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/RenderingContext.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/RenderingContext.java index 3641bc9..b6417e5 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/gui/RenderingContext.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/gui/RenderingContext.java @@ -28,11 +28,11 @@ public class RenderingContext { /** * UI component that mouse is currently hovering over. */ - private MouseInteractionController currentMouseOverComponent; + private MouseInteractionController objectPreviouslyUnderMouseCursor; public void prepareForNewFrameRendering(){ mouseEvent = null; - objectUnderMouse = null; + currentObjectUnderMouseCursor = null; } /** @@ -51,15 +51,15 @@ public class RenderingContext { /** * 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) { @@ -85,28 +85,24 @@ public class RenderingContext { /** * @return true 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; } } diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/ViewPanel.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/ViewPanel.java index 7f9b7eb..088d98a 100755 --- a/src/main/java/eu/svjatoslav/sixth/e3d/gui/ViewPanel.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/gui/ViewPanel.java @@ -206,7 +206,7 @@ public class ViewPanel extends JPanel implements ComponentListener { // abort rendering if window size is invalid if ((getWidth() > 0) && (getHeight() > 0) && renderFrame) { renderFrame(); - viewRepaintNeeded = renderingContext.handleDetectedComponentMouseEvents(); + viewRepaintNeeded = renderingContext.handlePossibleComponentMouseEvent(); } } diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/HIDInputTracker.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/HIDInputTracker.java index af0ae31..a63c33b 100755 --- a/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/HIDInputTracker.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/HIDInputTracker.java @@ -17,29 +17,25 @@ import java.util.List; import java.util.Map; /** - * Human input device input tracker. - *

- * 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 { /** - *

-     * 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.
-     * 
+ *

Map of pressed keys.

+ *

Key is mouse button code.

+ *

Value is system milliseconds when button was pressed.

+ *

So by reading the map one can determine currently pressed buttons as well as duration.

*/ private final Map pressedKeysToPressedTimeMap = new HashMap<>(); private final List detectedMouseEvents = new ArrayList<>(); private final List 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; diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/MouseEvent.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/MouseEvent.java index 8582cc0..b487d15 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/MouseEvent.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/MouseEvent.java @@ -6,13 +6,24 @@ package eu.svjatoslav.sixth.e3d.gui.humaninput; 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. + *
+     * 0 - mouse over (no button pressed)
+     * 1 - left mouse button
+     * 2 - middle mouse button
+     * 3 - right mouse button
+     * 
*/ public int button; diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/MouseInteractionController.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/MouseInteractionController.java index 9ae1f43..e29f978 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/MouseInteractionController.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/MouseInteractionController.java @@ -10,7 +10,7 @@ public interface MouseInteractionController { * Called when mouse is clicked on component. * @return true 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. diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/basic/solidpolygon/SolidPolygon.java b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/basic/solidpolygon/SolidPolygon.java index bc10857..87143b5 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/basic/solidpolygon/SolidPolygon.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/basic/solidpolygon/SolidPolygon.java @@ -102,7 +102,7 @@ public class SolidPolygon extends AbstractCoordinateShape { if (context.getMouseEvent() != null) if (pointWithinPolygon(context.getMouseEvent().coordinate, onScreenPoint1, onScreenPoint2, onScreenPoint3)) - context.setObjectUnderMouse(mouseInteractionController); + context.setCurrentObjectUnderMouseCursor(mouseInteractionController); if (color.isTransparent()) return; diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/basic/texturedpolygon/TexturedPolygon.java b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/basic/texturedpolygon/TexturedPolygon.java index 889acda..7a6f2bf 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/basic/texturedpolygon/TexturedPolygon.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/basic/texturedpolygon/TexturedPolygon.java @@ -26,7 +26,12 @@ public class TexturedPolygon extends AbstractCoordinateShape { * Polygon texture coordinates. */ public Point2D texturePoint1, texturePoint2, texturePoint3; - private boolean showBorders = false; + + /** + * If true 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, @@ -140,7 +145,7 @@ public class TexturedPolygon extends AbstractCoordinateShape { if (pointWithinPolygon( renderBuffer.getMouseEvent().coordinate, projectedPoint1, projectedPoint2, projectedPoint3)) - renderBuffer.setObjectUnderMouse(mouseInteractionController); + renderBuffer.setCurrentObjectUnderMouseCursor(mouseInteractionController); // Show polygon boundaries (for debugging) if (showBorders) -- 2.20.1