X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2FTApplication.java;h=a38b2daba2a95fbe382de7ffc383520f14d5ad68;hb=54eaded07d2c1c37d9e1000abdcc97be09955867;hp=9c9c5714c67cbad7eb7a093fe049644f88250b13;hpb=2bb26984bfcf482db4e4fc5fd2faea86004fc979;p=fanfix.git diff --git a/src/jexer/TApplication.java b/src/jexer/TApplication.java index 9c9c571..a38b2da 100644 --- a/src/jexer/TApplication.java +++ b/src/jexer/TApplication.java @@ -47,6 +47,7 @@ import java.util.ResourceBundle; import jexer.bits.Cell; import jexer.bits.CellAttributes; +import jexer.bits.Clipboard; import jexer.bits.ColorTheme; import jexer.bits.StringUtils; import jexer.event.TCommandEvent; @@ -148,6 +149,11 @@ public class TApplication implements Runnable { */ private Backend backend; + /** + * The clipboard for copy and paste. + */ + private Clipboard clipboard = new Clipboard(); + /** * Actual mouse coordinate X. */ @@ -325,6 +331,36 @@ public class TApplication implements Runnable { */ private long screenResizeTime = 0; + /** + * If true, screen selection is a rectangle. + */ + private boolean screenSelectionRectangle = false; + + /** + * If true, the mouse is dragging a screen selection. + */ + private boolean inScreenSelection = false; + + /** + * Screen selection starting X. + */ + private int screenSelectionX0; + + /** + * Screen selection starting Y. + */ + private int screenSelectionY0; + + /** + * Screen selection ending X. + */ + private int screenSelectionX1; + + /** + * Screen selection ending Y. + */ + private int screenSelectionY1; + /** * WidgetEventHandler is the main event consumer loop. There are at most * two such threads in existence: the primary for normal case and a @@ -869,6 +905,11 @@ public class TApplication implements Runnable { // resources. closeAllWindows(); + // Close the desktop. + if (desktop != null) { + setDesktop(null); + } + // Give the overarching application an opportunity to release // resources. onExit(); @@ -1100,8 +1141,8 @@ public class TApplication implements Runnable { oldMouseY = 0; } if (desktop != null) { - desktop.setDimensions(0, 0, resize.getWidth(), - resize.getHeight() - (hideStatusBar ? 0 : 1)); + desktop.setDimensions(0, desktopTop, resize.getWidth(), + (desktopBottom - desktopTop)); desktop.onResize(resize); } @@ -1152,6 +1193,28 @@ public class TApplication implements Runnable { typingHidMouse = false; TMouseEvent mouse = (TMouseEvent) event; + if (mouse.isMouse1() && (mouse.isShift() || mouse.isCtrl())) { + // Screen selection. + if (inScreenSelection) { + screenSelectionX1 = mouse.getX(); + screenSelectionY1 = mouse.getY(); + } else { + inScreenSelection = true; + screenSelectionX0 = mouse.getX(); + screenSelectionY0 = mouse.getY(); + screenSelectionX1 = mouse.getX(); + screenSelectionY1 = mouse.getY(); + screenSelectionRectangle = mouse.isCtrl(); + } + } else { + if (inScreenSelection) { + getScreen().copySelection(clipboard, screenSelectionX0, + screenSelectionY0, screenSelectionX1, screenSelectionY1, + screenSelectionRectangle); + } + inScreenSelection = false; + } + if ((mouseX != mouse.getX()) || (mouseY != mouse.getY())) { oldMouseX = mouseX; oldMouseY = mouseY; @@ -1172,7 +1235,8 @@ public class TApplication implements Runnable { mouse.getAbsoluteX(), mouse.getAbsoluteY(), mouse.isMouse1(), mouse.isMouse2(), mouse.isMouse3(), - mouse.isMouseWheelUp(), mouse.isMouseWheelDown()); + mouse.isMouseWheelUp(), mouse.isMouseWheelDown(), + mouse.isAlt(), mouse.isCtrl(), mouse.isShift()); } else { // The first click of a potential double-click. @@ -1296,6 +1360,8 @@ public class TApplication implements Runnable { } } else if (event instanceof TKeypressEvent) { dispatchToDesktop = false; + } else if (event instanceof TMenuEvent) { + dispatchToDesktop = false; } if (debugEvents) { @@ -1359,7 +1425,8 @@ public class TApplication implements Runnable { mouse.getAbsoluteX(), mouse.getAbsoluteY(), mouse.isMouse1(), mouse.isMouse2(), mouse.isMouse3(), - mouse.isMouseWheelUp(), mouse.isMouseWheelDown()); + mouse.isMouseWheelUp(), mouse.isMouseWheelDown(), + mouse.isAlt(), mouse.isCtrl(), mouse.isShift()); } else { // The first click of a potential double-click. @@ -1609,6 +1676,8 @@ public class TApplication implements Runnable { */ public final void setDesktop(final TDesktop desktop) { if (this.desktop != null) { + this.desktop.onPreClose(); + this.desktop.onUnfocus(); this.desktop.onClose(); } this.desktop = desktop; @@ -1670,7 +1739,7 @@ public class TApplication implements Runnable { String version = getClass().getPackage().getImplementationVersion(); if (version == null) { // This is Java 9+, use a hardcoded string here. - version = "0.3.2"; + version = "1.0.0"; } messageBox(i18n.getString("aboutDialogTitle"), MessageFormat.format(i18n.getString("aboutDialogText"), version), @@ -1715,27 +1784,15 @@ public class TApplication implements Runnable { // ------------------------------------------------------------------------ /** - * Invert the cell color at a position. This is used to track the mouse. - * - * @param x column position - * @param y row position - */ - private void invertCell(final int x, final int y) { - invertCell(x, y, false); - } - - /** - * Invert the cell color at a position. This is used to track the mouse. + * Draw the text mouse at position. * * @param x column position * @param y row position - * @param onlyThisCell if true, only invert this cell */ - private void invertCell(final int x, final int y, - final boolean onlyThisCell) { + private void drawTextMouse(final int x, final int y) { if (debugThreads) { - System.err.printf("%d %s invertCell() %d %d\n", + System.err.printf("%d %s drawTextMouse() %d %d\n", System.currentTimeMillis(), Thread.currentThread(), x, y); if (activeWindow != null) { @@ -1757,44 +1814,20 @@ public class TApplication implements Runnable { } } - Cell cell = getScreen().getCharXY(x, y); - if (cell.isImage()) { - cell.invertImage(); - } - if (cell.getForeColorRGB() < 0) { - cell.setForeColor(cell.getForeColor().invert()); - } else { - cell.setForeColorRGB(cell.getForeColorRGB() ^ 0x00ffffff); - } - if (cell.getBackColorRGB() < 0) { - cell.setBackColor(cell.getBackColor().invert()); - } else { - cell.setBackColorRGB(cell.getBackColorRGB() ^ 0x00ffffff); - } - getScreen().putCharXY(x, y, cell); - if ((onlyThisCell == true) || (cell.getWidth() == Cell.Width.SINGLE)) { - return; - } - - // This cell is one half of a fullwidth glyph. Invert the other - // half. - if (cell.getWidth() == Cell.Width.LEFT) { - if (x < getScreen().getWidth() - 1) { - Cell rightHalf = getScreen().getCharXY(x + 1, y); - if (rightHalf.getWidth() == Cell.Width.RIGHT) { - invertCell(x + 1, y, true); - return; - } - } - } - if (cell.getWidth() == Cell.Width.RIGHT) { - if (x > 0) { - Cell leftHalf = getScreen().getCharXY(x - 1, y); - if (leftHalf.getWidth() == Cell.Width.LEFT) { - invertCell(x - 1, y, true); - } + // If this cell is on top of the desktop, and the desktop has + // requested a hidden mouse, bail out. + if ((desktop != null) && (activeWindow == null) && (activeMenu == null)) { + if ((desktop.hasHiddenMouse() == true) + && (x > desktop.getX()) + && (x < desktop.getX() + desktop.getWidth() - 1) + && (y > desktop.getY()) + && (y < desktop.getY() + desktop.getHeight() - 1) + ) { + return; } } + + getScreen().invertCell(x, y); } /** @@ -1854,9 +1887,15 @@ public class TApplication implements Runnable { } } + if (inScreenSelection) { + getScreen().setSelection(screenSelectionX0, + screenSelectionY0, screenSelectionX1, screenSelectionY1, + screenSelectionRectangle); + } + if ((textMouse == true) && (typingHidMouse == false)) { // Draw mouse at the new position. - invertCell(mouseX, mouseY); + drawTextMouse(mouseX, mouseY); } oldDrawnMouseX = mouseX; @@ -1991,20 +2030,43 @@ public class TApplication implements Runnable { getScreen().unsetImageRow(mouseY); } } + + if (inScreenSelection) { + getScreen().setSelection(screenSelectionX0, screenSelectionY0, + screenSelectionX1, screenSelectionY1, screenSelectionRectangle); + } + if ((textMouse == true) && (typingHidMouse == false)) { - invertCell(mouseX, mouseY); + drawTextMouse(mouseX, mouseY); } oldDrawnMouseX = mouseX; oldDrawnMouseY = mouseY; // Place the cursor if it is visible if (!menuIsActive) { + + int visibleWindowCount = 0; + for (TWindow window: sorted) { + if (window.isShown()) { + visibleWindowCount++; + } + } + if (visibleWindowCount == 0) { + // No windows are visible, only the desktop. Allow it to + // have the cursor. + if (desktop != null) { + sorted.add(desktop); + } + } + TWidget activeWidget = null; if (sorted.size() > 0) { activeWidget = sorted.get(sorted.size() - 1).getActiveChild(); + int cursorClipTop = desktopTop; + int cursorClipBottom = desktopBottom; if (activeWidget.isCursorVisible()) { - if ((activeWidget.getCursorAbsoluteY() < desktopBottom) - && (activeWidget.getCursorAbsoluteY() > desktopTop) + if ((activeWidget.getCursorAbsoluteY() <= cursorClipBottom) + && (activeWidget.getCursorAbsoluteY() >= cursorClipTop) ) { getScreen().putCursor(true, activeWidget.getCursorAbsoluteX(), @@ -2163,9 +2225,6 @@ public class TApplication implements Runnable { assert (!window.isActive()); if (activeWindow != null) { - // TODO: see if this assertion is really necessary. - // assert (activeWindow.getZ() == 0); - activeWindow.setActive(false); // Increment every window Z that is on top of window