X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2FTTerminalWindow.java;h=9780e29d7d6643ad0c032801c6605d3320b91052;hb=69a8c36844309a07dfe7c8c7576d9c0e47be3303;hp=d17a2c4cdd53b3564fbb952276834f35822146b3;hpb=d11152032d9342cc178ba20adab40083a9f37081;p=nikiroo-utils.git diff --git a/src/jexer/TTerminalWindow.java b/src/jexer/TTerminalWindow.java index d17a2c4..9780e29 100644 --- a/src/jexer/TTerminalWindow.java +++ b/src/jexer/TTerminalWindow.java @@ -28,10 +28,10 @@ */ package jexer; -import java.awt.image.BufferedImage; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; +import java.awt.image.BufferedImage; import java.io.InputStream; import java.io.IOException; @@ -132,6 +132,18 @@ public class TTerminalWindow extends TScrollableWindow */ private Map glyphCache; + /** + * A cache of previously-rendered double-width glyphs for blinking text, + * when it is not visible. + */ + private Map glyphCacheBlink; + + /** + * The blink state, used only by ECMA48 backend and when double-width + * chars must be drawn. + */ + private boolean blinkState = true; + // ------------------------------------------------------------------------ // Constructors ----------------------------------------------------------- // ------------------------------------------------------------------------ @@ -538,13 +550,17 @@ public class TTerminalWindow extends TScrollableWindow return; } - if (mouse.isMouseWheelUp()) { - verticalDecrement(); - return; - } - if (mouse.isMouseWheelDown()) { - verticalIncrement(); - return; + // If the emulator is tracking mouse buttons, it needs to see wheel + // events. + if (emulator.getMouseProtocol() == ECMA48.MouseProtocol.OFF) { + if (mouse.isMouseWheelUp()) { + verticalDecrement(); + return; + } + if (mouse.isMouseWheelDown()) { + verticalIncrement(); + return; + } } if (mouseOnEmulator(mouse)) { synchronized (emulator) { @@ -749,6 +765,22 @@ public class TTerminalWindow extends TScrollableWindow // Add shortcut text newStatusBar(i18n.getString("statusBarRunning")); + + // Pass the correct text cell width/height to the emulator + int textWidth = 16; + int textHeight = 20; + if (getScreen() instanceof SwingTerminal) { + SwingTerminal terminal = (SwingTerminal) getScreen(); + + textWidth = terminal.getTextWidth(); + textHeight = terminal.getTextHeight(); + } else if (getScreen() instanceof ECMA48Terminal) { + ECMA48Terminal terminal = (ECMA48Terminal) getScreen(); + textWidth = terminal.getTextWidth(); + textHeight = terminal.getTextHeight(); + } + emulator.setTextWidth(textWidth); + emulator.setTextHeight(textHeight); } /** @@ -931,17 +963,28 @@ public class TTerminalWindow extends TScrollableWindow int textWidth = 16; int textHeight = 20; + boolean cursorBlinkVisible = true; if (getScreen() instanceof SwingTerminal) { SwingTerminal terminal = (SwingTerminal) getScreen(); textWidth = terminal.getTextWidth(); textHeight = terminal.getTextHeight(); + cursorBlinkVisible = terminal.getCursorBlinkVisible(); } else if (getScreen() instanceof ECMA48Terminal) { ECMA48Terminal terminal = (ECMA48Terminal) getScreen(); + if (!terminal.hasSixel()) { + // The backend does not have sixel support, draw this as text + // and bail out. + putCharXY(x, y, cell); + putCharXY(x + 1, y, ' ', cell); + return; + } + textWidth = terminal.getTextWidth(); textHeight = terminal.getTextHeight(); + cursorBlinkVisible = blinkState; } else { // We don't know how to dray glyphs to this screen, draw them as // text and bail out. @@ -959,8 +1002,11 @@ public class TTerminalWindow extends TScrollableWindow assert (doubleFont != null); BufferedImage image = null; - - image = glyphCache.get(cell); + if (cell.isBlink() && !cursorBlinkVisible) { + image = glyphCacheBlink.get(cell); + } else { + image = glyphCache.get(cell); + } if (image == null) { // Generate glyph and draw it to an image. image = new BufferedImage(textWidth * 2, textHeight * 2, @@ -976,14 +1022,18 @@ public class TTerminalWindow extends TScrollableWindow gr2.setColor(SwingTerminal.attrToBackgroundColor(cell)); gr2.fillRect(0, 0, image.getWidth(), image.getHeight()); } - gr2.setColor(SwingTerminal.attrToForegroundColor(cell)); - char [] chars = new char[1]; - chars[0] = cell.getChar(); - gr2.drawChars(chars, 0, 1, doubleTextAdjustX, - (textHeight * 2) - doubleMaxDescent + doubleTextAdjustY); - - if (cell.isUnderline() && (line.getDoubleHeight() != 1)) { - gr2.fillRect(0, textHeight - 2, textWidth, 2); + if (!cell.isBlink() + || (cell.isBlink() && cursorBlinkVisible) + ) { + gr2.setColor(SwingTerminal.attrToForegroundColor(cell)); + char [] chars = new char[1]; + chars[0] = cell.getChar(); + gr2.drawChars(chars, 0, 1, doubleTextAdjustX, + (textHeight * 2) - doubleMaxDescent + doubleTextAdjustY); + + if (cell.isUnderline() && (line.getDoubleHeight() != 1)) { + gr2.fillRect(0, textHeight - 2, textWidth, 2); + } } gr2.dispose(); @@ -991,7 +1041,11 @@ public class TTerminalWindow extends TScrollableWindow // be mutated by invertCell(). Cell key = new Cell(); key.setTo(cell); - glyphCache.put(key, image); + if (cell.isBlink() && !cursorBlinkVisible) { + glyphCacheBlink.put(key, image); + } else { + glyphCache.put(key, image); + } } // Now that we have the double-wide glyph drawn, copy the right @@ -1066,8 +1120,25 @@ public class TTerminalWindow extends TScrollableWindow gr.dispose(); - // (Re)create the glyph cache. + // (Re)create the glyph caches. glyphCache = new HashMap(); + glyphCacheBlink = new HashMap(); + + // Special case: the ECMA48 backend needs to have a timer to drive + // its blink state. + if (getScreen() instanceof jexer.backend.ECMA48Terminal) { + // Blink every 500 millis. + long millis = 500; + getApplication().addTimer(millis, true, + new TAction() { + public void DO() { + blinkState = !blinkState; + getApplication().doRepaint(); + } + } + ); + } + } }