Code refactoring
authorSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Thu, 21 May 2020 21:42:21 +0000 (00:42 +0300)
committerSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Thu, 21 May 2020 21:42:21 +0000 (00:42 +0300)
src/main/java/eu/svjatoslav/sixth/e3d/gui/GuiComponent.java
src/main/java/eu/svjatoslav/sixth/e3d/gui/ViewRenderListener.java
src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/HIDInputTracker.java
src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/KeyboardFocusStack.java
src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/KeyboardHelper.java [new file with mode: 0644]
src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/KeyboardInputHandler.java [new file with mode: 0644]
src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/UserInputHandler.java [deleted file]
src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/WorldNavigationUserInputTracker.java
src/main/java/eu/svjatoslav/sixth/e3d/gui/textEditorComponent/KeyboardHelper.java [deleted file]
src/main/java/eu/svjatoslav/sixth/e3d/gui/textEditorComponent/TextEditComponent.java

index 33bbb03..0fc1f11 100644 (file)
@@ -7,8 +7,8 @@ package eu.svjatoslav.sixth.e3d.gui;
 import eu.svjatoslav.sixth.e3d.geometry.Box;
 import eu.svjatoslav.sixth.e3d.geometry.Point3D;
 import eu.svjatoslav.sixth.e3d.gui.humaninput.MouseInteractionController;
-import eu.svjatoslav.sixth.e3d.gui.humaninput.UserInputHandler;
-import eu.svjatoslav.sixth.e3d.gui.textEditorComponent.KeyboardHelper;
+import eu.svjatoslav.sixth.e3d.gui.humaninput.KeyboardInputHandler;
+import eu.svjatoslav.sixth.e3d.gui.humaninput.KeyboardHelper;
 import eu.svjatoslav.sixth.e3d.math.Transform;
 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.line.LineAppearance;
 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.base.AbstractCompositeShape;
@@ -17,7 +17,7 @@ import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.wireframe.Wirefr
 import java.awt.event.KeyEvent;
 
 public class GuiComponent extends AbstractCompositeShape implements
-        UserInputHandler, MouseInteractionController {
+        KeyboardInputHandler, MouseInteractionController {
 
     private static final String GROUP_GUI_FOCUS = "gui.focus";
     public final ViewPanel viewPanel;
@@ -33,12 +33,6 @@ public class GuiComponent extends AbstractCompositeShape implements
         setDimensions(size);
     }
 
-    @Override
-    public boolean beforeRender(final ViewPanel viewPanel,
-                                final int millisecondsSinceLastFrame) {
-        return false;
-    }
-
     private WireframeBox createBorder() {
         final LineAppearance appearance = new LineAppearance(10,
                 new eu.svjatoslav.sixth.e3d.renderer.raster.Color(255, 0, 0, 100));
index e2f2e85..30e73d2 100644 (file)
@@ -7,13 +7,14 @@ package eu.svjatoslav.sixth.e3d.gui;
 public interface ViewRenderListener {
 
     /**
-     * Notifies that it is about time to render next frame and
+     * Notifies that it is about time (to keep constant framerate) to render next frame and
      * allows listener to do any related processing that it needs to.
      * <p>
      * Each {@link ViewRenderListener} will be notified exactly once before every frame is rendered.
      * <p>
      * {@link ViewRenderListener} can determine if frame repaint is actually
      * needed from its perspective. Frame will be rendered only if at least one listener says yes.
+     * This mechanism allows to save computing power and energy by skipping frame rendering when possible.
      *
      * @return <code>true</code> if underlying view shall be re-rendered. If at least one of the view update listeners
      * returns <code>true</code>, view is re-rendered.
index b5061dd..af0ae31 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Sixth 3D engine. Author: Svjatoslav Agejenko. 
+ * Sixth 3D engine. Author: Svjatoslav Agejenko.
  * This project is released under Creative Commons Zero (CC0) license.
  */
 package eu.svjatoslav.sixth.e3d.gui.humaninput;
@@ -16,6 +16,12 @@ import java.util.HashMap;
 import java.util.List;
 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.
+ */
 public class HIDInputTracker implements
         MouseMotionListener, KeyListener, MouseListener, MouseWheelListener, ViewRenderListener {
 
@@ -69,7 +75,7 @@ public class HIDInputTracker implements
      * @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
@@ -88,7 +94,7 @@ public class HIDInputTracker implements
      * @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)
@@ -97,7 +103,7 @@ public class HIDInputTracker implements
         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);
@@ -114,7 +120,7 @@ public class HIDInputTracker implements
     private synchronized boolean handleMouseClicksAndHover(final ViewPanel viewPanel) {
         boolean rerenderNeeded = false;
         MouseEvent event = findClickLocationToTrace();
-        if (event != null){
+        if (event != null) {
             // process mouse clicks as a first priority
             rerenderNeeded = true;
         } else {
@@ -240,7 +246,8 @@ public class HIDInputTracker implements
      * @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
index 27c232b..9a1cd6d 100644 (file)
@@ -12,15 +12,15 @@ public class KeyboardFocusStack {
 
     private final ViewPanel viewPanel;
     private WorldNavigationUserInputTracker defaultInputHandler = new WorldNavigationUserInputTracker();
-    private Stack<UserInputHandler> inputHandlers = new Stack<>();
-    private UserInputHandler currentUserInputHandler;
+    private Stack<KeyboardInputHandler> inputHandlers = new Stack<>();
+    private KeyboardInputHandler currentUserInputHandler;
 
     public KeyboardFocusStack(final ViewPanel viewPanel) {
         this.viewPanel = viewPanel;
         pushFocusOwner(defaultInputHandler);
     }
 
-    public UserInputHandler getCurrentFocusOwner() {
+    public KeyboardInputHandler getCurrentFocusOwner() {
         return currentUserInputHandler;
     }
 
@@ -35,7 +35,7 @@ public class KeyboardFocusStack {
         currentUserInputHandler.focusReceived(viewPanel);
     }
 
-    public boolean pushFocusOwner(final UserInputHandler newInputHandler) {
+    public boolean pushFocusOwner(final KeyboardInputHandler newInputHandler) {
         boolean updateNeeded = false;
 
         if (currentUserInputHandler == newInputHandler)
diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/KeyboardHelper.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/KeyboardHelper.java
new file mode 100644 (file)
index 0000000..44b861e
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Sixth 3D engine. Author: Svjatoslav Agejenko. 
+ * This project is released under Creative Commons Zero (CC0) license.
+ */
+package eu.svjatoslav.sixth.e3d.gui.humaninput;
+
+import java.awt.event.InputEvent;
+import java.util.HashSet;
+import java.util.Set;
+
+public class KeyboardHelper {
+
+    public static final int TAB = 9;
+    public static final int DOWN = 40;
+    public static final int UP = 38;
+    public static final int RIGHT = 39;
+    public static final int LEFT = 37;
+    public static final int PGDOWN = 34;
+    public static final int PGUP = 33;
+    public static final int HOME = 36;
+    public static final int END = 35;
+    public static final int DEL = 127;
+    public static final int ENTER = 10;
+    public static final int BACKSPACE = 8;
+    public static final int ESC = 27;
+    public static final int SHIFT = 16;
+
+    private static final Set<Integer> nonText;
+
+    static {
+        nonText = new HashSet<>();
+        nonText.add(DOWN);
+        nonText.add(UP);
+        nonText.add(LEFT);
+        nonText.add(RIGHT);
+
+        nonText.add(SHIFT);
+        nonText.add(ESC);
+    }
+
+    public static boolean isAltPressed(final int modifiersEx) {
+        return (modifiersEx | InputEvent.ALT_DOWN_MASK) == modifiersEx;
+    }
+
+    public static boolean isCtrlPressed(final int modifiersEx) {
+        return (modifiersEx | InputEvent.CTRL_DOWN_MASK) == modifiersEx;
+    }
+
+    public static boolean isShiftPressed(final int modifiersEx) {
+        return (modifiersEx | InputEvent.SHIFT_DOWN_MASK) == modifiersEx;
+    }
+
+    public static boolean isText(final int keyCode) {
+        return !nonText.contains(keyCode);
+    }
+
+}
diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/KeyboardInputHandler.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/KeyboardInputHandler.java
new file mode 100644 (file)
index 0000000..3f26cdf
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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.gui.ViewPanel;
+
+import java.awt.event.KeyEvent;
+
+/**
+ * This is the process:
+ *
+ * 1. Component receives focus, perhaps because user clicked on it with the mouse.
+ * 2. Now component will receive user key press and release events from the keyboard.
+ * 3. Component loses focus. Perhaps user chose another component to interact with.
+ */
+public interface KeyboardInputHandler {
+
+    /**
+     * @return <code>true</code> if view needs to be re-rendered.
+     */
+    boolean focusLost(ViewPanel viewPanel);
+
+    /**
+     * @return <code>true</code> if view needs to be re-rendered.
+     */
+    boolean focusReceived(ViewPanel viewPanel);
+
+    /**
+     * @return <code>true</code> if view needs to be re-rendered.
+     */
+    boolean keyPressed(KeyEvent event, ViewPanel viewPanel);
+
+    /**
+     * @return <code>true</code> if view needs to be re-rendered.
+     */
+    boolean keyReleased(KeyEvent event, ViewPanel viewPanel);
+
+}
diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/UserInputHandler.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/UserInputHandler.java
deleted file mode 100644 (file)
index 9bbd218..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.gui.ViewPanel;
-import eu.svjatoslav.sixth.e3d.gui.ViewRenderListener;
-
-import java.awt.event.KeyEvent;
-
-public interface UserInputHandler extends ViewRenderListener {
-
-    /**
-     * @return <code>true</code> if view update is needed.
-     */
-    boolean focusLost(ViewPanel viewPanel);
-
-    /**
-     * @return <code>true</code> if view update is needed.
-     */
-    boolean focusReceived(ViewPanel viewPanel);
-
-    /**
-     * @return <code>true</code> if view update is needed.
-     */
-    boolean keyPressed(KeyEvent event, ViewPanel viewPanel);
-
-    /**
-     * @return <code>true</code> if view update is needed.
-     */
-    boolean keyReleased(KeyEvent event, ViewPanel viewPanel);
-
-}
index a97dda6..8a66a3e 100644 (file)
@@ -6,11 +6,11 @@ package eu.svjatoslav.sixth.e3d.gui.humaninput;
 
 import eu.svjatoslav.sixth.e3d.gui.Avatar;
 import eu.svjatoslav.sixth.e3d.gui.ViewPanel;
-import eu.svjatoslav.sixth.e3d.gui.textEditorComponent.KeyboardHelper;
+import eu.svjatoslav.sixth.e3d.gui.ViewRenderListener;
 
 import java.awt.event.KeyEvent;
 
-public class WorldNavigationUserInputTracker implements UserInputHandler {
+public class WorldNavigationUserInputTracker implements KeyboardInputHandler, ViewRenderListener {
 
     @Override
     public boolean beforeRender(final ViewPanel viewPanel,
diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/textEditorComponent/KeyboardHelper.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/textEditorComponent/KeyboardHelper.java
deleted file mode 100644 (file)
index 7ae8c77..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Sixth 3D engine. Author: Svjatoslav Agejenko. 
- * This project is released under Creative Commons Zero (CC0) license.
- */
-package eu.svjatoslav.sixth.e3d.gui.textEditorComponent;
-
-import java.util.HashSet;
-import java.util.Set;
-
-public class KeyboardHelper {
-
-    public static final int TAB = 9;
-    public static final int DOWN = 40;
-    public static final int UP = 38;
-    public static final int RIGHT = 39;
-    public static final int LEFT = 37;
-    public static final int PGDOWN = 34;
-    public static final int PGUP = 33;
-    public static final int HOME = 36;
-    public static final int END = 35;
-    public static final int DEL = 127;
-    public static final int ENTER = 10;
-    public static final int BACKSPACE = 8;
-    public static final int ESC = 27;
-    public static final int SHIFT = 16;
-
-    private static final Set<Integer> nonText;
-
-    static {
-        nonText = new HashSet<>();
-        nonText.add(DOWN);
-        nonText.add(UP);
-        nonText.add(LEFT);
-        nonText.add(RIGHT);
-
-        nonText.add(SHIFT);
-        nonText.add(ESC);
-    }
-
-    public static boolean isAlt(final int modifiers) {
-        return (modifiers | 8) == modifiers;
-    }
-
-    public static boolean isCtrl(final int modifiers) {
-        return (modifiers | 2) == modifiers;
-    }
-
-    public static boolean isShift(final int modifiers) {
-        return (modifiers | 1) == modifiers;
-    }
-
-    public static boolean isText(final int keyCode) {
-        return !nonText.contains(keyCode);
-    }
-
-}
index a6987eb..9ee9109 100755 (executable)
@@ -8,6 +8,7 @@ import eu.svjatoslav.sixth.e3d.geometry.Point2D;
 import eu.svjatoslav.sixth.e3d.gui.GuiComponent;
 import eu.svjatoslav.sixth.e3d.gui.TextPointer;
 import eu.svjatoslav.sixth.e3d.gui.ViewPanel;
+import eu.svjatoslav.sixth.e3d.gui.humaninput.KeyboardHelper;
 import eu.svjatoslav.sixth.e3d.math.Transform;
 import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.textcanvas.TextCanvas;
@@ -22,28 +23,30 @@ import java.util.Set;
 public class TextEditComponent extends GuiComponent implements ClipboardOwner {
 
     private static final long serialVersionUID = -7118833957783600630L;
-    // lines that need to be repainted
+
+    /**
+     * Text rows that need to be repainted.
+     */
     private final Set<Integer> dirtyRows = new HashSet<>();
+
     private final TextCanvas textCanvas;
     public int scrolledCharacters = 0, scrolledLines = 0;
     public boolean selecting = false;
     public TextPointer selectionStart = new TextPointer(0, 0);
     public TextPointer selectionEnd = new TextPointer(0, 0);
-    public TextPointer cursorLocation;
+    public TextPointer cursorLocation = new TextPointer(0, 0);
     Page page = new Page();
     ColorConfig colorConfig = new ColorConfig();
     boolean repaintPage = false;
 
     public TextEditComponent(final Transform transform,
-                             final ViewPanel viewPanel, final Point2D size) {
-        super(transform, viewPanel, size.to3D());
-
-        cursorLocation = new TextPointer(0, 0);
+                             final ViewPanel viewPanel, final Point2D sizeInWorldCoordinates) {
+        super(transform, viewPanel, sizeInWorldCoordinates.to3D());
 
         // initialize visual panel
 
-        final int columns = (int) (size.x / TextCanvas.FONT_CHAR_WIDTH);
-        final int rows = (int) (size.y / TextCanvas.FONT_CHAR_HEIGHT);
+        final int columns = (int) (sizeInWorldCoordinates.x / TextCanvas.FONT_CHAR_WIDTH);
+        final int rows = (int) (sizeInWorldCoordinates.y / TextCanvas.FONT_CHAR_HEIGHT);
 
         textCanvas = new TextCanvas(new Transform(), new TextPointer(rows,
                 columns), Color.WHITE, colorConfig.normalBack);
@@ -393,17 +396,16 @@ public class TextEditComponent extends GuiComponent implements ClipboardOwner {
     }
 
     private void processKeyEvent(final KeyEvent event) {
-        final int modifiers = event.getModifiers();
-
+        final int modifiers = event.getModifiersEx();
         final int keyCode = event.getKeyCode();
         final char keyChar = event.getKeyChar();
 
         // System.out.println("Keycode:" + keyCode s+ ", keychar:" + keyChar);
 
-        if (KeyboardHelper.isAlt(modifiers))
+        if (KeyboardHelper.isAltPressed(modifiers))
             return;
 
-        if (KeyboardHelper.isCtrl(modifiers)) {
+        if (KeyboardHelper.isCtrlPressed(modifiers)) {
             processCtrlCombinations(keyCode);
             return;
         }
@@ -420,10 +422,7 @@ public class TextEditComponent extends GuiComponent implements ClipboardOwner {
             return;
         }
 
-        // System.out.println("Co:" + String.valueOf(code) + "  Ch:" +
-        // String.valueOf(keyChar));
-
-        if (KeyboardHelper.isShift(modifiers)) {
+        if (KeyboardHelper.isShiftPressed(modifiers)) {
             if (!selecting)
                 attemptSelectionStart:{
 
@@ -434,9 +433,6 @@ public class TextEditComponent extends GuiComponent implements ClipboardOwner {
                             | (keyChar == 8) | (keyChar == 9))
                         break attemptSelectionStart;
 
-                    // System.out.println("Selection started:" + keyChar + " "
-                    // + keyCode);
-
                     selectionStart = new TextPointer(cursorLocation);
                     selectionEnd = selectionStart;
                     selecting = true;
@@ -492,7 +488,7 @@ public class TextEditComponent extends GuiComponent implements ClipboardOwner {
     }
 
     private void processTab(final int modifiers) {
-        if (KeyboardHelper.isShift(modifiers)) {
+        if (KeyboardHelper.isShiftPressed(modifiers)) {
             if (selectionStart.compareTo(selectionEnd) != 0) {
                 // dedent multiple lines
                 ensureSelectionOrder();