X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2FTWindow.java;h=19c96fd141d2550209a9ca8fb14ae53bcbfbc378;hb=eb29bbb5ec70c43895dd0f053630c7e3cd402cba;hp=e15092e5c07c29894be0cfa08e182914765689c4;hpb=2b9c27db318b916730aa04f2b41bd3bff795a5dc;p=fanfix.git diff --git a/src/jexer/TWindow.java b/src/jexer/TWindow.java index e15092e..19c96fd 100644 --- a/src/jexer/TWindow.java +++ b/src/jexer/TWindow.java @@ -1,35 +1,36 @@ -/** +/* * Jexer - Java Text User Interface * - * License: LGPLv3 or later - * - * This module is licensed under the GNU Lesser General Public License - * Version 3. Please see the file "COPYING" in this directory for more - * information about the GNU Lesser General Public License Version 3. + * The MIT License (MIT) * - * Copyright (C) 2015 Kevin Lamonte + * Copyright (C) 2017 Kevin Lamonte * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see - * http://www.gnu.org/licenses/, or write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * @author Kevin Lamonte [kevin.lamonte@gmail.com] * @version 1 */ 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.*; @@ -48,30 +48,44 @@ import static jexer.TKeypress.*; */ public class TWindow extends TWidget { + // ------------------------------------------------------------------------ + // Public constants ------------------------------------------------------- + // ------------------------------------------------------------------------ + /** - * Window's parent TApplication. + * Window is resizable (default yes). */ - private TApplication application; + public static final int RESIZABLE = 0x01; /** - * Get this TWindow's parent TApplication. - * - * @return this TWindow's parent TApplication + * Window is modal (default no). */ - @Override - public final TApplication getApplication() { - return application; - } + public static final int MODAL = 0x02; /** - * Get the Screen. - * - * @return the Screen + * Window is centered (default no). */ - @Override - public final Screen getScreen() { - return application.getScreen(); - } + 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 ----------------------------------------------- + // ------------------------------------------------------------------------ + + /** + * Window flags. Note package private access. + */ + int flags = RESIZABLE; /** * Window title. @@ -96,25 +110,34 @@ public class TWindow extends TWidget { this.title = title; } - /** - * Window is resizable (default yes). - */ - public static final int RESIZABLE = 0x01; + // ------------------------------------------------------------------------ + // TApplication integration ----------------------------------------------- + // ------------------------------------------------------------------------ /** - * Window is modal (default no). + * Window's parent TApplication. */ - public static final int MODAL = 0x02; + private TApplication application; /** - * Window is centered (default no). + * Get this TWindow's parent TApplication. + * + * @return this TWindow's parent TApplication */ - public static final int CENTERED = 0x04; + @Override + public final TApplication getApplication() { + return application; + } /** - * Window flags. + * Get the Screen. + * + * @return the Screen */ - private int flags = RESIZABLE; + @Override + public final Screen getScreen() { + return application.getScreen(); + } /** * Z order. Lower number means more in-front. @@ -139,17 +162,90 @@ public class TWindow extends TWidget { this.z = z; } + /** + * Window's keyboard shortcuts. Any key in this set will be passed to + * the window directly rather than processed through the menu + * accelerators. + */ + private HashSet keyboardShortcuts = new HashSet(); + + /** + * Add a keypress to be overridden for this window. + * + * @param key the key to start taking control of + */ + protected void addShortcutKeypress(final TKeypress key) { + keyboardShortcuts.add(key); + } + + /** + * Remove a keypress to be overridden for this window. + * + * @param key the key to stop taking control of + */ + protected void removeShortcutKeypress(final TKeypress key) { + keyboardShortcuts.remove(key); + } + + /** + * Remove all keypresses to be overridden for this window. + */ + protected void clearShortcutKeypresses() { + keyboardShortcuts.clear(); + } + + /** + * Determine if a keypress is overridden for this window. + * + * @param key the key to check + * @return true if this window wants to process this key on its own + */ + public boolean isShortcutKeypress(final TKeypress key) { + return keyboardShortcuts.contains(key); + } + + /** + * A window may have a status bar associated with it. TApplication will + * draw this status bar last, and will also route events to it first + * before the window. + */ + protected TStatusBar statusBar = null; + + /** + * Get the window's status bar, or null if it does not have one. + * + * @return the status bar, or null + */ + public TStatusBar getStatusBar() { + return statusBar; + } + + /** + * Set the window's status bar to a new one. + * + * @param text the status bar text + * @return the status bar + */ + public TStatusBar newStatusBar(final String text) { + statusBar = new TStatusBar(this, text); + return statusBar; + } + + // ------------------------------------------------------------------------ + // Window movement/resizing support --------------------------------------- + // ------------------------------------------------------------------------ + /** * If true, then the user clicked on the title bar and is moving the * window. */ - private boolean inWindowMove = false; + protected boolean inWindowMove = false; /** * If true, then the user clicked on the bottom right corner and is * resizing the window. */ - private boolean inWindowResize = false; + protected boolean inWindowResize = false; /** * If true, then the user selected "Size/Move" (or hit Ctrl-F5) and is @@ -187,6 +283,184 @@ public class TWindow extends TWidget { private int restoreWindowX; private int restoreWindowY; + /** + * Set the maximum width for this window. + * + * @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. + */ + public final void center() { + if ((flags & CENTERED) != 0) { + if (getWidth() < getScreen().getWidth()) { + setX((getScreen().getWidth() - getWidth()) / 2); + } else { + setX(0); + } + setY(((application.getDesktopBottom() + - application.getDesktopTop()) - getHeight()) / 2); + if (getY() < 0) { + setY(0); + } + setY(getY() + application.getDesktopTop()); + } + } + + /** + * Maximize window. + */ + public void maximize() { + if (maximized) { + return; + } + + restoreWindowWidth = getWidth(); + restoreWindowHeight = getHeight(); + restoreWindowX = getX(); + restoreWindowY = getY(); + setWidth(getScreen().getWidth()); + setHeight(application.getDesktopBottom() - 1); + setX(0); + setY(1); + maximized = true; + } + + /** + * Restore (unmaximize) window. + */ + public void restore() { + if (!maximized) { + return; + } + + setWidth(restoreWindowWidth); + setHeight(restoreWindowHeight); + setX(restoreWindowX); + setY(restoreWindowY); + 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 ----------------------------------------------------------- + // ------------------------------------------------------------------------ + /** * Public constructor. Window will be located at (0, 0). * @@ -274,23 +548,29 @@ public class TWindow extends TWidget { application.addWindow(this); } + // ------------------------------------------------------------------------ + // General behavior ------------------------------------------------------- + // ------------------------------------------------------------------------ + /** - * Recenter the window on-screen. + * See if this window is undergoing any movement/resize/etc. + * + * @return true if the window is moving */ - public final void center() { - if ((flags & CENTERED) != 0) { - if (getWidth() < getScreen().getWidth()) { - setX((getScreen().getWidth() - getWidth()) / 2); - } else { - setX(0); - } - setY(((application.getDesktopBottom() - - application.getDesktopTop()) - getHeight()) / 2); - if (getY() < 0) { - setY(0); - } - setY(getY() + application.getDesktopTop()); + 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; } /** @@ -306,51 +586,24 @@ public class TWindow extends TWidget { } /** - * Returns true if the mouse is currently on the close button. - * - * @return true if mouse is currently on the close button - */ - private boolean mouseOnClose() { - if ((mouse != null) - && (mouse.getAbsoluteY() == getY()) - && (mouse.getAbsoluteX() == getX() + 3) - ) { - return true; - } - return false; - } - - /** - * Returns true if the mouse is currently on the maximize/restore button. + * Returns true if this window has a close box. * - * @return true if the mouse is currently on the maximize/restore button + * @return true if this window has a close box */ - private boolean mouseOnMaximize() { - if ((mouse != null) - && !isModal() - && (mouse.getAbsoluteY() == getY()) - && (mouse.getAbsoluteX() == getX() + getWidth() - 4) - ) { + public final boolean hasCloseBox() { + if ((flags & NOCLOSEBOX) != 0) { return true; } return false; } /** - * Returns true if the mouse is currently on the resizable lower right - * corner. + * Returns true if this window has a maximize/zoom box. * - * @return true if the mouse is currently on the resizable lower right - * corner + * @return true if this window has a maximize/zoom box */ - private boolean mouseOnResize() { - if (((flags & RESIZABLE) != 0) - && !isModal() - && (mouse != null) - && (mouse.getAbsoluteY() == getY() + getHeight() - 1) - && ((mouse.getAbsoluteX() == getX() + getWidth() - 1) - || (mouse.getAbsoluteX() == getX() + getWidth() - 2)) - ) { + public final boolean hasZoomBox() { + if ((flags & NOZOOMBOX) != 0) { return true; } return false; @@ -361,21 +614,21 @@ public class TWindow extends TWidget { * * @return the background color */ - public final CellAttributes getBackground() { + public CellAttributes getBackground() { if (!isModal() && (inWindowMove || inWindowResize || inKeyboardResize) ) { - assert (getActive()); + assert (isActive()); return getTheme().getColor("twindow.background.windowmove"); } else if (isModal() && inWindowMove) { - assert (getActive()); + assert (isActive()); return getTheme().getColor("twindow.background.modal"); } else if (isModal()) { - if (getActive()) { + if (isActive()) { return getTheme().getColor("twindow.background.modal"); } return getTheme().getColor("twindow.background.modal.inactive"); - } else if (getActive()) { + } else if (isActive()) { assert (!isModal()); return getTheme().getColor("twindow.background"); } else { @@ -389,22 +642,22 @@ public class TWindow extends TWidget { * * @return the border color */ - private CellAttributes getBorder() { + public CellAttributes getBorder() { if (!isModal() && (inWindowMove || inWindowResize || inKeyboardResize) ) { - assert (getActive()); + assert (isActive()); return getTheme().getColor("twindow.border.windowmove"); } else if (isModal() && inWindowMove) { - assert (getActive()); + assert (isActive()); return getTheme().getColor("twindow.border.modal.windowmove"); } else if (isModal()) { - if (getActive()) { + if (isActive()) { return getTheme().getColor("twindow.border.modal"); } else { return getTheme().getColor("twindow.border.modal.inactive"); } - } else if (getActive()) { + } else if (isActive()) { assert (!isModal()); return getTheme().getColor("twindow.border"); } else { @@ -422,32 +675,24 @@ public class TWindow extends TWidget { if (!isModal() && (inWindowMove || inWindowResize || inKeyboardResize) ) { - assert (getActive()); + assert (isActive()); return 1; } else if (isModal() && inWindowMove) { - assert (getActive()); + assert (isActive()); return 1; } else if (isModal()) { - if (getActive()) { + if (isActive()) { return 2; } else { return 1; } - } else if (getActive()) { + } else if (isActive()) { return 2; } else { return 1; } } - /** - * Subclasses should override this method to cleanup resources. This is - * called by application.closeWindow(). - */ - public void onClose() { - // Default: do nothing - } - /** * Called by TApplication.drawChildren() to render on screen. */ @@ -464,32 +709,34 @@ public class TWindow extends TWidget { // Draw the title int titleLeft = (getWidth() - title.length() - 2) / 2; putCharXY(titleLeft, 0, ' ', border); - putStrXY(titleLeft + 1, 0, title); + putStringXY(titleLeft + 1, 0, title); putCharXY(titleLeft + title.length() + 1, 0, ' ', border); - if (getActive()) { + if (isActive()) { // Draw the close button - putCharXY(2, 0, '[', border); - putCharXY(4, 0, ']', border); - if (mouseOnClose() && mouse.getMouse1()) { - 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); - if (mouseOnMaximize() && mouse.getMouse1()) { + if (mouseOnMaximize() && mouse.isMouse1()) { putCharXY(getWidth() - 4, 0, GraphicsChars.CP437[0x0F], getTheme().getColor("twindow.border.windowmove")); } else { @@ -515,6 +762,105 @@ public class TWindow extends TWidget { } } + // ------------------------------------------------------------------------ + // Event handlers --------------------------------------------------------- + // ------------------------------------------------------------------------ + + /** + * Returns true if the mouse is currently on the close button. + * + * @return true if mouse is currently on the close button + */ + protected boolean mouseOnClose() { + if ((flags & NOCLOSEBOX) != 0) { + return false; + } + if ((mouse != null) + && (mouse.getAbsoluteY() == getY()) + && (mouse.getAbsoluteX() == getX() + 3) + ) { + return true; + } + return false; + } + + /** + * Returns true if the mouse is currently on the maximize/restore button. + * + * @return true if the mouse is currently on the maximize/restore button + */ + protected boolean mouseOnMaximize() { + if ((flags & NOZOOMBOX) != 0) { + return false; + } + if ((mouse != null) + && !isModal() + && (mouse.getAbsoluteY() == getY()) + && (mouse.getAbsoluteX() == getX() + getWidth() - 4) + ) { + return true; + } + return false; + } + + /** + * Returns true if the mouse is currently on the resizable lower right + * corner. + * + * @return true if the mouse is currently on the resizable lower right + * corner + */ + protected boolean mouseOnResize() { + if (((flags & RESIZABLE) != 0) + && !isModal() + && (mouse != null) + && (mouse.getAbsoluteY() == getY() + getHeight() - 1) + && ((mouse.getAbsoluteX() == getX() + getWidth() - 1) + || (mouse.getAbsoluteX() == getX() + getWidth() - 2)) + ) { + return true; + } + return false; + } + + /** + * Subclasses should override this method to cleanup resources. This is + * called by application.closeWindow(). + */ + public void onClose() { + // Default: do nothing + } + + /** + * Called by application.switchWindow() when this window gets the + * focus, and also by application.addWindow(). + */ + public void onFocus() { + // Default: do nothing + } + + /** + * Called by application.switchWindow() when another window gets the + * focus. + */ + public void onUnfocus() { + // 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. * @@ -523,12 +869,11 @@ public class TWindow extends TWidget { @Override public void onMouseDown(final TMouseEvent mouse) { this.mouse = mouse; - application.setRepaint(); inKeyboardResize = false; if ((mouse.getAbsoluteY() == getY()) - && mouse.getMouse1() + && mouse.isMouse1() && (getX() <= mouse.getAbsoluteX()) && (mouse.getAbsoluteX() < getX() + getWidth()) && !mouseOnClose() @@ -558,36 +903,17 @@ public class TWindow extends TWidget { return; } + // Give the shortcut bar a shot at this. + if (statusBar != null) { + if (statusBar.statusBarMouseDown(mouse)) { + return; + } + } + // I didn't take it, pass it on to my children super.onMouseDown(mouse); } - /** - * Maximize window. - */ - private void maximize() { - restoreWindowWidth = getWidth(); - restoreWindowHeight = getHeight(); - restoreWindowX = getX(); - restoreWindowY = getY(); - setWidth(getScreen().getWidth()); - setHeight(application.getDesktopBottom() - 1); - setX(0); - setY(1); - maximized = true; - } - - /** - * Restote (unmaximize) window. - */ - private void restore() { - setWidth(restoreWindowWidth); - setHeight(restoreWindowHeight); - setX(restoreWindowX); - setY(restoreWindowY); - maximized = false; - } - /** * Handle mouse button releases. * @@ -596,28 +922,27 @@ public class TWindow extends TWidget { @Override public void onMouseUp(final TMouseEvent mouse) { this.mouse = mouse; - application.setRepaint(); - if ((inWindowMove) && (mouse.getMouse1())) { + if ((inWindowMove) && (mouse.isMouse1())) { // Stop moving window inWindowMove = false; return; } - if ((inWindowResize) && (mouse.getMouse1())) { + if ((inWindowResize) && (mouse.isMouse1())) { // Stop resizing window inWindowResize = false; return; } - if (mouse.getMouse1() && mouseOnClose()) { + if (mouse.isMouse1() && mouseOnClose()) { // Close window application.closeWindow(this); return; } if ((mouse.getAbsoluteY() == getY()) - && mouse.getMouse1() + && mouse.isMouse1() && mouseOnMaximize()) { if (maximized) { // Restore @@ -632,6 +957,13 @@ public class TWindow extends TWidget { return; } + // Give the shortcut bar a shot at this. + if (statusBar != null) { + if (statusBar.statusBarMouseUp(mouse)) { + return; + } + } + // I didn't take it, pass it on to my children super.onMouseUp(mouse); } @@ -644,7 +976,6 @@ public class TWindow extends TWidget { @Override public void onMouseMotion(final TMouseEvent mouse) { this.mouse = mouse; - application.setRepaint(); if (inWindowMove) { // Move window over @@ -654,10 +985,20 @@ public class TWindow extends TWidget { if (getY() < application.getDesktopTop()) { setY(application.getDesktopTop()); } + // Don't go below the status bar + if (getY() >= application.getDesktopBottom()) { + setY(application.getDesktopBottom() - 1); + } return; } 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)); @@ -702,6 +1043,11 @@ public class TWindow extends TWidget { return; } + // Give the shortcut bar a shot at this. + if (statusBar != null) { + statusBar.statusBarMouseMotion(mouse); + } + // I didn't take it, pass it on to my children super.onMouseMotion(mouse); } @@ -716,8 +1062,8 @@ public class TWindow extends TWidget { if (inKeyboardResize) { - // ESC - Exit size/move - if (keypress.equals(kbEsc)) { + // ESC or ENTER - Exit size/move + if (keypress.equals(kbEsc) || keypress.equals(kbEnter)) { inKeyboardResize = false; } @@ -741,65 +1087,98 @@ public class TWindow extends TWidget { setY(getY() - 1); } } - if (keypress.equals(kbShiftLeft)) { - if (getWidth() > minimumWindowWidth) { - 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) { - setWidth(getWidth() + 1); + if (keypress.equals(kbShiftRight)) { + if ((getWidth() < maximumWindowWidth) + || (maximumWindowWidth <= 0) + ) { + setWidth(getWidth() + 1); + } } - } - if (keypress.equals(kbShiftUp)) { - if (getHeight() > minimumWindowHeight) { - setHeight(getHeight() - 1); + if (keypress.equals(kbShiftUp)) { + if ((getHeight() > minimumWindowHeight) + || (minimumWindowHeight <= 0) + ) { + setHeight(getHeight() - 1); + } } - } - if (keypress.equals(kbShiftDown)) { - if (getHeight() < maximumWindowHeight) { - 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())); + + } // if ((flags & RESIZABLE) != 0) return; } + // Give the shortcut bar a shot at this. + if (statusBar != null) { + if (statusBar.statusBarKeypress(keypress)) { + return; + } + } + // These keystrokes will typically not be seen unless a subclass // 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); @@ -817,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); @@ -856,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; + } + + if (menu.getId() == TMenu.MID_WINDOW_MOVE) { + inKeyboardResize = true; + return; } - 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); @@ -985,10 +1379,10 @@ public class TWindow extends TWidget { * @param str string to draw * @param attr attributes to use (bold, foreColor, backColor) */ - public final void putStrXY(final int x, final int y, final String str, + public final void putStringXY(final int x, final int y, final String str, final CellAttributes attr) { - getScreen().putStrXY(x, y, str, attr); + getScreen().putStringXY(x, y, str, attr); } /** @@ -999,8 +1393,8 @@ public class TWindow extends TWidget { * @param y row coordinate. 0 is the top-most row. * @param str string to draw */ - public final void putStrXY(final int x, final int y, final String str) { - getScreen().putStrXY(x, y, str); + public final void putStringXY(final int x, final int y, final String str) { + getScreen().putStringXY(x, y, str); } /** @@ -1033,5 +1427,4 @@ public class TWindow extends TWidget { getScreen().hLineXY(x, y, n, ch, attr); } - }