X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2FTWindow.java;h=19c96fd141d2550209a9ca8fb14ae53bcbfbc378;hb=eb29bbb5ec70c43895dd0f053630c7e3cd402cba;hp=32d94b928a48add6a82c1caf690d97b3b41c7638;hpb=2ce6dab2bbd951e6d0f09f94759efda5ee4b65ac;p=fanfix.git diff --git a/src/jexer/TWindow.java b/src/jexer/TWindow.java index 32d94b9..19c96fd 100644 --- a/src/jexer/TWindow.java +++ b/src/jexer/TWindow.java @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (C) 2016 Kevin Lamonte + * Copyright (C) 2017 Kevin Lamonte * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -30,6 +30,7 @@ package jexer; import java.util.HashSet; +import jexer.backend.Screen; import jexer.bits.Cell; import jexer.bits.CellAttributes; import jexer.bits.GraphicsChars; @@ -38,7 +39,6 @@ import jexer.event.TKeypressEvent; import jexer.event.TMenuEvent; import jexer.event.TMouseEvent; import jexer.event.TResizeEvent; -import jexer.io.Screen; import jexer.menu.TMenu; import static jexer.TCommand.*; import static jexer.TKeypress.*; @@ -67,6 +67,17 @@ public class TWindow extends TWidget { */ public static final int CENTERED = 0x04; + /** + * Window has no close box (default no). Window can still be closed via + * TApplication.closeWindow() and TWindow.close(). + */ + public static final int NOCLOSEBOX = 0x08; + + /** + * Window has no maximize box (default no). + */ + public static final int NOZOOMBOX = 0x10; + // ------------------------------------------------------------------------ // Common window attributes ----------------------------------------------- // ------------------------------------------------------------------------ @@ -278,9 +289,60 @@ public class TWindow extends TWidget { * @param maximumWindowWidth new maximum width */ public final void setMaximumWindowWidth(final int maximumWindowWidth) { + if ((maximumWindowWidth != -1) + && (maximumWindowWidth < minimumWindowWidth + 1) + ) { + throw new IllegalArgumentException("Maximum window width cannot " + + "be smaller than minimum window width + 1"); + } this.maximumWindowWidth = maximumWindowWidth; } + /** + * Set the minimum width for this window. + * + * @param minimumWindowWidth new minimum width + */ + public final void setMinimumWindowWidth(final int minimumWindowWidth) { + if ((maximumWindowWidth != -1) + && (minimumWindowWidth > maximumWindowWidth - 1) + ) { + throw new IllegalArgumentException("Minimum window width cannot " + + "be larger than maximum window width - 1"); + } + this.minimumWindowWidth = minimumWindowWidth; + } + + /** + * Set the maximum height for this window. + * + * @param maximumWindowHeight new maximum height + */ + public final void setMaximumWindowHeight(final int maximumWindowHeight) { + if ((maximumWindowHeight != -1) + && (maximumWindowHeight < minimumWindowHeight + 1) + ) { + throw new IllegalArgumentException("Maximum window height cannot " + + "be smaller than minimum window height + 1"); + } + this.maximumWindowHeight = maximumWindowHeight; + } + + /** + * Set the minimum height for this window. + * + * @param minimumWindowHeight new minimum height + */ + public final void setMinimumWindowHeight(final int minimumWindowHeight) { + if ((maximumWindowHeight != -1) + && (minimumWindowHeight > maximumWindowHeight - 1) + ) { + throw new IllegalArgumentException("Minimum window height cannot " + + "be larger than maximum window height - 1"); + } + this.minimumWindowHeight = minimumWindowHeight; + } + /** * Recenter the window on-screen. */ @@ -303,7 +365,11 @@ public class TWindow extends TWidget { /** * Maximize window. */ - private void maximize() { + public void maximize() { + if (maximized) { + return; + } + restoreWindowWidth = getWidth(); restoreWindowHeight = getHeight(); restoreWindowX = getX(); @@ -316,9 +382,13 @@ public class TWindow extends TWidget { } /** - * Restote (unmaximize) window. + * Restore (unmaximize) window. */ - private void restore() { + public void restore() { + if (!maximized) { + return; + } + setWidth(restoreWindowWidth); setHeight(restoreWindowHeight); setX(restoreWindowX); @@ -326,6 +396,67 @@ public class TWindow extends TWidget { maximized = false; } + // ------------------------------------------------------------------------ + // Window visibility ------------------------------------------------------ + // ------------------------------------------------------------------------ + + /** + * Hidden flag. A hidden window will still have its onIdle() called, and + * will also have onClose() called at application exit. Note package + * private access: TApplication will force hidden false if a modal window + * is active. + */ + boolean hidden = false; + + /** + * Returns true if this window is hidden. + * + * @return true if this window is hidden, false if the window is shown + */ + public final boolean isHidden() { + return hidden; + } + + /** + * Returns true if this window is shown. + * + * @return true if this window is shown, false if the window is hidden + */ + public final boolean isShown() { + return !hidden; + } + + /** + * Hide window. A hidden window will still have its onIdle() called, and + * will also have onClose() called at application exit. Hidden windows + * will not receive any other events. + */ + public void hide() { + application.hideWindow(this); + } + + /** + * Show window. + */ + public void show() { + application.showWindow(this); + } + + /** + * Activate window (bring to top and receive events). + */ + public void activate() { + application.activateWindow(this); + } + + /** + * Close window. Note that windows without a close box can still be + * closed by calling the close() method. + */ + public void close() { + application.closeWindow(this); + } + // ------------------------------------------------------------------------ // Constructors ----------------------------------------------------------- // ------------------------------------------------------------------------ @@ -421,6 +552,27 @@ public class TWindow extends TWidget { // General behavior ------------------------------------------------------- // ------------------------------------------------------------------------ + /** + * See if this window is undergoing any movement/resize/etc. + * + * @return true if the window is moving + */ + public boolean inMovements() { + if (inWindowResize || inWindowMove || inKeyboardResize) { + return true; + } + return false; + } + + /** + * Stop any pending movement/resize/etc. + */ + public void stopMovements() { + inWindowResize = false; + inWindowMove = false; + inKeyboardResize = false; + } + /** * Returns true if this window is modal. * @@ -433,12 +585,36 @@ public class TWindow extends TWidget { return true; } + /** + * Returns true if this window has a close box. + * + * @return true if this window has a close box + */ + public final boolean hasCloseBox() { + if ((flags & NOCLOSEBOX) != 0) { + return true; + } + return false; + } + + /** + * Returns true if this window has a maximize/zoom box. + * + * @return true if this window has a maximize/zoom box + */ + public final boolean hasZoomBox() { + if ((flags & NOZOOMBOX) != 0) { + return true; + } + return false; + } + /** * Retrieve the background color. * * @return the background color */ - public final CellAttributes getBackground() { + public CellAttributes getBackground() { if (!isModal() && (inWindowMove || inWindowResize || inKeyboardResize) ) { @@ -539,22 +715,24 @@ public class TWindow extends TWidget { if (isActive()) { // Draw the close button - putCharXY(2, 0, '[', border); - putCharXY(4, 0, ']', border); - if (mouseOnClose() && mouse.isMouse1()) { - putCharXY(3, 0, GraphicsChars.CP437[0x0F], - !isModal() - ? getTheme().getColor("twindow.border.windowmove") - : getTheme().getColor("twindow.border.modal.windowmove")); - } else { - putCharXY(3, 0, GraphicsChars.CP437[0xFE], - !isModal() - ? getTheme().getColor("twindow.border.windowmove") - : getTheme().getColor("twindow.border.modal.windowmove")); + if ((flags & NOCLOSEBOX) == 0) { + putCharXY(2, 0, '[', border); + putCharXY(4, 0, ']', border); + if (mouseOnClose() && mouse.isMouse1()) { + putCharXY(3, 0, GraphicsChars.CP437[0x0F], + !isModal() + ? getTheme().getColor("twindow.border.windowmove") + : getTheme().getColor("twindow.border.modal.windowmove")); + } else { + putCharXY(3, 0, GraphicsChars.CP437[0xFE], + !isModal() + ? getTheme().getColor("twindow.border.windowmove") + : getTheme().getColor("twindow.border.modal.windowmove")); + } } // Draw the maximize button - if (!isModal()) { + if (!isModal() && ((flags & NOZOOMBOX) == 0)) { putCharXY(getWidth() - 5, 0, '[', border); putCharXY(getWidth() - 3, 0, ']', border); @@ -593,7 +771,10 @@ public class TWindow extends TWidget { * * @return true if mouse is currently on the close button */ - private boolean mouseOnClose() { + protected boolean mouseOnClose() { + if ((flags & NOCLOSEBOX) != 0) { + return false; + } if ((mouse != null) && (mouse.getAbsoluteY() == getY()) && (mouse.getAbsoluteX() == getX() + 3) @@ -608,7 +789,10 @@ public class TWindow extends TWidget { * * @return true if the mouse is currently on the maximize/restore button */ - private boolean mouseOnMaximize() { + protected boolean mouseOnMaximize() { + if ((flags & NOZOOMBOX) != 0) { + return false; + } if ((mouse != null) && !isModal() && (mouse.getAbsoluteY() == getY()) @@ -626,7 +810,7 @@ public class TWindow extends TWidget { * @return true if the mouse is currently on the resizable lower right * corner */ - private boolean mouseOnResize() { + protected boolean mouseOnResize() { if (((flags & RESIZABLE) != 0) && !isModal() && (mouse != null) @@ -663,6 +847,20 @@ public class TWindow extends TWidget { // Default: do nothing } + /** + * Called by application.hideWindow(). + */ + public void onHide() { + // Default: do nothing + } + + /** + * Called by application.showWindow(). + */ + public void onShow() { + // Default: do nothing + } + /** * Handle mouse button presses. * @@ -795,6 +993,12 @@ public class TWindow extends TWidget { } if (inWindowResize) { + // Do not permit resizing below the status line + if (mouse.getAbsoluteY() == application.getDesktopBottom()) { + inWindowResize = false; + return; + } + // Move window over setWidth(resizeWindowWidth + (mouse.getAbsoluteX() - moveWindowMouseX)); @@ -883,38 +1087,46 @@ public class TWindow extends TWidget { setY(getY() - 1); } } - if (keypress.equals(kbShiftLeft)) { - if ((getWidth() > minimumWindowWidth) - || (minimumWindowWidth <= 0) - ) { - setWidth(getWidth() - 1); + + /* + * Only permit keyboard resizing if the window was RESIZABLE. + */ + if ((flags & RESIZABLE) != 0) { + + if (keypress.equals(kbShiftLeft)) { + if ((getWidth() > minimumWindowWidth) + || (minimumWindowWidth <= 0) + ) { + setWidth(getWidth() - 1); + } } - } - if (keypress.equals(kbShiftRight)) { - if ((getWidth() < maximumWindowWidth) - || (maximumWindowWidth <= 0) - ) { - setWidth(getWidth() + 1); + if (keypress.equals(kbShiftRight)) { + if ((getWidth() < maximumWindowWidth) + || (maximumWindowWidth <= 0) + ) { + setWidth(getWidth() + 1); + } } - } - if (keypress.equals(kbShiftUp)) { - if ((getHeight() > minimumWindowHeight) - || (minimumWindowHeight <= 0) - ) { - setHeight(getHeight() - 1); + if (keypress.equals(kbShiftUp)) { + if ((getHeight() > minimumWindowHeight) + || (minimumWindowHeight <= 0) + ) { + setHeight(getHeight() - 1); + } } - } - if (keypress.equals(kbShiftDown)) { - if ((getHeight() < maximumWindowHeight) - || (maximumWindowHeight <= 0) - ) { - setHeight(getHeight() + 1); + if (keypress.equals(kbShiftDown)) { + if ((getHeight() < maximumWindowHeight) + || (maximumWindowHeight <= 0) + ) { + setHeight(getHeight() + 1); + } } - } - // Pass a resize event to my children - onResize(new TResizeEvent(TResizeEvent.Type.WIDGET, - getWidth(), getHeight())); + // Pass a resize event to my children + onResize(new TResizeEvent(TResizeEvent.Type.WIDGET, + getWidth(), getHeight())); + + } // if ((flags & RESIZABLE) != 0) return; } @@ -930,37 +1142,43 @@ public class TWindow extends TWidget { // overrides onMenu() due to how TApplication dispatches // accelerators. - // Ctrl-W - close window - if (keypress.equals(kbCtrlW)) { - application.closeWindow(this); - return; - } + if (!(this instanceof TDesktop)) { - // F6 - behave like Alt-TAB - if (keypress.equals(kbF6)) { - application.switchWindow(true); - return; - } + // Ctrl-W - close window + if (keypress.equals(kbCtrlW)) { + if ((flags & NOCLOSEBOX) == 0) { + application.closeWindow(this); + } + return; + } - // Shift-F6 - behave like Shift-Alt-TAB - if (keypress.equals(kbShiftF6)) { - application.switchWindow(false); - return; - } + // F6 - behave like Alt-TAB + if (keypress.equals(kbF6)) { + application.switchWindow(true); + return; + } - // F5 - zoom - if (keypress.equals(kbF5)) { - if (maximized) { - restore(); - } else { - maximize(); + // Shift-F6 - behave like Shift-Alt-TAB + if (keypress.equals(kbShiftF6)) { + application.switchWindow(false); + return; } - } - // Ctrl-F5 - size/move - if (keypress.equals(kbCtrlF5)) { - inKeyboardResize = !inKeyboardResize; - } + // F5 - zoom + if (keypress.equals(kbF5) && ((flags & NOZOOMBOX) == 0)) { + if (maximized) { + restore(); + } else { + maximize(); + } + } + + // Ctrl-F5 - size/move + if (keypress.equals(kbCtrlF5)) { + inKeyboardResize = !inKeyboardResize; + } + + } // if (!(this instanceof TDesktop)) // I didn't take it, pass it on to my children super.onKeypress(keypress); @@ -978,33 +1196,39 @@ public class TWindow extends TWidget { // overrides onMenu() due to how TApplication dispatches // accelerators. - if (command.equals(cmWindowClose)) { - application.closeWindow(this); - return; - } + if (!(this instanceof TDesktop)) { - if (command.equals(cmWindowNext)) { - application.switchWindow(true); - return; - } + if (command.equals(cmWindowClose)) { + if ((flags & NOCLOSEBOX) == 0) { + application.closeWindow(this); + } + return; + } - if (command.equals(cmWindowPrevious)) { - application.switchWindow(false); - return; - } + if (command.equals(cmWindowNext)) { + application.switchWindow(true); + return; + } - if (command.equals(cmWindowMove)) { - inKeyboardResize = true; - return; - } + if (command.equals(cmWindowPrevious)) { + application.switchWindow(false); + return; + } - if (command.equals(cmWindowZoom)) { - if (maximized) { - restore(); - } else { - maximize(); + if (command.equals(cmWindowMove)) { + inKeyboardResize = true; + return; } - } + + if (command.equals(cmWindowZoom) && ((flags & NOZOOMBOX) == 0)) { + if (maximized) { + restore(); + } else { + maximize(); + } + } + + } // if (!(this instanceof TDesktop)) // I didn't take it, pass it on to my children super.onCommand(command); @@ -1017,34 +1241,43 @@ public class TWindow extends TWidget { */ @Override public void onMenu(final TMenuEvent menu) { - if (menu.getId() == TMenu.MID_WINDOW_CLOSE) { - application.closeWindow(this); - return; - } - if (menu.getId() == TMenu.MID_WINDOW_NEXT) { - application.switchWindow(true); - return; - } + if (!(this instanceof TDesktop)) { - if (menu.getId() == TMenu.MID_WINDOW_PREVIOUS) { - application.switchWindow(false); - return; - } + if (menu.getId() == TMenu.MID_WINDOW_CLOSE) { + if ((flags & NOCLOSEBOX) == 0) { + application.closeWindow(this); + } + return; + } - if (menu.getId() == TMenu.MID_WINDOW_MOVE) { - inKeyboardResize = true; - return; - } + if (menu.getId() == TMenu.MID_WINDOW_NEXT) { + application.switchWindow(true); + return; + } - if (menu.getId() == TMenu.MID_WINDOW_ZOOM) { - if (maximized) { - restore(); - } else { - maximize(); + if (menu.getId() == TMenu.MID_WINDOW_PREVIOUS) { + application.switchWindow(false); + return; } - return; - } + + if (menu.getId() == TMenu.MID_WINDOW_MOVE) { + inKeyboardResize = true; + return; + } + + if ((menu.getId() == TMenu.MID_WINDOW_ZOOM) + && ((flags & NOZOOMBOX) == 0) + ) { + if (maximized) { + restore(); + } else { + maximize(); + } + return; + } + + } // if (!(this instanceof TDesktop)) // I didn't take it, pass it on to my children super.onMenu(menu); @@ -1194,5 +1427,4 @@ public class TWindow extends TWidget { getScreen().hLineXY(x, y, n, ch, attr); } - }