X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2FTApplication.java;h=9d27c10f5420052103cee046baae697ca8c2bd6e;hb=12b90437b5f22c2ae6e9b9b14c3b62b60f6143e5;hp=bffe38e455f13658b4c7988c776e4c6af8d9b12a;hpb=e820d5dd4e52a787e7f53f6409bb6ff334c3ef7b;p=nikiroo-utils.git diff --git a/src/jexer/TApplication.java b/src/jexer/TApplication.java index bffe38e..9d27c10 100644 --- a/src/jexer/TApplication.java +++ b/src/jexer/TApplication.java @@ -270,7 +270,7 @@ public class TApplication implements Runnable { * constant. Someday it would be nice to have a multi-line menu or * toolbars. */ - private static final int desktopTop = 1; + private int desktopTop = 1; /** * Y coordinate of the bottom edge of the desktop. @@ -289,11 +289,42 @@ public class TApplication implements Runnable { */ private boolean focusFollowsMouse = false; + /** + * If true, display a text-based mouse cursor. + */ + private boolean textMouse = true; + + /** + * If true, hide the mouse after typing a keystroke. + */ + private boolean hideMouseWhenTyping = false; + + /** + * If true, the mouse should not be displayed because a keystroke was + * typed. + */ + private boolean typingHidMouse = false; + + /** + * If true, hide the status bar. + */ + private boolean hideStatusBar = false; + + /** + * If true, hide the menu bar. + */ + private boolean hideMenuBar = false; + /** * The list of commands to run before the next I/O check. */ private List invokeLaters = new LinkedList(); + /** + * The last time the screen was resized. + */ + private long screenResizeTime = 0; + /** * WidgetEventHandler is the main event consumer loop. There are at most * two such threads in existence: the primary for normal case and a @@ -684,8 +715,32 @@ public class TApplication implements Runnable { * Finish construction once the backend is set. */ private void TApplicationImpl() { + // Text block mouse option + if (System.getProperty("jexer.textMouse", "true").equals("false")) { + textMouse = false; + } + + // Hide mouse when typing option + if (System.getProperty("jexer.hideMouseWhenTyping", + "false").equals("true")) { + + hideMouseWhenTyping = true; + } + + // Hide status bar option + if (System.getProperty("jexer.hideStatusBar", + "false").equals("true")) { + hideStatusBar = true; + } + + // Hide menu bar option + if (System.getProperty("jexer.hideMenuBar", "false").equals("true")) { + hideMenuBar = true; + } + theme = new ColorTheme(); - desktopBottom = getScreen().getHeight() - 1; + desktopTop = (hideMenuBar ? 0 : 1); + desktopBottom = getScreen().getHeight() - 1 + (hideStatusBar ? 1 : 0); fillEventQueue = new LinkedList(); drainEventQueue = new LinkedList(); windows = new LinkedList(); @@ -717,6 +772,7 @@ public class TApplication implements Runnable { ); } } + } // ------------------------------------------------------------------------ @@ -813,6 +869,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(); @@ -861,7 +922,7 @@ public class TApplication implements Runnable { return true; } - if (command.equals(cmMenu)) { + if (command.equals(cmMenu) && (hideMenuBar == false)) { if (!modalWindowActive() && (activeMenu == null)) { if (menus.size() > 0) { menus.get(0).setActive(true); @@ -924,7 +985,7 @@ public class TApplication implements Runnable { openImage(); return true; } - if (menu.getId() == TMenu.MID_CHANGE_FONT) { + if (menu.getId() == TMenu.MID_SCREEN_OPTIONS) { new TFontChooserWindow(this); return true; } @@ -946,6 +1007,7 @@ public class TApplication implements Runnable { && !keypress.getKey().isCtrl() && (activeMenu == null) && !modalWindowActive() + && (hideMenuBar == false) ) { assert (subMenus.size() == 0); @@ -1025,17 +1087,26 @@ public class TApplication implements Runnable { if (event instanceof TResizeEvent) { TResizeEvent resize = (TResizeEvent) event; synchronized (getScreen()) { - getScreen().setDimensions(resize.getWidth(), - resize.getHeight()); + if ((System.currentTimeMillis() - screenResizeTime >= 15) + || (resize.getWidth() < getScreen().getWidth()) + || (resize.getHeight() < getScreen().getHeight()) + ) { + getScreen().setDimensions(resize.getWidth(), + resize.getHeight()); + screenResizeTime = System.currentTimeMillis(); + } desktopBottom = getScreen().getHeight() - 1; + if (hideStatusBar) { + desktopBottom++; + } mouseX = 0; mouseY = 0; oldMouseX = 0; oldMouseY = 0; } if (desktop != null) { - desktop.setDimensions(0, 0, resize.getWidth(), - resize.getHeight() - 1); + desktop.setDimensions(0, desktopTop, resize.getWidth(), + (desktopBottom - desktopTop)); desktop.onResize(resize); } @@ -1075,8 +1146,16 @@ public class TApplication implements Runnable { // Special application-wide events ----------------------------------- + if (event instanceof TKeypressEvent) { + if (hideMouseWhenTyping) { + typingHidMouse = true; + } + } + // Peek at the mouse position if (event instanceof TMouseEvent) { + typingHidMouse = false; + TMouseEvent mouse = (TMouseEvent) event; if ((mouseX != mouse.getX()) || (mouseY != mouse.getY())) { oldMouseX = mouseX; @@ -1222,6 +1301,8 @@ public class TApplication implements Runnable { } } else if (event instanceof TKeypressEvent) { dispatchToDesktop = false; + } else if (event instanceof TMenuEvent) { + dispatchToDesktop = false; } if (debugEvents) { @@ -1262,6 +1343,8 @@ public class TApplication implements Runnable { // Peek at the mouse position if (event instanceof TMouseEvent) { + typingHidMouse = false; + TMouseEvent mouse = (TMouseEvent) event; if ((mouseX != mouse.getX()) || (mouseY != mouse.getY())) { oldMouseX = mouseX; @@ -1533,6 +1616,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; @@ -1681,20 +1766,32 @@ public class TApplication implements Runnable { } } + // 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; + } + } + Cell cell = getScreen().getCharXY(x, y); if (cell.isImage()) { cell.invertImage(); + } + if (cell.getForeColorRGB() < 0) { + cell.setForeColor(cell.getForeColor().invert()); } else { - 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); - } + 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)) { @@ -1712,12 +1809,12 @@ public class TApplication implements Runnable { } } } - assert (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 (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); + } } } } @@ -1779,8 +1876,10 @@ public class TApplication implements Runnable { } } - // Draw mouse at the new position. - invertCell(mouseX, mouseY); + if ((textMouse == true) && (typingHidMouse == false)) { + // Draw mouse at the new position. + invertCell(mouseX, mouseY); + } oldDrawnMouseX = mouseX; oldDrawnMouseY = mouseY; @@ -1821,63 +1920,71 @@ public class TApplication implements Runnable { } } - // Draw the blank menubar line - reset the screen clipping first so - // it won't trim it out. - getScreen().resetClipping(); - getScreen().hLineXY(0, 0, getScreen().getWidth(), ' ', - theme.getColor("tmenu")); - // Now draw the menus. - int x = 1; - for (TMenu menu: menus) { - CellAttributes menuColor; - CellAttributes menuMnemonicColor; - if (menu.isActive()) { - menuIsActive = true; - menuColor = theme.getColor("tmenu.highlighted"); - menuMnemonicColor = theme.getColor("tmenu.mnemonic.highlighted"); - topLevel = menu; - } else { - menuColor = theme.getColor("tmenu"); - menuMnemonicColor = theme.getColor("tmenu.mnemonic"); - } - // Draw the menu title - getScreen().hLineXY(x, 0, StringUtils.width(menu.getTitle()) + 2, ' ', - menuColor); - getScreen().putStringXY(x + 1, 0, menu.getTitle(), menuColor); - // Draw the highlight character - getScreen().putCharXY(x + 1 + menu.getMnemonic().getShortcutIdx(), - 0, menu.getMnemonic().getShortcut(), menuMnemonicColor); - - if (menu.isActive()) { - ((TWindow) menu).drawChildren(); - // Reset the screen clipping so we can draw the next title. - getScreen().resetClipping(); - } - x += StringUtils.width(menu.getTitle()) + 2; - } + if (hideMenuBar == false) { - for (TMenu menu: subMenus) { - // Reset the screen clipping so we can draw the next sub-menu. + // Draw the blank menubar line - reset the screen clipping first + // so it won't trim it out. getScreen().resetClipping(); - ((TWindow) menu).drawChildren(); + getScreen().hLineXY(0, 0, getScreen().getWidth(), ' ', + theme.getColor("tmenu")); + // Now draw the menus. + int x = 1; + for (TMenu menu: menus) { + CellAttributes menuColor; + CellAttributes menuMnemonicColor; + if (menu.isActive()) { + menuIsActive = true; + menuColor = theme.getColor("tmenu.highlighted"); + menuMnemonicColor = theme.getColor("tmenu.mnemonic.highlighted"); + topLevel = menu; + } else { + menuColor = theme.getColor("tmenu"); + menuMnemonicColor = theme.getColor("tmenu.mnemonic"); + } + // Draw the menu title + getScreen().hLineXY(x, 0, + StringUtils.width(menu.getTitle()) + 2, ' ', menuColor); + getScreen().putStringXY(x + 1, 0, menu.getTitle(), menuColor); + // Draw the highlight character + getScreen().putCharXY(x + 1 + + menu.getMnemonic().getScreenShortcutIdx(), + 0, menu.getMnemonic().getShortcut(), menuMnemonicColor); + + if (menu.isActive()) { + ((TWindow) menu).drawChildren(); + // Reset the screen clipping so we can draw the next + // title. + getScreen().resetClipping(); + } + x += StringUtils.width(menu.getTitle()) + 2; + } + + for (TMenu menu: subMenus) { + // Reset the screen clipping so we can draw the next + // sub-menu. + getScreen().resetClipping(); + ((TWindow) menu).drawChildren(); + } } getScreen().resetClipping(); - // Draw the status bar of the top-level window - TStatusBar statusBar = null; - if (topLevel != null) { - statusBar = topLevel.getStatusBar(); - } - if (statusBar != null) { - getScreen().resetClipping(); - statusBar.setWidth(getScreen().getWidth()); - statusBar.setY(getScreen().getHeight() - topLevel.getY()); - statusBar.draw(); - } else { - CellAttributes barColor = new CellAttributes(); - barColor.setTo(getTheme().getColor("tstatusbar.text")); - getScreen().hLineXY(0, desktopBottom, getScreen().getWidth(), ' ', - barColor); + if (hideStatusBar == false) { + // Draw the status bar of the top-level window + TStatusBar statusBar = null; + if (topLevel != null) { + statusBar = topLevel.getStatusBar(); + } + if (statusBar != null) { + getScreen().resetClipping(); + statusBar.setWidth(getScreen().getWidth()); + statusBar.setY(getScreen().getHeight() - topLevel.getY()); + statusBar.draw(); + } else { + CellAttributes barColor = new CellAttributes(); + barColor.setTo(getTheme().getColor("tstatusbar.text")); + getScreen().hLineXY(0, desktopBottom, getScreen().getWidth(), + ' ', barColor); + } } // Draw the mouse pointer @@ -1906,18 +2013,37 @@ public class TApplication implements Runnable { getScreen().unsetImageRow(mouseY); } } - invertCell(mouseX, mouseY); + if ((textMouse == true) && (typingHidMouse == false)) { + invertCell(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(), @@ -2076,9 +2202,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 @@ -2379,6 +2502,7 @@ public class TApplication implements Runnable { if (((window.flags & TWindow.CENTERED) == 0) && ((window.flags & TWindow.ABSOLUTEXY) == 0) && (smartWindowPlacement == true) + && (!(window instanceof TDesktop)) ) { doSmartPlacement(window); @@ -2717,6 +2841,7 @@ public class TApplication implements Runnable { && (!modalWindowActive()) && (!overrideMenuWindowActive()) && (mouse.getAbsoluteY() == 0) + && (hideMenuBar == false) ) { for (TMenu menu: subMenus) { @@ -2744,6 +2869,7 @@ public class TApplication implements Runnable { && (mouse.isMouse1()) && (activeMenu != null) && (mouse.getAbsoluteY() == 0) + && (hideMenuBar == false) ) { TMenu oldMenu = activeMenu; @@ -2912,6 +3038,7 @@ public class TApplication implements Runnable { */ public final void switchMenu(final boolean forward) { assert (activeMenu != null); + assert (hideMenuBar == false); for (TMenu menu: subMenus) { menu.setActive(false); @@ -3121,7 +3248,7 @@ public class TApplication implements Runnable { TMenu toolMenu = addMenu(i18n.getString("toolMenuTitle")); toolMenu.addDefaultItem(TMenu.MID_REPAINT); toolMenu.addDefaultItem(TMenu.MID_VIEW_IMAGE); - toolMenu.addDefaultItem(TMenu.MID_CHANGE_FONT); + toolMenu.addDefaultItem(TMenu.MID_SCREEN_OPTIONS); TStatusBar toolStatusBar = toolMenu.newStatusBar(i18n. getString("toolMenuStatus")); toolStatusBar.addShortcutKeypress(kbF1, cmHelp, i18n.getString("Help"));