package com.googlecode.lanterna.gui2;
import com.googlecode.lanterna.*;
import com.googlecode.lanterna.graphics.*;
import com.googlecode.lanterna.input.*;
import java.util.*;
public class SplitPanel extends Panel {
private final Component compA;
private final ImageComponent thumb;
private final Component compB;
private boolean isHorizontal;
private double ratio = 0.5;
public static SplitPanel ofHorizontal(Component left, Component right) {
SplitPanel split = new SplitPanel(left, right, true);
return split;
}
public static SplitPanel ofVertical(Component top, Component bottom) {
SplitPanel split = new SplitPanel(top, bottom, false);
return split;
}
protected SplitPanel(Component a, Component b, boolean isHorizontal) {
this.compA = a;
this.compB = b;
this.isHorizontal = isHorizontal;
thumb = makeThumb();
setLayoutManager(new ScrollPanelLayoutManager());
setRatio(10, 10);
addComponent(a);
addComponent(thumb);
addComponent(b);
}
ImageComponent makeThumb() {
ImageComponent imageComponent = new ImageComponent() {
TerminalSize aSize;
TerminalSize bSize;
TerminalSize tSize;
TerminalPosition down = null;
TerminalPosition drag = null;
@Override
public Result handleKeyStroke(KeyStroke keyStroke) {
if (!(keyStroke instanceof MouseAction)) {
return Result.UNHANDLED;
}
MouseAction mouse = (MouseAction)keyStroke;
if (mouse.isMouseDown()) {
aSize = compA.getSize();
bSize = compB.getSize();
tSize = thumb.getSize();
down = mouse.getPosition();
}
if (mouse.isMouseDrag()) {
drag = mouse.getPosition();
if (down == null) {
down = drag;
}
int delta = isHorizontal ? drag.minus(down).getColumn() : drag.minus(down).getRow();
if (isHorizontal) {
int a = Math.max(1, tSize.getColumns() + aSize.getColumns() + delta);
int b = Math.max(1, bSize.getColumns() - delta);
setRatio(a, b);
} else {
int a = Math.max(1, tSize.getRows() + aSize.getRows() + delta);
int b = Math.max(1, bSize.getRows() - delta);
setRatio(a, b);
}
}
if (mouse.isMouseUp()) {
down = null;
drag = null;
}
return Result.HANDLED;
}
};
return imageComponent;
}
class ScrollPanelLayoutManager implements LayoutManager {
public ScrollPanelLayoutManager() {
}
@Override
public TerminalSize getPreferredSize(List<Component> components) {
TerminalSize sizeA = compA.getPreferredSize();
int aWidth = sizeA.getColumns();
int aHeight = sizeA.getRows();
TerminalSize sizeB = compB.getPreferredSize();
int bWidth = sizeB.getColumns();
int bHeight = sizeB.getRows();
int tWidth = thumb.getPreferredSize().getColumns();
int tHeight = thumb.getPreferredSize().getRows();
if (isHorizontal) {
TerminalSize result = new TerminalSize(aWidth + tWidth + bWidth, Math.max(aHeight, Math.max(tHeight, bHeight)));
return result;
} else {
TerminalSize result = new TerminalSize(Math.max(aWidth, Math.max(tWidth, bWidth)), aHeight + tHeight + bHeight);
return result;
}
}
@Override
public void doLayout(TerminalSize area, List<Component> components) {
TerminalSize size = getSize();
int length = isHorizontal ? size.getRows() : size.getColumns();
TerminalSize tsize = new TerminalSize(isHorizontal ? 1 : length, !isHorizontal ? 1 : length);
TextImage textImage = new BasicTextImage(tsize);
Theme theme = getTheme();
ThemeDefinition themeDefinition = theme.getDefaultDefinition();
ThemeStyle themeStyle = themeDefinition.getNormal();
textImage.setAll(new TextCharacter(isHorizontal ? Symbols.SINGLE_LINE_VERTICAL : Symbols.SINGLE_LINE_HORIZONTAL, themeStyle.getForeground(), themeStyle.getBackground()));
thumb.setTextImage(textImage);
int tWidth = thumb.getPreferredSize().getColumns();
int tHeight = thumb.getPreferredSize().getRows();
int w = size.getColumns();
int h = size.getRows();
if (isHorizontal) {
w -= tWidth;
} else {
h -= tHeight;
}
if (isHorizontal) {
int leftWidth = Math.max(0, (int)(w * ratio));
int leftHeight = Math.max(0, Math.min(compA.getPreferredSize().getRows(), h));
int rightWidth = Math.max(0, w - leftWidth);
int rightHeight = Math.max(0, Math.min(compB.getPreferredSize().getRows(), h));
compA.setSize(new TerminalSize(leftWidth, leftHeight));
thumb.setSize(thumb.getPreferredSize());
compB.setSize(new TerminalSize(rightWidth, rightHeight));
compA.setPosition(new TerminalPosition(0,0));
thumb.setPosition(new TerminalPosition(leftWidth, h/2 - tHeight/2));
compB.setPosition(new TerminalPosition(leftWidth + tWidth, 0));
} else {
int leftWidth = Math.max(0, Math.min(compA.getPreferredSize().getColumns(), w));
int leftHeight = Math.max(0, (int)(h * ratio));
int rightWidth = Math.max(0, Math.min(compB.getPreferredSize().getColumns(), w));
int rightHeight = Math.max(0, h - leftHeight);
compA.setSize(new TerminalSize(leftWidth, leftHeight));
thumb.setSize(thumb.getPreferredSize());
compB.setSize(new TerminalSize(rightWidth, rightHeight));
compA.setPosition(new TerminalPosition(0,0));
thumb.setPosition(new TerminalPosition(w/2 - tWidth/2, leftHeight));
compB.setPosition(new TerminalPosition(0, leftHeight + tHeight));
}
}
@Override
public boolean hasChanged() {
return true;
}
}
public void setRatio(int left, int right) {
if (left == 0 || right == 0) {
ratio = 0.5;
}
int total = Math.abs(left) + Math.abs(right);
ratio = (double)left / (double)total;
}
}