X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2FTSplitPane.java;h=7c85278f88d0d6df3ff34f01064e2be57d25481d;hb=12b90437b5f22c2ae6e9b9b14c3b62b60f6143e5;hp=796a04a8d12c6854f1a0a6607661f4a4093472ec;hpb=0b5d7658ba514e13c257dbac51a4c86e47f79230;p=nikiroo-utils.git diff --git a/src/jexer/TSplitPane.java b/src/jexer/TSplitPane.java index 796a04a..7c85278 100644 --- a/src/jexer/TSplitPane.java +++ b/src/jexer/TSplitPane.java @@ -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 ------------------------------------------------------------- // ------------------------------------------------------------------------ @@ -275,7 +298,9 @@ public class TSplitPane extends TWidget { "horizontal split pane"); } if (left == null) { - remove(this.left); + if (this.left != null) { + remove(this.left); + } this.left = null; return; } @@ -305,7 +330,9 @@ public class TSplitPane extends TWidget { "horizontal split pane"); } if (right == null) { - remove(this.right); + if (this.right != null) { + remove(this.right); + } this.right = null; return; } @@ -335,7 +362,9 @@ public class TSplitPane extends TWidget { "split pane"); } if (top == null) { - remove(this.top); + if (this.top != null) { + remove(this.top); + } this.top = null; return; } @@ -365,7 +394,9 @@ public class TSplitPane extends TWidget { "vertical split pane"); } if (bottom == null) { - remove(this.bottom); + if (this.bottom != null) { + remove(this.bottom); + } this.bottom = null; return; } @@ -375,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. */ @@ -418,4 +535,68 @@ public class TSplitPane extends TWidget { layoutChildren(); } + /** + * Remove this split, removing the widget specified. + * + * @param widgetToRemove the widget to remove + * @param doClose if true, call the close() method before removing the + * child + * @return the pane that remains, or null if nothing is retained + */ + public TWidget removeSplit(final TWidget widgetToRemove, + final boolean doClose) { + + TWidget keep = null; + if (vertical) { + if ((widgetToRemove != left) && (widgetToRemove != right)) { + throw new IllegalArgumentException("widget to remove is not " + + "either of the panes in this splitpane"); + } + if (widgetToRemove == left) { + keep = right; + } else { + keep = left; + } + + } else { + if ((widgetToRemove != top) && (widgetToRemove != bottom)) { + throw new IllegalArgumentException("widget to remove is not " + + "either of the panes in this splitpane"); + } + if (widgetToRemove == top) { + keep = bottom; + } else { + keep = top; + } + } + + // Remove me from my parent widget. + 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; + } + + 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; + } + }