X-Git-Url: http://git.nikiroo.be/?p=jvcard.git;a=blobdiff_plain;f=src%2Fcom%2Fgooglecode%2Flanterna%2Fscreen%2FVirtualScreen.java;fp=src%2Fcom%2Fgooglecode%2Flanterna%2Fscreen%2FVirtualScreen.java;h=0000000000000000000000000000000000000000;hp=a45c3615e58c019e3734bb9722effde8c5d276a5;hb=f06c81000632cfb5f525ca458f719338f55f9f66;hpb=a73a906356c971b080c36368e71a15d87e8b8d31 diff --git a/src/com/googlecode/lanterna/screen/VirtualScreen.java b/src/com/googlecode/lanterna/screen/VirtualScreen.java deleted file mode 100644 index a45c361..0000000 --- a/src/com/googlecode/lanterna/screen/VirtualScreen.java +++ /dev/null @@ -1,321 +0,0 @@ -package com.googlecode.lanterna.screen; - -import com.googlecode.lanterna.*; -import com.googlecode.lanterna.graphics.TextGraphics; -import com.googlecode.lanterna.input.KeyStroke; -import com.googlecode.lanterna.input.KeyType; - -import java.io.IOException; - -/** - * VirtualScreen wraps a normal screen and presents it as a screen that has a configurable minimum size; if the real - * screen is smaller than this size, the presented screen will add scrolling to get around it. To anyone using this - * class, it will appear and behave just as a normal screen. Scrolling is done by using CTRL + arrow keys. - *

- * The use case for this class is to allow you to set a minimum size that you can count on be honored, no matter how - * small the user makes the terminal. This should make programming GUIs easier. - * @author Martin - */ -public class VirtualScreen extends AbstractScreen { - private final Screen realScreen; - private final FrameRenderer frameRenderer; - private TerminalSize minimumSize; - private TerminalPosition viewportTopLeft; - private TerminalSize viewportSize; - - /** - * Creates a new VirtualScreen that wraps a supplied Screen. The screen passed in here should be the real screen - * that is created on top of the real {@code Terminal}, it will have the correct size and content for what's - * actually displayed to the user, but this class will present everything as one view with a fixed minimum size, - * no matter what size the real terminal has. - *

- * The initial minimum size will be the current size of the screen. - * @param screen Real screen that will be used when drawing the whole or partial virtual screen - */ - public VirtualScreen(Screen screen) { - super(screen.getTerminalSize()); - this.frameRenderer = new DefaultFrameRenderer(); - this.realScreen = screen; - this.minimumSize = screen.getTerminalSize(); - this.viewportTopLeft = TerminalPosition.TOP_LEFT_CORNER; - this.viewportSize = minimumSize; - } - - /** - * Sets the minimum size we want the virtual screen to have. If the user resizes the real terminal to something - * smaller than this, the virtual screen will refuse to make it smaller and add scrollbars to the view. - * @param minimumSize Minimum size we want the screen to have - */ - public void setMinimumSize(TerminalSize minimumSize) { - this.minimumSize = minimumSize; - TerminalSize virtualSize = minimumSize.max(realScreen.getTerminalSize()); - if(!minimumSize.equals(virtualSize)) { - addResizeRequest(virtualSize); - super.doResizeIfNecessary(); - } - calculateViewport(realScreen.getTerminalSize()); - } - - /** - * Returns the minimum size this virtual screen can have. If the real terminal is made smaller than this, the - * virtual screen will draw scrollbars and implement scrolling - * @return Minimum size configured for this virtual screen - */ - public TerminalSize getMinimumSize() { - return minimumSize; - } - - @Override - public void startScreen() throws IOException { - realScreen.startScreen(); - } - - @Override - public void stopScreen() throws IOException { - realScreen.stopScreen(); - } - - @Override - public TextCharacter getFrontCharacter(TerminalPosition position) { - return null; - } - - @Override - public void setCursorPosition(TerminalPosition position) { - super.setCursorPosition(position); - if(position == null) { - realScreen.setCursorPosition(null); - return; - } - position = position.withRelativeColumn(-viewportTopLeft.getColumn()).withRelativeRow(-viewportTopLeft.getRow()); - if(position.getColumn() >= 0 && position.getColumn() < viewportSize.getColumns() && - position.getRow() >= 0 && position.getRow() < viewportSize.getRows()) { - realScreen.setCursorPosition(position); - } - else { - realScreen.setCursorPosition(null); - } - } - - @Override - public synchronized TerminalSize doResizeIfNecessary() { - TerminalSize underlyingSize = realScreen.doResizeIfNecessary(); - if(underlyingSize == null) { - return null; - } - - TerminalSize newVirtualSize = calculateViewport(underlyingSize); - if(!getTerminalSize().equals(newVirtualSize)) { - addResizeRequest(newVirtualSize); - return super.doResizeIfNecessary(); - } - return newVirtualSize; - } - - private TerminalSize calculateViewport(TerminalSize realTerminalSize) { - TerminalSize newVirtualSize = minimumSize.max(realTerminalSize); - if(newVirtualSize.equals(realTerminalSize)) { - viewportSize = realTerminalSize; - viewportTopLeft = TerminalPosition.TOP_LEFT_CORNER; - } - else { - TerminalSize newViewportSize = frameRenderer.getViewportSize(realTerminalSize, newVirtualSize); - if(newViewportSize.getRows() > viewportSize.getRows()) { - viewportTopLeft = viewportTopLeft.withRow(Math.max(0, viewportTopLeft.getRow() - (newViewportSize.getRows() - viewportSize.getRows()))); - } - if(newViewportSize.getColumns() > viewportSize.getColumns()) { - viewportTopLeft = viewportTopLeft.withColumn(Math.max(0, viewportTopLeft.getColumn() - (newViewportSize.getColumns() - viewportSize.getColumns()))); - } - viewportSize = newViewportSize; - } - return newVirtualSize; - } - - @Override - public void refresh(RefreshType refreshType) throws IOException { - setCursorPosition(getCursorPosition()); //Make sure the cursor is at the correct position - if(!viewportSize.equals(realScreen.getTerminalSize())) { - frameRenderer.drawFrame( - realScreen.newTextGraphics(), - realScreen.getTerminalSize(), - getTerminalSize(), - viewportTopLeft); - } - - //Copy the rows - TerminalPosition viewportOffset = frameRenderer.getViewportOffset(); - if(realScreen instanceof AbstractScreen) { - AbstractScreen asAbstractScreen = (AbstractScreen)realScreen; - getBackBuffer().copyTo( - asAbstractScreen.getBackBuffer(), - viewportTopLeft.getRow(), - viewportSize.getRows(), - viewportTopLeft.getColumn(), - viewportSize.getColumns(), - viewportOffset.getRow(), - viewportOffset.getColumn()); - } - else { - for(int y = 0; y < viewportSize.getRows(); y++) { - for(int x = 0; x < viewportSize.getColumns(); x++) { - realScreen.setCharacter( - x + viewportOffset.getColumn(), - y + viewportOffset.getRow(), - getBackBuffer().getCharacterAt( - x + viewportTopLeft.getColumn(), - y + viewportTopLeft.getRow())); - } - } - } - realScreen.refresh(refreshType); - } - - @Override - public KeyStroke pollInput() throws IOException { - return filter(realScreen.pollInput()); - } - - @Override - public KeyStroke readInput() throws IOException { - return filter(realScreen.readInput()); - } - - private KeyStroke filter(KeyStroke keyStroke) throws IOException { - if(keyStroke == null) { - return null; - } - else if(keyStroke.isAltDown() && keyStroke.getKeyType() == KeyType.ArrowLeft) { - if(viewportTopLeft.getColumn() > 0) { - viewportTopLeft = viewportTopLeft.withRelativeColumn(-1); - refresh(); - return null; - } - } - else if(keyStroke.isAltDown() && keyStroke.getKeyType() == KeyType.ArrowRight) { - if(viewportTopLeft.getColumn() + viewportSize.getColumns() < getTerminalSize().getColumns()) { - viewportTopLeft = viewportTopLeft.withRelativeColumn(1); - refresh(); - return null; - } - } - else if(keyStroke.isAltDown() && keyStroke.getKeyType() == KeyType.ArrowUp) { - if(viewportTopLeft.getRow() > 0) { - viewportTopLeft = viewportTopLeft.withRelativeRow(-1); - realScreen.scrollLines(0,viewportSize.getRows()-1,-1); - refresh(); - return null; - } - } - else if(keyStroke.isAltDown() && keyStroke.getKeyType() == KeyType.ArrowDown) { - if(viewportTopLeft.getRow() + viewportSize.getRows() < getTerminalSize().getRows()) { - viewportTopLeft = viewportTopLeft.withRelativeRow(1); - realScreen.scrollLines(0,viewportSize.getRows()-1,1); - refresh(); - return null; - } - } - return keyStroke; - } - - @Override - public void scrollLines(int firstLine, int lastLine, int distance) { - // do base class stuff (scroll own back buffer) - super.scrollLines(firstLine, lastLine, distance); - // vertical range visible in realScreen: - int vpFirst = viewportTopLeft.getRow(), - vpRows = viewportSize.getRows(); - // adapt to realScreen range: - firstLine = Math.max(0, firstLine - vpFirst); - lastLine = Math.min(vpRows - 1, lastLine - vpFirst); - // if resulting range non-empty: scroll that range in realScreen: - if (firstLine <= lastLine) { - realScreen.scrollLines(firstLine, lastLine, distance); - } - } - - /** - * Interface for rendering the virtual screen's frame when the real terminal is too small for the virtual screen - */ - public interface FrameRenderer { - /** - * Given the size of the real terminal and the current size of the virtual screen, how large should the viewport - * where the screen content is drawn be? - * @param realSize Size of the real terminal - * @param virtualSize Size of the virtual screen - * @return Size of the viewport, according to this FrameRenderer - */ - TerminalSize getViewportSize(TerminalSize realSize, TerminalSize virtualSize); - - /** - * Where in the virtual screen should the top-left position of the viewport be? To draw the viewport from the - * top-left position of the screen, return 0x0 (or TerminalPosition.TOP_LEFT_CORNER) here. - * @return Position of the top-left corner of the viewport inside the screen - */ - TerminalPosition getViewportOffset(); - - /** - * Drawn the 'frame', meaning anything that is outside the viewport (title, scrollbar, etc) - * @param graphics Graphics to use to text drawing operations - * @param realSize Size of the real terminal - * @param virtualSize Size of the virtual screen - * @param virtualScrollPosition If the virtual screen is larger than the real terminal, this is the current - * scroll offset the VirtualScreen is using - */ - void drawFrame( - TextGraphics graphics, - TerminalSize realSize, - TerminalSize virtualSize, - TerminalPosition virtualScrollPosition); - } - - private static class DefaultFrameRenderer implements FrameRenderer { - @Override - public TerminalSize getViewportSize(TerminalSize realSize, TerminalSize virtualSize) { - if(realSize.getColumns() > 1 && realSize.getRows() > 2) { - return realSize.withRelativeColumns(-1).withRelativeRows(-2); - } - else { - return realSize; - } - } - - @Override - public TerminalPosition getViewportOffset() { - return TerminalPosition.TOP_LEFT_CORNER; - } - - @Override - public void drawFrame( - TextGraphics graphics, - TerminalSize realSize, - TerminalSize virtualSize, - TerminalPosition virtualScrollPosition) { - - if(realSize.getColumns() == 1 || realSize.getRows() <= 2) { - return; - } - TerminalSize viewportSize = getViewportSize(realSize, virtualSize); - - graphics.setForegroundColor(TextColor.ANSI.WHITE); - graphics.setBackgroundColor(TextColor.ANSI.BLACK); - graphics.fill(' '); - graphics.putString(0, graphics.getSize().getRows() - 1, "Terminal too small, use ALT+arrows to scroll"); - - int horizontalSize = (int)(((double)(viewportSize.getColumns()) / (double)virtualSize.getColumns()) * (viewportSize.getColumns())); - int scrollable = viewportSize.getColumns() - horizontalSize - 1; - int horizontalPosition = (int)((double)scrollable * ((double)virtualScrollPosition.getColumn() / (double)(virtualSize.getColumns() - viewportSize.getColumns()))); - graphics.drawLine( - new TerminalPosition(horizontalPosition, graphics.getSize().getRows() - 2), - new TerminalPosition(horizontalPosition + horizontalSize, graphics.getSize().getRows() - 2), - Symbols.BLOCK_MIDDLE); - - int verticalSize = (int)(((double)(viewportSize.getRows()) / (double)virtualSize.getRows()) * (viewportSize.getRows())); - scrollable = viewportSize.getRows() - verticalSize - 1; - int verticalPosition = (int)((double)scrollable * ((double)virtualScrollPosition.getRow() / (double)(virtualSize.getRows() - viewportSize.getRows()))); - graphics.drawLine( - new TerminalPosition(graphics.getSize().getColumns() - 1, verticalPosition), - new TerminalPosition(graphics.getSize().getColumns() - 1, verticalPosition + verticalSize), - Symbols.BLOCK_MIDDLE); - } - } -}