Add 'src/jexer/' from commit 'cf01c92f5809a0732409e280fb0f32f27393618d'
[fanfix.git] / src / jexer / TSplitPane.java
index b63ea1fbd06fd8805b3c7e3e27d654f59a3dfaf3..7c85278f88d0d6df3ff34f01064e2be57d25481d 100644 (file)
@@ -147,9 +147,9 @@ public class TSplitPane extends TWidget {
 
         if (mouse.isMouse1()) {
             if (vertical) {
-                inSplitMove = (mouse.getX() == split);
+                inSplitMove = (mouse.getAbsoluteX() - getAbsoluteX() == split);
             } else {
-                inSplitMove = (mouse.getY() == split);
+                inSplitMove = (mouse.getAbsoluteY() - getAbsoluteY() == split);
             }
             if (inSplitMove) {
                 return;
@@ -199,10 +199,10 @@ public class TSplitPane extends TWidget {
 
         if (inSplitMove) {
             if (vertical) {
-                split = mouse.getX();
+                split = mouse.getAbsoluteX() - getAbsoluteX();
                 split = Math.min(Math.max(1, split), getWidth() - 2);
             } else {
-                split = mouse.getY();
+                split = mouse.getAbsoluteY() - getAbsoluteY();
                 split = Math.min(Math.max(1, split), getHeight() - 2);
             }
             layoutChildren();
@@ -251,6 +251,29 @@ public class TSplitPane extends TWidget {
 
     }
 
+    /**
+     * Generate a human-readable string for this widget.
+     *
+     * @return a human-readable string
+     */
+    @Override
+    public String toString() {
+        return String.format("%s(%8x) %s position (%d, %d) geometry %dx%d " +
+            "split %d left %s(%8x) right %s(%8x) top %s(%8x) bottom %s(%8x) " +
+            "active %s enabled %s visible %s", getClass().getName(),
+            hashCode(), (vertical ? "VERTICAL" : "HORIZONTAL"),
+            getX(), getY(), getWidth(), getHeight(), split,
+            (left == null ? "null" : left.getClass().getName()),
+            (left == null ? 0 : left.hashCode()),
+            (right == null ? "null" : right.getClass().getName()),
+            (right == null ? 0 : right.hashCode()),
+            (top == null ? "null" : top.getClass().getName()),
+            (top == null ? 0 : top.hashCode()),
+            (bottom == null ? "null" : bottom.getClass().getName()),
+            (bottom == null ? 0 : bottom.hashCode()),
+            isActive(), isEnabled(), isVisible());
+    }
+
     // ------------------------------------------------------------------------
     // TSplitPane -------------------------------------------------------------
     // ------------------------------------------------------------------------
@@ -383,6 +406,92 @@ public class TSplitPane extends TWidget {
                 getHeight()));
     }
 
+    /**
+     * Remove a widget, regardless of what pane it is on.
+     *
+     * @param widget the widget to remove
+     */
+    public void removeWidget(final TWidget widget) {
+        if (widget == null) {
+            throw new IllegalArgumentException("cannot remove null widget");
+        }
+        if (left == widget) {
+            left = null;
+            assert(right != widget);
+            assert(top != widget);
+            assert(bottom != widget);
+            return;
+        }
+        if (right == widget) {
+            right = null;
+            assert(left != widget);
+            assert(top != widget);
+            assert(bottom != widget);
+            return;
+        }
+        if (top == widget) {
+            top = null;
+            assert(left != widget);
+            assert(right != widget);
+            assert(bottom != widget);
+            return;
+        }
+        if (bottom == widget) {
+            bottom = null;
+            assert(left != widget);
+            assert(right != widget);
+            assert(top != widget);
+            return;
+        }
+        throw new IllegalArgumentException("widget " + widget +
+            " not in this split");
+    }
+
+    /**
+     * Replace a widget, regardless of what pane it is on, with another
+     * widget.
+     *
+     * @param oldWidget the widget to remove
+     * @param newWidget the widget to replace it with
+     */
+    public void replaceWidget(final TWidget oldWidget,
+        final TWidget newWidget) {
+
+        if (oldWidget == null) {
+            throw new IllegalArgumentException("cannot remove null oldWidget");
+        }
+        if (left == oldWidget) {
+            setLeft(newWidget);
+            assert(right != newWidget);
+            assert(top != newWidget);
+            assert(bottom != newWidget);
+            return;
+        }
+        if (right == oldWidget) {
+            setRight(newWidget);
+            assert(left != newWidget);
+            assert(top != newWidget);
+            assert(bottom != newWidget);
+            return;
+        }
+        if (top == oldWidget) {
+            setTop(newWidget);
+            assert(left != newWidget);
+            assert(right != newWidget);
+            assert(bottom != newWidget);
+            return;
+        }
+        if (bottom == oldWidget) {
+            setBottom(newWidget);
+            assert(left != newWidget);
+            assert(right != newWidget);
+            assert(top != newWidget);
+            return;
+        }
+        throw new IllegalArgumentException("oldWidget " + oldWidget +
+            " not in this split");
+    }
+
     /**
      * Layout the two child widgets.
      */
@@ -462,19 +571,31 @@ public class TSplitPane extends TWidget {
         }
 
         // Remove me from my parent widget.
-        TWidget newParent = getParent();
+        TWidget myParent = getParent();
         remove(false);
 
         if (keep == null) {
+            if (myParent instanceof TSplitPane) {
+                // TSplitPane has a left/right/top/bottom link to me
+                // somewhere, remove it.
+                ((TSplitPane) myParent).removeWidget(this);
+            }
+
             // Nothing is left of either pane.  Remove me and bail out.
             return null;
         }
 
-        keep.setParent(newParent, false);
-        keep.setDimensions(getX(), getY(), getWidth(), getHeight());
-        keep.onResize(new TResizeEvent(TResizeEvent.Type.WIDGET, getWidth(),
-                getHeight()));
-
+        if (myParent instanceof TSplitPane) {
+            // TSplitPane has a left/right/top/bottom link to me
+            // somewhere, replace me with keep.
+            ((TSplitPane) myParent).replaceWidget(this, keep);
+        } else {
+            keep.setParent(myParent, false);
+            keep.setDimensions(getX(), getY(), getWidth(), getHeight());
+            keep.onResize(new TResizeEvent(TResizeEvent.Type.WIDGET, getWidth(),
+                    getHeight()));
+        }
+        
         return keep;
     }