X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2FTSplitPane.java;h=b308e9b79162a57aea99d55bad2a77f22e951eb3;hb=HEAD;hp=277f080e22af099cf0bb576eb09dd4637027e4c2;hpb=469c2b3cf74f88072a9a1e5758379f24b14f469e;p=fanfix.git diff --git a/src/jexer/TSplitPane.java b/src/jexer/TSplitPane.java index 277f080..b308e9b 100644 --- a/src/jexer/TSplitPane.java +++ b/src/jexer/TSplitPane.java @@ -30,10 +30,8 @@ package jexer; import jexer.bits.CellAttributes; import jexer.bits.GraphicsChars; -import jexer.event.TMenuEvent; import jexer.event.TMouseEvent; import jexer.event.TResizeEvent; -import jexer.menu.TMenu; /** * TSplitPane contains two widgets with a draggable horizontal or vertical @@ -147,9 +145,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 +197,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(); @@ -225,7 +223,28 @@ public class TSplitPane extends TWidget { CellAttributes attr = getTheme().getColor("tsplitpane"); if (vertical) { vLineXY(split, 0, getHeight(), GraphicsChars.WINDOW_SIDE, attr); - // TODO: draw intersections of children + + // Draw intersections of children + if ((left instanceof TSplitPane) + && (((TSplitPane) left).vertical == false) + && (right instanceof TSplitPane) + && (((TSplitPane) right).vertical == false) + && (((TSplitPane) left).split == ((TSplitPane) right).split) + ) { + putCharXY(split, ((TSplitPane) left).split, '\u253C', attr); + } else { + if ((left instanceof TSplitPane) + && (((TSplitPane) left).vertical == false) + ) { + putCharXY(split, ((TSplitPane) left).split, '\u2524', attr); + } + if ((right instanceof TSplitPane) + && (((TSplitPane) right).vertical == false) + ) { + putCharXY(split, ((TSplitPane) right).split, '\u251C', + attr); + } + } if ((mouse != null) && (mouse.getAbsoluteX() == getAbsoluteX() + split) @@ -237,7 +256,28 @@ public class TSplitPane extends TWidget { } } else { hLineXY(0, split, getWidth(), GraphicsChars.SINGLE_BAR, attr); - // TODO: draw intersections of children + + // Draw intersections of children + if ((top instanceof TSplitPane) + && (((TSplitPane) top).vertical == true) + && (bottom instanceof TSplitPane) + && (((TSplitPane) bottom).vertical == true) + && (((TSplitPane) top).split == ((TSplitPane) bottom).split) + ) { + putCharXY(((TSplitPane) top).split, split, '\u253C', attr); + } else { + if ((top instanceof TSplitPane) + && (((TSplitPane) top).vertical == true) + ) { + putCharXY(((TSplitPane) top).split, split, '\u2534', attr); + } + if ((bottom instanceof TSplitPane) + && (((TSplitPane) bottom).vertical == true) + ) { + putCharXY(((TSplitPane) bottom).split, split, '\u252C', + attr); + } + } if ((mouse != null) && (mouse.getAbsoluteY() == getAbsoluteY() + split) @@ -251,6 +291,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 +338,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 +370,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 +402,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 +434,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 +446,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. */ @@ -454,18 +611,30 @@ public class TSplitPane extends TWidget { } // Remove me from my parent widget. - TWidget newParent = getParent(); - setParent(null, false); + 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; }