#35 CJK WIP
[fanfix.git] / src / jexer / TApplication.java
index 2537c3e4b5bbdfddb0d05837000bd6effea21a48..4428d29f79d64bb5183926330f3c115fb2b924da 100644 (file)
@@ -283,11 +283,6 @@ public class TApplication implements Runnable {
      */
     private boolean focusFollowsMouse = false;
 
-    /**
-     * The images that might be displayed.  Note package private access.
-     */
-    private List<TImage> images;
-
     /**
      * The list of commands to run before the next I/O check.
      */
@@ -606,7 +601,6 @@ public class TApplication implements Runnable {
         accelerators    = new HashMap<TKeypress, TMenuItem>();
         menuItems       = new LinkedList<TMenuItem>();
         desktop         = new TDesktop(this);
-        images          = new LinkedList<TImage>();
 
         // Special case: the Swing backend needs to have a timer to drive its
         // blink state.
@@ -1489,7 +1483,7 @@ public class TApplication implements Runnable {
         String version = getClass().getPackage().getImplementationVersion();
         if (version == null) {
             // This is Java 9+, use a hardcoded string here.
-            version = "0.3.1";
+            version = "0.3.2";
         }
         messageBox(i18n.getString("aboutDialogTitle"),
             MessageFormat.format(i18n.getString("aboutDialogText"), version),
@@ -1540,6 +1534,19 @@ public class TApplication implements Runnable {
      * @param y row position
      */
     private void invertCell(final int x, final int y) {
+        invertCell(x, y, false);
+    }
+
+    /**
+     * Invert the cell color at a position.  This is used to track the mouse.
+     *
+     * @param x column position
+     * @param y row position
+     * @param onlyThisCell if true, only invert this cell
+     */
+    private void invertCell(final int x, final int y,
+        final boolean onlyThisCell) {
+
         if (debugThreads) {
             System.err.printf("%d %s invertCell() %d %d\n",
                 System.currentTimeMillis(), Thread.currentThread(), x, y);
@@ -1579,6 +1586,29 @@ public class TApplication implements Runnable {
             }
         }
         getScreen().putCharXY(x, y, cell);
+        if ((onlyThisCell == true) || (cell.getWidth() == Cell.Width.SINGLE)) {
+            return;
+        }
+
+        // This cell is one half of a fullwidth glyph.  Invert the other
+        // half.
+        if (cell.getWidth() == Cell.Width.LEFT) {
+            if (x < getScreen().getWidth() - 1) {
+                Cell rightHalf = getScreen().getCharXY(x + 1, y);
+                if (rightHalf.getWidth() == Cell.Width.RIGHT) {
+                    invertCell(x + 1, y, true);
+                    return;
+                }
+            }
+        }
+        assert (cell.getWidth() == Cell.Width.RIGHT);
+
+        if (x > 0) {
+            Cell leftHalf = getScreen().getCharXY(x - 1, y);
+            if (leftHalf.getWidth() == Cell.Width.LEFT) {
+                invertCell(x - 1, y, true);
+            }
+        }
     }
 
     /**
@@ -1617,7 +1647,7 @@ public class TApplication implements Runnable {
                 getScreen().putCharXY(oldDrawnMouseX, oldDrawnMouseY,
                     oldDrawnMouseCell);
                 oldDrawnMouseCell = getScreen().getCharXY(mouseX, mouseY);
-                if ((images.size() > 0) && (backend instanceof ECMA48Backend)) {
+                if (backend instanceof ECMA48Backend) {
                     // Special case: the entire row containing the mouse has
                     // to be re-drawn if it has any image data, AND any rows
                     // in between.
@@ -1644,7 +1674,7 @@ public class TApplication implements Runnable {
                 oldDrawnMouseX = mouseX;
                 oldDrawnMouseY = mouseY;
             }
-            if ((images.size() > 0) || getScreen().isDirty()) {
+            if (getScreen().isDirty()) {
                 backend.flushScreen();
             }
             return;
@@ -1746,7 +1776,7 @@ public class TApplication implements Runnable {
                 oldDrawnMouseX, oldDrawnMouseY);
         }
         oldDrawnMouseCell = getScreen().getCharXY(mouseX, mouseY);
-        if ((images.size() > 0) && (backend instanceof ECMA48Backend)) {
+        if (backend instanceof ECMA48Backend) {
             // Special case: the entire row containing the mouse has to be
             // re-drawn if it has any image data, AND any rows in between.
             if (oldDrawnMouseY != mouseY) {
@@ -1797,7 +1827,7 @@ public class TApplication implements Runnable {
         }
 
         // Flush the screen contents
-        if ((images.size() > 0) || getScreen().isDirty()) {
+        if (getScreen().isDirty()) {
             if (debugThreads) {
                 System.err.printf("%d %s backend.flushScreen()\n",
                     System.currentTimeMillis(), Thread.currentThread());
@@ -2529,46 +2559,6 @@ public class TApplication implements Runnable {
         window.setY(windowY);
     }
 
-    // ------------------------------------------------------------------------
-    // TImage management ------------------------------------------------------
-    // ------------------------------------------------------------------------
-
-    /**
-     * Add an image to the list.  Note package private access.
-     *
-     * @param image the image to add
-     * @throws IllegalArgumentException if the image is already used in
-     * another TApplication
-     */
-    final void addImage(final TImage image) {
-        if ((image.getApplication() != null)
-            && (image.getApplication() != this)
-        ) {
-            throw new IllegalArgumentException("Image " + image +
-                " is already " + "part of application " +
-                image.getApplication());
-        }
-        images.add(image);
-    }
-
-    /**
-     * Remove an image from the list.  Note package private access.
-     *
-     * @param image the image to remove
-     * @throws IllegalArgumentException if the image is already used in
-     * another TApplication
-     */
-    final void removeImage(final TImage image) {
-        if ((image.getApplication() != null)
-            && (image.getApplication() != this)
-        ) {
-            throw new IllegalArgumentException("Image " + image +
-                " is already " + "part of application " +
-                image.getApplication());
-        }
-        images.remove(image);
-    }
-
     // ------------------------------------------------------------------------
     // TMenu management -------------------------------------------------------
     // ------------------------------------------------------------------------
@@ -3157,6 +3147,7 @@ public class TApplication implements Runnable {
         columnMenu.addDefaultItem(TMenu.MID_TABLE_COLUMN_WIDEN, false);
         TSubMenu fileMenu = tableMenu.addSubMenu(i18n.
             getString("tableSubMenuFile"));
+        fileMenu.addDefaultItem(TMenu.MID_TABLE_FILE_OPEN_CSV, false);
         fileMenu.addDefaultItem(TMenu.MID_TABLE_FILE_SAVE_CSV, false);
         fileMenu.addDefaultItem(TMenu.MID_TABLE_FILE_SAVE_TEXT, false);