#50 additional mouse pointer options
authorKevin Lamonte <kevin.lamonte@gmail.com>
Fri, 16 Aug 2019 22:16:18 +0000 (17:16 -0500)
committerKevin Lamonte <kevin.lamonte@gmail.com>
Fri, 16 Aug 2019 22:16:18 +0000 (17:16 -0500)
src/jexer/TApplication.java
src/jexer/TTerminalWindow.java
src/jexer/TWindow.java
src/jexer/backend/SwingComponent.java

index 8cbce90008643cb622928322cab03ae2741fec35..0f50457a9b66f77ee38f05fff4ffa51da318317f 100644 (file)
@@ -289,6 +289,22 @@ public class TApplication implements Runnable {
      */
     private boolean focusFollowsMouse = false;
 
+    /**
+     * If true, display a text-based mouse cursor.
+     */
+    private boolean textMouse = true;
+
+    /**
+     * If true, hide the mouse after typing a keystroke.
+     */
+    private boolean hideMouseWhenTyping = false;
+
+    /**
+     * If true, the mouse should not be displayed because a keystroke was
+     * typed.
+     */
+    private boolean typingHidMouse = false;
+
     /**
      * The list of commands to run before the next I/O check.
      */
@@ -722,6 +738,19 @@ public class TApplication implements Runnable {
                 );
             }
         }
+
+        // Text block mouse option
+        if (System.getProperty("jexer.textMouse", "true").equals("false")) {
+            textMouse = false;
+        }
+
+        // Hide mouse when typing option
+        if (System.getProperty("jexer.hideMouseWhenTyping",
+                "false").equals("true")) {
+
+            hideMouseWhenTyping = true;
+        }
+
     }
 
     // ------------------------------------------------------------------------
@@ -1086,8 +1115,16 @@ public class TApplication implements Runnable {
 
         // Special application-wide events -----------------------------------
 
+        if (event instanceof TKeypressEvent) {
+            if (hideMouseWhenTyping) {
+                typingHidMouse = true;
+            }
+        }
+
         // Peek at the mouse position
         if (event instanceof TMouseEvent) {
+            typingHidMouse = false;
+
             TMouseEvent mouse = (TMouseEvent) event;
             if ((mouseX != mouse.getX()) || (mouseY != mouse.getY())) {
                 oldMouseX = mouseX;
@@ -1273,6 +1310,8 @@ public class TApplication implements Runnable {
 
         // Peek at the mouse position
         if (event instanceof TMouseEvent) {
+            typingHidMouse = false;
+
             TMouseEvent mouse = (TMouseEvent) event;
             if ((mouseX != mouse.getX()) || (mouseY != mouse.getY())) {
                 oldMouseX = mouseX;
@@ -1789,8 +1828,10 @@ public class TApplication implements Runnable {
                     }
                 }
 
-                // Draw mouse at the new position.
-                invertCell(mouseX, mouseY);
+                if ((textMouse == true) && (typingHidMouse == false)) {
+                    // Draw mouse at the new position.
+                    invertCell(mouseX, mouseY);
+                }
 
                 oldDrawnMouseX = mouseX;
                 oldDrawnMouseY = mouseY;
@@ -1916,7 +1957,9 @@ public class TApplication implements Runnable {
                 getScreen().unsetImageRow(mouseY);
             }
         }
-        invertCell(mouseX, mouseY);
+        if ((textMouse == true) && (typingHidMouse == false)) {
+            invertCell(mouseX, mouseY);
+        }
         oldDrawnMouseX = mouseX;
         oldDrawnMouseY = mouseY;
 
index 4e0123fd7aa383a8d1aeaf4b5e693cb52d10d39d..320c67a087364aac66e4e7c5be6215de7d30224d 100644 (file)
@@ -143,6 +143,17 @@ public class TTerminalWindow extends TScrollableWindow
      */
     private long lastUpdateTime = 0;
 
+    /**
+     * If true, hide the mouse after typing a keystroke.
+     */
+    private boolean hideMouseWhenTyping = true;
+
+    /**
+     * If true, the mouse should not be displayed because a keystroke was
+     * typed.
+     */
+    private boolean typingHidMouse = false;
+
     // ------------------------------------------------------------------------
     // Constructors -----------------------------------------------------------
     // ------------------------------------------------------------------------
@@ -521,6 +532,9 @@ public class TTerminalWindow extends TScrollableWindow
      */
     @Override
     public void onKeypress(final TKeypressEvent keypress) {
+        if (hideMouseWhenTyping) {
+            typingHidMouse = true;
+        }
 
         // Scrollback up/down
         if (keypress.equals(kbShiftPgUp)
@@ -572,6 +586,10 @@ public class TTerminalWindow extends TScrollableWindow
             return;
         }
 
+        if (hideMouseWhenTyping) {
+            typingHidMouse = false;
+        }
+
         // If the emulator is tracking mouse buttons, it needs to see wheel
         // events.
         if (emulator.getMouseProtocol() == ECMA48.MouseProtocol.OFF) {
@@ -609,6 +627,10 @@ public class TTerminalWindow extends TScrollableWindow
             return;
         }
 
+        if (hideMouseWhenTyping) {
+            typingHidMouse = false;
+        }
+
         if (mouseOnEmulator(mouse)) {
             mouse.setX(mouse.getX() - 1);
             mouse.setY(mouse.getY() - 1);
@@ -634,6 +656,10 @@ public class TTerminalWindow extends TScrollableWindow
             return;
         }
 
+        if (hideMouseWhenTyping) {
+            typingHidMouse = false;
+        }
+
         if (mouseOnEmulator(mouse)) {
             mouse.setX(mouse.getX() - 1);
             mouse.setY(mouse.getY() - 1);
@@ -650,6 +676,18 @@ public class TTerminalWindow extends TScrollableWindow
     // TTerminalWindow --------------------------------------------------------
     // ------------------------------------------------------------------------
 
+    /**
+     * Returns true if this window does not want the application-wide mouse
+     * cursor drawn over it.
+     *
+     * @return true if this window does not want the application-wide mouse
+     * cursor drawn over it
+     */
+    @Override
+    public boolean hasHiddenMouse() {
+        return (super.hasHiddenMouse() || typingHidMouse);
+    }
+
     /**
      * Claim the keystrokes the emulator will need.
      */
@@ -785,6 +823,13 @@ public class TTerminalWindow extends TScrollableWindow
         // Pass the correct text cell width/height to the emulator
         emulator.setTextWidth(getScreen().getTextWidth());
         emulator.setTextHeight(getScreen().getTextHeight());
+
+        // Hide mouse when typing option
+        if (System.getProperty("jexer.TTerminal.hideMouseWhenTyping",
+                "true").equals("false")) {
+
+            hideMouseWhenTyping = false;
+        }
     }
 
     /**
index 77bd2b31544fe39f9f5f063a4f15df3ce343d66d..2855209eda870bb5a5bc44c9d2670585f7400d89 100644 (file)
@@ -1384,7 +1384,7 @@ public class TWindow extends TWidget {
      * @return true if this window does not want the application-wide mouse
      * cursor drawn over it
      */
-    public final boolean hasHiddenMouse() {
+    public boolean hasHiddenMouse() {
         return hideMouse;
     }
 
index 23b50ab3b7b9f5e157cdb81ff867aa98ee44e070..57f8fd6b40ee4a508bc907e9d50c4d69510aa853 100644 (file)
@@ -43,6 +43,8 @@ import java.awt.event.MouseWheelListener;
 import java.awt.event.WindowListener;
 import java.awt.image.BufferedImage;
 import java.awt.image.BufferStrategy;
+import java.io.IOException;
+import javax.imageio.ImageIO;
 import javax.swing.JComponent;
 import javax.swing.JFrame;
 import javax.swing.SwingUtilities;
@@ -151,14 +153,26 @@ class SwingComponent {
     public void setupComponent() {
         component.setBackground(Color.black);
 
-        // Kill the X11 cursor
-        // Transparent 16 x 16 pixel cursor image.
-        BufferedImage cursorImg = new BufferedImage(16, 16,
-            BufferedImage.TYPE_INT_ARGB);
-        // Create a new blank cursor.
-        Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(
-        cursorImg, new Point(0, 0), "blank cursor");
-        component.setCursor(blankCursor);
+        if (System.getProperty("jexer.Swing.mouseImage") != null) {
+            component.setCursor(getMouseImage());
+        } else if (System.getProperty("jexer.Swing.mouseStyle") != null) {
+            component.setCursor(getMouseCursor());
+        } else if (System.getProperty("jexer.textMouse",
+                "true").equals("false")
+        ) {
+            // If the user has suppressed the text mouse, don't kill the X11
+            // mouse.
+            component.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+        } else {
+            // Kill the X11 cursor
+            // Transparent 16 x 16 pixel cursor image.
+            BufferedImage cursorImg = new BufferedImage(16, 16,
+                BufferedImage.TYPE_INT_ARGB);
+            // Create a new blank cursor.
+            Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(
+                cursorImg, new Point(0, 0), "blank cursor");
+            component.setCursor(blankCursor);
+        }
 
         // Be capable of seeing Tab / Shift-Tab
         component.setFocusTraversalKeysEnabled(false);
@@ -172,14 +186,26 @@ class SwingComponent {
         frame.setBackground(Color.black);
         frame.pack();
 
-        // Kill the X11 cursor
-        // Transparent 16 x 16 pixel cursor image.
-        BufferedImage cursorImg = new BufferedImage(16, 16,
-            BufferedImage.TYPE_INT_ARGB);
-        // Create a new blank cursor.
-        Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(
-        cursorImg, new Point(0, 0), "blank cursor");
-        frame.setCursor(blankCursor);
+        if (System.getProperty("jexer.Swing.mouseImage") != null) {
+            frame.setCursor(getMouseImage());
+        } else if (System.getProperty("jexer.Swing.mouseStyle") != null) {
+            frame.setCursor(getMouseCursor());
+        } else if (System.getProperty("jexer.textMouse",
+                "true").equals("false")
+        ) {
+            // If the user has suppressed the text mouse, don't kill the X11
+            // mouse.
+            frame.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+        } else {
+            // Kill the X11 cursor
+            // Transparent 16 x 16 pixel cursor image.
+            BufferedImage cursorImg = new BufferedImage(16, 16,
+                BufferedImage.TYPE_INT_ARGB);
+            // Create a new blank cursor.
+            Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(
+                cursorImg, new Point(0, 0), "blank cursor");
+            frame.setCursor(blankCursor);
+        }
 
         // Be capable of seeing Tab / Shift-Tab
         frame.setFocusTraversalKeysEnabled(false);
@@ -191,6 +217,80 @@ class SwingComponent {
         }
     }
 
+    /**
+     * Load an image named in jexer.Swing.mouseImage as the mouse cursor.
+     * The image must be on the classpath.
+     *
+     * @return the cursor
+     */
+    private Cursor getMouseImage() {
+        Cursor cursor = Cursor.getDefaultCursor();
+        String filename = System.getProperty("jexer.Swing.mouseImage");
+        assert (filename != null);
+
+        try {
+            ClassLoader loader = Thread.currentThread().
+                getContextClassLoader();
+
+            java.net.URL url = loader.getResource(filename);
+            if (url == null) {
+                // User named a file, but it's not on the classpath.  Bail
+                // out.
+                return cursor;
+            }
+
+            BufferedImage cursorImage = ImageIO.read(url);
+            java.awt.Dimension cursorSize = Toolkit.getDefaultToolkit().
+                getBestCursorSize(
+                        cursorImage.getWidth(), cursorImage.getHeight());
+
+            cursor = Toolkit.getDefaultToolkit().createCustomCursor(cursorImage,
+                new Point((int) Math.min(cursorImage.getWidth() / 2,
+                        cursorSize.getWidth() - 1),
+                    (int) Math.min(cursorImage.getHeight() / 2,
+                        cursorSize.getHeight() - 1)),
+                "custom cursor");
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return cursor;
+    }
+
+    /**
+     * Get the appropriate mouse cursor based on jexer.Swing.mouseStyle.
+     *
+     * @return the cursor
+     */
+    private Cursor getMouseCursor() {
+        Cursor cursor = Cursor.getDefaultCursor();
+        String style = System.getProperty("jexer.Swing.mouseStyle");
+        assert (style != null);
+
+        style = style.toLowerCase();
+
+        if (style.equals("none")) {
+            // Transparent 16 x 16 pixel cursor image.
+            BufferedImage cursorImg = new BufferedImage(16, 16,
+                BufferedImage.TYPE_INT_ARGB);
+            // Create a new blank cursor.
+            cursor = Toolkit.getDefaultToolkit().createCustomCursor(
+                cursorImg, new Point(0, 0), "blank cursor");
+        } else if (style.equals("default")) {
+            cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
+        } else if (style.equals("hand")) {
+            cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
+        } else if (style.equals("text")) {
+            cursor = Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR);
+        } else if (style.equals("move")) {
+            cursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);
+        } else if (style.equals("crosshair")) {
+            cursor = Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);
+        }
+
+        return cursor;
+    }
+
     /**
      * Set the window title.
      *