#19 TField fixes
authorKevin Lamonte <kevin.lamonte@gmail.com>
Thu, 17 Aug 2017 15:10:47 +0000 (11:10 -0400)
committerKevin Lamonte <kevin.lamonte@gmail.com>
Thu, 17 Aug 2017 15:10:47 +0000 (11:10 -0400)
src/jexer/TField.java
src/jexer/TWidget.java
src/jexer/backend/LogicalScreen.java
src/jexer/demos/DemoTextFieldWindow.java

index fbe726bc04ca2f1d68a38155569890a2780166e3..785a276d2fc7531012b213a45fff05140bfda672 100644 (file)
@@ -218,7 +218,8 @@ public class TField extends TWidget {
     }
 
     /**
-     * Update the cursor position.
+     * Update the visible cursor position to match the location of position
+     * and windowStart.
      */
     protected void updateCursor() {
         if ((position > getWidth()) && fixed) {
@@ -230,6 +231,23 @@ public class TField extends TWidget {
         }
     }
 
+    /**
+     * Normalize windowStart such that most of the field data if visible.
+     */
+    protected void normalizeWindowStart() {
+        if (fixed) {
+            // windowStart had better be zero, there is nothing to do here.
+            assert (windowStart == 0);
+            return;
+        }
+        windowStart = position - (getWidth() - 1);
+        if (windowStart < 0) {
+            windowStart = 0;
+        }
+
+        updateCursor();
+    }
+
     /**
      * Handle mouse button presses.
      *
@@ -268,6 +286,7 @@ public class TField extends TWidget {
                     windowStart--;
                 }
             }
+            normalizeWindowStart();
             return;
         }
 
@@ -322,6 +341,7 @@ public class TField extends TWidget {
                 text = text.substring(0, position)
                         + text.substring(position + 1);
             }
+            dispatch(false);
             return;
         }
 
@@ -339,6 +359,7 @@ public class TField extends TWidget {
                 }
             }
             dispatch(false);
+            normalizeWindowStart();
             return;
         }
 
index d292ec1490c938f304e142a565551d8eb6060e74..22766dde5aa281212c320182fbad09f76c9978f6 100644 (file)
@@ -302,6 +302,25 @@ public abstract class TWidget implements Comparable<TWidget> {
      * @return if true, this widget has a visible cursor
      */
     public final boolean isCursorVisible() {
+        // If cursor is out of my bounds, it is not visible.
+        if ((cursorX >= width)
+            || (cursorX < 0)
+            || (cursorY >= height)
+            || (cursorY < 0)
+        ) {
+            return false;
+        }
+
+        // If cursor is out of my window's bounds, it is not visible.
+        if ((getCursorAbsoluteX() >= window.getAbsoluteX()
+                + window.getWidth() - 1)
+            || (getCursorAbsoluteX() < 0)
+            || (getCursorAbsoluteY() >= window.getAbsoluteY()
+                + window.getHeight() - 1)
+            || (getCursorAbsoluteY() < 0)
+        ) {
+            return false;
+        }
         return cursorVisible;
     }
 
index 4e7971eaf71fce92b4fa61e32e6d3288ef05aaa4..c9b025abb257cb260f1ecff0f62a97e792d4caef 100644 (file)
@@ -293,6 +293,16 @@ public class LogicalScreen implements Screen {
 
         if ((X >= 0) && (X < width) && (Y >= 0) && (Y < height)) {
             logical[X][Y].setTo(attr);
+
+            // If this happens to be the cursor position, make the position
+            // dirty.
+            if ((cursorX == X) && (cursorY == Y)) {
+                if (physical[cursorX][cursorY].getChar() == 'Q') {
+                    physical[cursorX][cursorY].setChar('X');
+                } else {
+                    physical[cursorX][cursorY].setChar('Q');
+                }
+            }
         }
     }
 
@@ -354,6 +364,16 @@ public class LogicalScreen implements Screen {
 
             logical[X][Y].setTo(attr);
             logical[X][Y].setChar(ch);
+
+            // If this happens to be the cursor position, make the position
+            // dirty.
+            if ((cursorX == X) && (cursorY == Y)) {
+                if (physical[cursorX][cursorY].getChar() == 'Q') {
+                    physical[cursorX][cursorY].setChar('X');
+                } else {
+                    physical[cursorX][cursorY].setChar('Q');
+                }
+            }
         }
     }
 
@@ -381,6 +401,16 @@ public class LogicalScreen implements Screen {
 
         if ((X >= 0) && (X < width) && (Y >= 0) && (Y < height)) {
             logical[X][Y].setChar(ch);
+
+            // If this happens to be the cursor position, make the position
+            // dirty.
+            if ((cursorX == X) && (cursorY == Y)) {
+                if (physical[cursorX][cursorY].getChar() == 'Q') {
+                    physical[cursorX][cursorY].setChar('X');
+                } else {
+                    physical[cursorX][cursorY].setChar('Q');
+                }
+            }
         }
     }
 
index fcdf4615cefe4fccf0b63d49d02fceac26374a5c..51656ba7f4e964bbb61ff4af365eeaba67d7d7b5 100644 (file)
@@ -67,6 +67,9 @@ public class DemoTextFieldWindow extends TWindow {
         addPasswordField(35, row++, 15, false);
         addLabel("Fixed-width password:", 1, row);
         addPasswordField(35, row++, 15, true, "hunter2");
+        addLabel("Very long text field:", 1, row);
+        TField selected = addField(35, row++, 40, false,
+            "Very very long field text that should be outside the window");
         row += 1;
 
         addButton("&Close Window", (getWidth() - 14) / 2, getHeight() - 4,
@@ -77,6 +80,8 @@ public class DemoTextFieldWindow extends TWindow {
             }
         );
 
+        activate(selected);
+
         statusBar = newStatusBar("Text fields");
         statusBar.addShortcutKeypress(kbF1, cmHelp, "Help");
         statusBar.addShortcutKeypress(kbF2, cmShell, "Shell");