예제 #1
0
    @Override
    public void drawBorder(TextGraphics graphics, TerminalSize actualSize, String title) {
      graphics.applyTheme(graphics.getTheme().getDefinition(Theme.Category.Border));
      final int width = actualSize.getColumns();
      final int height = actualSize.getRows();

      // Top
      graphics.drawString(0, 0, ACS.ULCORNER + "");
      for (int x = 1; x < width - 1; x++) graphics.drawString(x, 0, ACS.HLINE + "");
      graphics.drawString(width - 1, 0, ACS.URCORNER + "");

      // Each row
      for (int i = 1; i < height - 1; i++) {
        graphics.drawString(0, i, ACS.VLINE + "");
        graphics.drawString(0 + width - 1, i, ACS.VLINE + "");
      }

      // Bottom
      graphics.drawString(0, height - 1, ACS.LLCORNER + "");
      for (int x = 1; x < width - 1; x++) graphics.drawString(x, height - 1, ACS.HLINE + "");
      graphics.drawString(width - 1, height - 1, ACS.LRCORNER + "");

      // Write the title
      graphics.applyTheme(graphics.getTheme().getDefinition(Theme.Category.DialogArea));
      graphics.setBoldMask(true);
      graphics.drawString(2, 0, title);
    }
예제 #2
0
  // WARNING!!! Should only be called in a block synchronized on mutex! See refresh()
  private void resizeScreenIfNeeded() {
    TerminalSize newSize;
    synchronized (resizeQueue) {
      if (resizeQueue.isEmpty()) return;

      newSize = resizeQueue.getLast();
      resizeQueue.clear();
    }

    int height = newSize.getRows();
    int width = newSize.getColumns();
    ScreenCharacter[][] newBackBuffer = new ScreenCharacter[height][width];
    ScreenCharacter[][] newVisibleScreen = new ScreenCharacter[height][width];
    ScreenCharacter newAreaCharacter =
        new ScreenCharacter('X', Terminal.Color.GREEN, Terminal.Color.BLACK);
    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++) {
        if (x < backbuffer[0].length && y < backbuffer.length)
          newBackBuffer[y][x] = backbuffer[y][x];
        else newBackBuffer[y][x] = new ScreenCharacter(newAreaCharacter);

        if (x < visibleScreen[0].length && y < visibleScreen.length)
          newVisibleScreen[y][x] = visibleScreen[y][x];
        else newVisibleScreen[y][x] = new ScreenCharacter(newAreaCharacter);
      }
    }

    backbuffer = newBackBuffer;
    visibleScreen = newVisibleScreen;
    wholeScreenInvalid = true;
    terminalSize = new TerminalSize(newSize);
  }
예제 #3
0
 /**
  * Moves the current cursor position
  *
  * @param column 0-indexed column number of the new position
  * @param row 0-indexed row number of the new position
  */
 public void setCursorPosition(int column, int row) {
   synchronized (mutex) {
     if (column >= 0
         && column < terminalSize.getColumns()
         && row >= 0
         && row < terminalSize.getRows()) {
       this.cursorPosition = new TerminalPosition(column, row);
     }
   }
 }
예제 #4
0
 @Override
 public TerminalSize surroundAreaSize(TerminalSize TerminalSize) {
   return new TerminalSize(
       TerminalSize.getColumns() == Integer.MAX_VALUE
           ? Integer.MAX_VALUE
           : TerminalSize.getColumns() + 4,
       TerminalSize.getRows() == Integer.MAX_VALUE
           ? Integer.MAX_VALUE
           : TerminalSize.getRows() + 2);
 }
예제 #5
0
  /**
   * Erases all the characters on the screen, effectively giving you a blank area. The default
   * background color will be used, if you want to fill the screen with a different color you will
   * need to do this manually.
   */
  public void clear() {
    // ScreenCharacter is immutable, so we can use it for every element
    ScreenCharacter background = new ScreenCharacter(' ');

    synchronized (mutex) {
      for (int y = 0; y < terminalSize.getRows(); y++) {
        for (int x = 0; x < terminalSize.getColumns(); x++) {
          backbuffer[y][x] = background;
        }
      }
    }
  }
예제 #6
0
    @Override
    public void drawBorder(TextGraphics graphics, TerminalSize actualSize, String title) {
      final int width = actualSize.getColumns();
      final int height = actualSize.getRows();
      final Theme.Definition upperLeft;
      final Theme.Definition lowerRight;

      if (raised) {
        upperLeft = graphics.getTheme().getDefinition(Theme.Category.RaisedBorder);
        lowerRight = graphics.getTheme().getDefinition(Theme.Category.Border);
      } else {
        upperLeft = graphics.getTheme().getDefinition(Theme.Category.Border);
        lowerRight = graphics.getTheme().getDefinition(Theme.Category.RaisedBorder);
      }

      // Top
      graphics.applyTheme(upperLeft);
      graphics.drawString(0, 0, ACS.ULCORNER + "");
      for (int i = 1; i < width - 1; i++) graphics.drawString(i, 0, ACS.HLINE + "");
      graphics.applyTheme(lowerRight);
      graphics.drawString(width - 1, 0, ACS.URCORNER + "");

      // Each row
      for (int i = 1; i < height - 1; i++) {
        graphics.applyTheme(upperLeft);
        graphics.drawString(0, i, ACS.VLINE + "");
        graphics.applyTheme(lowerRight);
        graphics.drawString(width - 1, i, ACS.VLINE + "");
      }

      // Bottom
      graphics.applyTheme(upperLeft);
      graphics.drawString(0, height - 1, ACS.LLCORNER + "");
      graphics.applyTheme(lowerRight);
      for (int i = 1; i < width - 1; i++) graphics.drawString(i, height - 1, ACS.HLINE + "");
      graphics.drawString(width - 1, height - 1, ACS.LRCORNER + "");

      // Write the title
      graphics.applyTheme(graphics.getTheme().getDefinition(Theme.Category.DialogArea));
      graphics.setBoldMask(true);
      graphics.drawString(2, 0, title);
    }
예제 #7
0
  /**
   * Call this method to make changes done through {@code putCharacter(...)}, {@code putString(...)}
   * visible on the terminal. The screen will calculate the changes that are required and send the
   * necessary characters and control sequences to make it so.
   */
  public void refresh() {
    if (!hasBeenActivated) return;

    synchronized (mutex) {
      // If any resize operations are in the queue, execute them
      resizeScreenIfNeeded();

      Map<TerminalPosition, ScreenCharacter> updateMap =
          new TreeMap<TerminalPosition, ScreenCharacter>(new ScreenPointComparator());

      for (int y = 0; y < terminalSize.getRows(); y++) {
        for (int x = 0; x < terminalSize.getColumns(); x++) {
          ScreenCharacter c = backbuffer[y][x];
          if (!c.equals(visibleScreen[y][x]) || wholeScreenInvalid) {
            visibleScreen[y][x] =
                c; // Remember, ScreenCharacter is immutable, we don't need to worry about it being
            // modified
            updateMap.put(new TerminalPosition(x, y), c);
          }
        }
      }

      Writer terminalWriter = new Writer();
      terminalWriter.reset();
      TerminalPosition previousPoint = null;
      for (TerminalPosition nextUpdate : updateMap.keySet()) {
        if (previousPoint == null
            || previousPoint.getRow() != nextUpdate.getRow()
            || previousPoint.getColumn() + 1 != nextUpdate.getColumn()) {
          terminalWriter.setCursorPosition(nextUpdate.getColumn(), nextUpdate.getRow());
        }
        terminalWriter.writeCharacter(updateMap.get(nextUpdate));
        previousPoint = nextUpdate;
      }
      terminalWriter.setCursorPosition(
          getCursorPosition().getColumn(), getCursorPosition().getRow());
      wholeScreenInvalid = false;
    }
    terminal.flush();
  }
예제 #8
0
 /**
  * Creates a new Screen on top of a supplied terminal and will set the size of the screen to a
  * supplied value. The screen is initially blank.
  *
  * @param terminal
  * @param terminalSize
  */
 public Screen(Terminal terminal, TerminalSize terminalSize) {
   this(terminal, terminalSize.getColumns(), terminalSize.getRows());
 }