Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
189 changes: 127 additions & 62 deletions src/main/java/com/googlecode/lanterna/gui2/SplitPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,20 @@
*/
package com.googlecode.lanterna.gui2;

import com.googlecode.lanterna.*;
import com.googlecode.lanterna.graphics.*;
import com.googlecode.lanterna.input.*;

import java.util.*;
import java.util.List;

import com.googlecode.lanterna.SGR;
import com.googlecode.lanterna.Symbols;
import com.googlecode.lanterna.TerminalPosition;
import com.googlecode.lanterna.TerminalSize;
import com.googlecode.lanterna.TextCharacter;
import com.googlecode.lanterna.graphics.BasicTextImage;
import com.googlecode.lanterna.graphics.TextImage;
import com.googlecode.lanterna.graphics.Theme;
import com.googlecode.lanterna.graphics.ThemeDefinition;
import com.googlecode.lanterna.graphics.ThemeStyle;
import com.googlecode.lanterna.input.KeyStroke;
import com.googlecode.lanterna.input.MouseAction;

/**
* @author ginkoblongata
Expand Down Expand Up @@ -71,54 +80,113 @@ ImageComponent makeThumb() {
TerminalPosition drag = null;

@Override
public Result handleKeyStroke(KeyStroke keyStroke) {
Result result;
if (keyStroke instanceof MouseAction) {
result = handleMouseAction((MouseAction) keyStroke);
}
// TODO: Implement keyboard based resizing
else {
result = super.handleKeyStroke(keyStroke);
}
return result;
}

private Result handleMouseAction(MouseAction mouseAction) {
if (mouseAction.isMouseDown()) {
aSize = compA.getSize();
bSize = compB.getSize();
tSize = thumb.getSize();
down = mouseAction.getPosition();
}
if (mouseAction.isMouseDrag()) {
drag = mouseAction.getPosition();

// xxxxxxxxxxxxxxxxxxxxx
// this is a hack, should not be needed if the pane drag
// only on mouse down'd comp stuff was completely working
if (down == null) {
down = drag;
public Result handleKeyStroke(KeyStroke keyStroke)
{
Result result = null;
switch(keyStroke.getKeyType())
{
case ARROW_UP:
if(!isHorizontal) {
aSize = compA.getSize();
bSize = compB.getSize();
tSize = thumb.getSize();

resize(-1);
result = Result.HANDLED;
}
else result = Result.MOVE_FOCUS_UP;
break;

case ARROW_DOWN:
if(!isHorizontal) {
aSize = compA.getSize();
bSize = compB.getSize();
tSize = thumb.getSize();
resize(1);
result = Result.HANDLED;
}
else result = Result.MOVE_FOCUS_DOWN;
break;

case ARROW_LEFT:
if(isHorizontal) {
aSize = compA.getSize();
bSize = compB.getSize();
tSize = thumb.getSize();
resize(-1);
result = Result.HANDLED;
}
// xxxxxxxxxxxxxxxxxxxxx

int delta = isHorizontal ? drag.minus(down).getColumn() : drag.minus(down).getRow();
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
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);
else result = Result.MOVE_FOCUS_LEFT;
break;

case ARROW_RIGHT:
if(isHorizontal) {
aSize = compA.getSize();
bSize = compB.getSize();
tSize = thumb.getSize();
resize(1);
result = Result.HANDLED;
}
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
}
if (mouseAction.isMouseUp()) {
down = null;
drag = null;
}
return Result.HANDLED;
else result = Result.MOVE_FOCUS_LEFT;
break;

case MOUSE_EVENT:
if (!isFocused()) {
return super.handleKeyStroke(keyStroke);
}

MouseAction action = (MouseAction)keyStroke;
if (action.isMouseDown()) {
aSize = compA.getSize();
bSize = compB.getSize();
tSize = thumb.getSize();
down = action.getPosition();
}

if (action.isMouseDrag()) {
drag = action.getPosition();

// xxxxxxxxxxxxxxxxxxxxx
// this is a hack, should not be needed if the pane drag
// only on mouse down'd comp stuff was completely working
if (down == null) {
down = drag;
}
// xxxxxxxxxxxxxxxxxxxxx

int delta = isHorizontal ? drag.minus(down).getColumn() : drag.minus(down).getRow();
resize(delta);
}

if (action.isMouseUp()) {
down = null;
drag = null;
}

result = Result.HANDLED;
break;

default: result = super.handleKeyStroke(keyStroke);
}

return result;
}

private void resize(int delta)
{
if (tSize == null || aSize == null || bSize == null) return;

// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
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);
}
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
}
};
return imageComponent;
Expand All @@ -132,7 +200,6 @@ public ScrollPanelLayoutManager() {
hasChanged = true;
}


@Override
public TerminalSize getPreferredSize(List<Component> components) {
TerminalSize sizeA = compA.getPreferredSize();
Expand All @@ -154,11 +221,8 @@ public TerminalSize getPreferredSize(List<Component> components) {

@Override
public void doLayout(TerminalSize area, List<Component> components) {
TerminalSize size = getSize();

// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// TODO: themed
int length = isHorizontal ? size.getRows() : size.getColumns();
int length = isHorizontal ? area.getRows() : area.getColumns();
TerminalSize tsize = new TerminalSize(isHorizontal ? 1 : length, !isHorizontal ? 1 : length);
TextImage textImage = new BasicTextImage(tsize);
Theme theme = getTheme();
Expand All @@ -180,8 +244,8 @@ public void doLayout(TerminalSize area, List<Component> components) {
int tWidth = thumb.getPreferredSize().getColumns();
int tHeight = thumb.getPreferredSize().getRows();

int w = size.getColumns();
int h = size.getRows();
int w = area.getColumns();
int h = area.getRows();

if (isHorizontal) {
w -= tWidth;
Expand All @@ -198,10 +262,10 @@ public void doLayout(TerminalSize area, List<Component> components) {

if (isHorizontal) {
int leftWidth = Math.max(0, (int) (w * ratio));
int leftHeight = Math.max(0, Math.min(compA.getPreferredSize().getRows(), h));
int leftHeight = Math.max(0, h);

int rightWidth = Math.max(0, w - leftWidth);
int rightHeight = Math.max(0, Math.min(compB.getPreferredSize().getRows(), h));
int rightHeight = Math.max(0, h);

compA.setSize(new TerminalSize(leftWidth, leftHeight));
thumb.setSize(thumb.getPreferredSize());
Expand All @@ -211,10 +275,10 @@ public void doLayout(TerminalSize area, List<Component> components) {
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 leftWidth = Math.max(0, w);
int leftHeight = Math.max(0, (int) (h * ratio));

int rightWidth = Math.max(0, Math.min(compB.getPreferredSize().getColumns(), w));
int rightWidth = Math.max(0, w);
int rightHeight = Math.max(0, h - leftHeight);

compA.setSize(new TerminalSize(leftWidth, leftHeight));
Expand Down Expand Up @@ -253,6 +317,7 @@ public void setRatio(int left, int right) {
int total = Math.abs(left) + Math.abs(right);
ratio = (double) left / (double) total;
}
invalidate();
}

public void setThumbVisible(boolean visible) {
Expand Down
41 changes: 36 additions & 5 deletions src/test/java/com/googlecode/lanterna/gui2/SplitPanelTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@
*/
package com.googlecode.lanterna.gui2;

import com.googlecode.lanterna.*;
import com.googlecode.lanterna.bundle.*;
import com.googlecode.lanterna.graphics.*;
import java.util.Arrays;

import com.googlecode.lanterna.TerminalSize;
import com.googlecode.lanterna.TextCharacter;
import com.googlecode.lanterna.bundle.LanternaThemes;
import com.googlecode.lanterna.graphics.BasicTextImage;
import com.googlecode.lanterna.graphics.TextImage;
import com.googlecode.lanterna.gui2.LinearLayout.GrowPolicy;

/**
*
Expand Down Expand Up @@ -116,6 +121,7 @@ public static void main(String[] args) throws Exception {
@Override
public void init(WindowBasedTextGUI textGUI) {
final BasicWindow window = new BasicWindow("SplitPanelTest");
window.setHints(Arrays.asList(Window.Hint.FULL_SCREEN));
window.setTheme(LanternaThemes.getRegisteredTheme("businessmachine"));

ImageComponent left = makeImageComponent(IMAGE_X);
Expand All @@ -133,9 +139,34 @@ public void init(WindowBasedTextGUI textGUI) {
splitV.setRatio(20, 80);

Panel mainPanel = new Panel();
mainPanel.setLayoutManager(new GridLayout(2));
mainPanel.setLayoutManager(new BorderLayout());
SplitPanel splitboth = SplitPanel.ofHorizontal(splitH.withBorder(Borders.singleLine("horiontal split")), splitV.withBorder(Borders.singleLine("vertical split")));
mainPanel.addComponent(splitboth);

Panel pnlTextV = new Panel();
pnlTextV.setLayoutManager(new BorderLayout());
{
String txt = "This is a multiline text box on the bottom of the vertical SplitPanel that should expand to take up the extra space.";
TextBox txtLogs = new TextBox(txt, TextBox.Style.MULTI_LINE);
txtLogs.setHorizontalFocusSwitching(false);
txtLogs.setVerticalFocusSwitching(false);

pnlTextV.addComponent(txtLogs, BorderLayout.Location.CENTER);
}

SplitPanel splitLeft = SplitPanel.ofVertical(splitboth.withBorder(Borders.singleLine()), pnlTextV.withBorder(Borders.singleLine()));
Panel pnlTextH = new Panel();
pnlTextH.setLayoutManager(new BorderLayout());
{
String txt = "This is a multiline text box on the bottom of the horizontal SplitPanel that should expand to take up the extra space.";
TextBox txtLogs = new TextBox(txt, TextBox.Style.MULTI_LINE);
txtLogs.setHorizontalFocusSwitching(false);
txtLogs.setVerticalFocusSwitching(false);

pnlTextH.addComponent(txtLogs, BorderLayout.Location.CENTER);
}

SplitPanel splitMain = SplitPanel.ofHorizontal(splitLeft.withBorder(Borders.singleLine("Left Component")), pnlTextH.withBorder(Borders.singleLine("Right Component")));
mainPanel.addComponent(splitMain, BorderLayout.Location.CENTER);

window.setComponent(mainPanel);
textGUI.addWindow(window);
Expand Down