package com.googlecode.lanterna.gui2;
import com.googlecode.lanterna.TerminalPosition;
import com.googlecode.lanterna.gui2.menu.MenuBar;
import com.googlecode.lanterna.input.KeyStroke;
import com.googlecode.lanterna.TerminalSize;
import com.googlecode.lanterna.input.KeyType;
import java.util.*;
public abstract class AbstractWindow extends AbstractBasePane<Window> implements Window {
private String title;
private WindowBasedTextGUI textGUI;
private boolean visible;
private TerminalSize lastKnownSize;
private TerminalSize lastKnownDecoratedSize;
private TerminalPosition lastKnownPosition;
private TerminalPosition contentOffset;
private Set<Hint> hints;
private WindowPostRenderer windowPostRenderer;
private boolean closeWindowWithEscape;
public AbstractWindow() {
this("");
}
public AbstractWindow(String title) {
super();
this.title = title;
this.textGUI = null;
this.visible = true;
this.contentOffset = TerminalPosition.TOP_LEFT_CORNER;
this.lastKnownPosition = null;
this.lastKnownSize = null;
this.lastKnownDecoratedSize = null;
this.closeWindowWithEscape = false;
this.hints = new HashSet<>();
}
public void setCloseWindowWithEscape(boolean closeWindowWithEscape) {
this.closeWindowWithEscape = closeWindowWithEscape;
}
@Override
public void setTextGUI(WindowBasedTextGUI textGUI) {
if(this.textGUI != null && textGUI != null) {
throw new UnsupportedOperationException("Are you calling setTextGUI yourself? Please read the documentation"
+ " in that case (this could also be a bug in Lanterna, please report it if you are sure you are "
+ "not calling Window.setTextGUI(..) from your code)");
}
this.textGUI = textGUI;
}
@Override
public WindowBasedTextGUI getTextGUI() {
return textGUI;
}
public void setTitle(String title) {
this.title = title;
invalidate();
}
@Override
public String getTitle() {
return title;
}
@Override
public boolean isVisible() {
return visible;
}
@Override
public void setVisible(boolean visible) {
this.visible = visible;
}
@Override
public void draw(TextGUIGraphics graphics) {
if(!graphics.getSize().equals(lastKnownSize)) {
getComponent().invalidate();
}
setSize(graphics.getSize(), false);
super.draw(graphics);
}
@Override
public boolean handleInput(KeyStroke key) {
boolean handled = super.handleInput(key);
if(!handled && closeWindowWithEscape && key.getKeyType() == KeyType.Escape) {
close();
return true;
}
return handled;
}
@Override
@Deprecated
public TerminalPosition toGlobal(TerminalPosition localPosition) {
return toGlobalFromContentRelative(localPosition);
}
@Override
public TerminalPosition toGlobalFromContentRelative(TerminalPosition contentLocalPosition) {
if(contentLocalPosition == null) {
return null;
}
return lastKnownPosition.withRelative(contentOffset.withRelative(contentLocalPosition));
}
@Override
@Deprecated
public TerminalPosition toGlobalFromDecoratedRelative(TerminalPosition localPosition) {
if(localPosition == null) {
return null;
}
return lastKnownPosition.withRelative(localPosition);
}
@Override
@Deprecated
public TerminalPosition fromGlobal(TerminalPosition globalPosition) {
return fromGlobalToContentRelative(globalPosition);
}
@Override
public TerminalPosition fromGlobalToContentRelative(TerminalPosition globalPosition) {
if(globalPosition == null || lastKnownPosition == null) {
return null;
}
return globalPosition.withRelative(
-lastKnownPosition.getColumn() - contentOffset.getColumn(),
-lastKnownPosition.getRow() - contentOffset.getRow());
}
@Override
public TerminalPosition fromGlobalToDecoratedRelative(TerminalPosition globalPosition) {
if(globalPosition == null || lastKnownPosition == null) {
return null;
}
return globalPosition.withRelative(
-lastKnownPosition.getColumn(),
-lastKnownPosition.getRow());
}
@Override
public TerminalSize getPreferredSize() {
TerminalSize preferredSize = contentHolder.getPreferredSize();
MenuBar menuBar = getMenuBar();
if (menuBar.getMenuCount() > 0) {
TerminalSize menuPreferredSize = menuBar.getPreferredSize();
preferredSize = preferredSize.withRelativeRows(menuPreferredSize.getRows())
.withColumns(Math.max(menuPreferredSize.getColumns(), preferredSize.getColumns()));
}
return preferredSize;
}
@Override
public void setHints(Collection<Hint> hints) {
this.hints = new HashSet<>(hints);
invalidate();
}
@Override
public Set<Hint> getHints() {
return Collections.unmodifiableSet(hints);
}
@Override
public WindowPostRenderer getPostRenderer() {
return windowPostRenderer;
}
@Override
public void addWindowListener(WindowListener windowListener) {
addBasePaneListener(windowListener);
}
@Override
public void removeWindowListener(WindowListener windowListener) {
removeBasePaneListener(windowListener);
}
public void setWindowPostRenderer(WindowPostRenderer windowPostRenderer) {
this.windowPostRenderer = windowPostRenderer;
}
@Override
public final TerminalPosition getPosition() {
return lastKnownPosition;
}
@Override
public final void setPosition(TerminalPosition topLeft) {
TerminalPosition oldPosition = this.lastKnownPosition;
this.lastKnownPosition = topLeft;
for(BasePaneListener<?> listener: getBasePaneListeners()) {
if(listener instanceof WindowListener) {
((WindowListener)listener).onMoved(this, oldPosition, topLeft);
}
}
}
@Override
public final TerminalSize getSize() {
return lastKnownSize;
}
@Override
@Deprecated
public void setSize(TerminalSize size) {
setSize(size, true);
}
@Override
public void setFixedSize(TerminalSize size) {
hints.add(Hint.FIXED_SIZE);
setSize(size);
}
private void setSize(TerminalSize size, boolean invalidate) {
TerminalSize oldSize = this.lastKnownSize;
this.lastKnownSize = size;
if(invalidate) {
invalidate();
}
for(BasePaneListener<?> listener: getBasePaneListeners()) {
if(listener instanceof WindowListener) {
((WindowListener)listener).onResized(this, oldSize, size);
}
}
}
@Override
public final TerminalSize getDecoratedSize() {
return lastKnownDecoratedSize;
}
@Override
public final void setDecoratedSize(TerminalSize decoratedSize) {
this.lastKnownDecoratedSize = decoratedSize;
}
@Override
public void setContentOffset(TerminalPosition offset) {
this.contentOffset = offset;
}
@Override
public void close() {
if(textGUI != null) {
textGUI.removeWindow(this);
}
setComponent(null);
}
@Override
public void waitUntilClosed() {
WindowBasedTextGUI textGUI = getTextGUI();
if(textGUI != null) {
textGUI.waitForWindowToClose(this);
}
}
Window self() { return this; }
}