From df8de03f80590dde35f26616db91ad6163007b7e Mon Sep 17 00:00:00 2001 From: Kevin Lamonte Date: Mon, 9 Mar 2015 08:03:14 -0400 Subject: [PATCH] base data structures --- .gitignore | 5 + Makefile | 30 +- src/jexer/TCommand.java | 165 ++++++ src/jexer/TKeypress.java | 862 ++++++++++++++++++++++++++++ src/jexer/backend/Backend.java | 78 +++ src/jexer/bits/MnemonicString.java | 97 ++++ src/jexer/event/TCommandEvent.java | 64 +++ src/jexer/event/TInputEvent.java | 54 ++ src/jexer/event/TKeypressEvent.java | 70 +++ src/jexer/event/TMenuEvent.java | 64 +++ src/jexer/event/TMouseEvent.java | 133 +++++ src/jexer/event/TResizeEvent.java | 86 +++ src/jexer/io/Screen.java | 646 +++++++++++++++++++++ src/jexer/session/SessionInfo.java | 78 +++ src/jexer/session/TSessionInfo.java | 110 ++++ 15 files changed, 2540 insertions(+), 2 deletions(-) create mode 100644 src/jexer/TCommand.java create mode 100644 src/jexer/TKeypress.java create mode 100644 src/jexer/backend/Backend.java create mode 100644 src/jexer/bits/MnemonicString.java create mode 100644 src/jexer/event/TCommandEvent.java create mode 100644 src/jexer/event/TInputEvent.java create mode 100644 src/jexer/event/TKeypressEvent.java create mode 100644 src/jexer/event/TMenuEvent.java create mode 100644 src/jexer/event/TMouseEvent.java create mode 100644 src/jexer/event/TResizeEvent.java create mode 100644 src/jexer/io/Screen.java create mode 100644 src/jexer/session/SessionInfo.java create mode 100644 src/jexer/session/TSessionInfo.java diff --git a/.gitignore b/.gitignore index 32858aa..8184903 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,8 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + +# Editor backup files +*.java~ +*.xml~ +*Makefile~ diff --git a/Makefile b/Makefile index 34e264e..490814a 100644 --- a/Makefile +++ b/Makefile @@ -39,18 +39,44 @@ ANT_TARGET_DIR = build TARGET_DIR = classes JEXER_SRC = $(SRC_DIR)/jexer/TApplication.java \ + $(SRC_DIR)/jexer/TCommand.java \ + $(SRC_DIR)/jexer/TKeypress.java \ $(SRC_DIR)/jexer/bits/GraphicsChars.java \ $(SRC_DIR)/jexer/bits/Color.java \ $(SRC_DIR)/jexer/bits/CellAttributes.java \ $(SRC_DIR)/jexer/bits/Cell.java \ - $(SRC_DIR)/jexer/bits/ColorTheme.java + $(SRC_DIR)/jexer/bits/ColorTheme.java \ + $(SRC_DIR)/jexer/bits/MnemonicString.java \ + $(SRC_DIR)/jexer/event/TInputEvent.java \ + $(SRC_DIR)/jexer/event/TCommandEvent.java \ + $(SRC_DIR)/jexer/event/TKeypressEvent.java \ + $(SRC_DIR)/jexer/event/TMenuEvent.java \ + $(SRC_DIR)/jexer/event/TMouseEvent.java \ + $(SRC_DIR)/jexer/event/TResizeEvent.java \ + $(SRC_DIR)/jexer/session/SessionInfo.java \ + $(SRC_DIR)/jexer/session/TSessionInfo.java \ + $(SRC_DIR)/jexer/io/Screen.java \ + $(SRC_DIR)/jexer/backend/Backend.java JEXER_BIN = $(TARGET_DIR)/jexer/TApplication.class \ + $(TARGET_DIR)/jexer/TCommand.class \ + $(TARGET_DIR)/jexer/TKeypress.class \ $(TARGET_DIR)/jexer/bits/GraphicsChars.class \ $(TARGET_DIR)/jexer/bits/Color.class \ $(TARGET_DIR)/jexer/bits/CellAttributes.class \ $(TARGET_DIR)/jexer/bits/Cell.class \ - $(TARGET_DIR)/jexer/bits/ColorTheme.class + $(TARGET_DIR)/jexer/bits/ColorTheme.class \ + $(TARGET_DIR)/jexer/bits/MnemonicString.class \ + $(TARGET_DIR)/jexer/event/TInputEvent.class \ + $(TARGET_DIR)/jexer/event/TCommandEvent.class \ + $(TARGET_DIR)/jexer/event/TKeypressEvent.class \ + $(TARGET_DIR)/jexer/event/TMenuEvent.class \ + $(TARGET_DIR)/jexer/event/TMouseEvent.class \ + $(TARGET_DIR)/jexer/event/TResizeEvent.class \ + $(TARGET_DIR)/jexer/session/SessionInfo.class \ + $(TARGET_DIR)/jexer/session/TSessionInfo.class \ + $(TARGET_DIR)/jexer/io/Screen.class \ + $(TARGET_DIR)/jexer/backend/Backend.class JAVAC = javac JAVAFLAGS = -g -deprecation diff --git a/src/jexer/TCommand.java b/src/jexer/TCommand.java new file mode 100644 index 0000000..0a38903 --- /dev/null +++ b/src/jexer/TCommand.java @@ -0,0 +1,165 @@ +/** + * Jexer - Java Text User Interface + * + * Version: $Id$ + * + * Author: Kevin Lamonte, kevin.lamonte@gmail.com + * + * License: LGPLv3 or later + * + * Copyright: 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. + * + * Copyright (C) 2015 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. + * + * 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. + * + * 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 + */ +package jexer; + +/** + * This class encapsulates several kinds of user commands. A user command + * can be generated by a menu action or keyboard accelerator. + */ +public class TCommand { + + public enum Type { + /** + * Immediately abort the application (e.g. remote side closed + * connection) + */ + ABORT, + + /** + * File open dialog + */ + OPEN, + + /** + * Exit application + */ + EXIT, + + /** + * Spawn OS shell window + */ + SHELL, + + /** + * Cut selected text and copy to the clipboard + */ + CUT, + + /** + * Copy selected text to clipboard + */ + COPY, + + /** + * Paste from clipboard + */ + PASTE, + + /** + * Clear selected text without copying it to the clipboard + */ + CLEAR, + + /** + * Tile windows + */ + TILE, + + /** + * Cascade windows + */ + CASCADE, + + /** + * Close all windows + */ + CLOSE_ALL, + + /** + * Move (move/resize) window + */ + WINDOW_MOVE, + + /** + * Zoom (maximize/restore) window + */ + WINDOW_ZOOM, + + /** + * Next window (like Alt-TAB) + */ + WINDOW_NEXT, + + /** + * Previous window (like Shift-Alt-TAB) + */ + WINDOW_PREVIOUS, + + /** + * Close window + */ + WINDOW_CLOSE, + + } + + /** + * Type of command, one of EXIT, CASCADE, etc. + */ + public Type type; + + /** + * Public contructor + * + * @param type the Type of command, one of EXIT, CASCADE, etc. + */ + public TCommand(Type type) { + this.type = type; + } + + /** + * Make human-readable description of this event + */ + @Override + public String toString() { + return String.format("%s", type); + } + + static public final TCommand cmAbort = new TCommand(TCommand.Type.ABORT); + static public final TCommand cmExit = new TCommand(TCommand.Type.EXIT); + static public final TCommand cmQuit = new TCommand(TCommand.Type.EXIT); + static public final TCommand cmOpen = new TCommand(TCommand.Type.OPEN); + static public final TCommand cmShell = new TCommand(TCommand.Type.SHELL); + static public final TCommand cmCut = new TCommand(TCommand.Type.CUT); + static public final TCommand cmCopy = new TCommand(TCommand.Type.COPY); + static public final TCommand cmPaste = new TCommand(TCommand.Type.PASTE); + static public final TCommand cmClear = new TCommand(TCommand.Type.CLEAR); + static public final TCommand cmTile = new TCommand(TCommand.Type.TILE); + static public final TCommand cmCascade = new TCommand(TCommand.Type.CASCADE); + static public final TCommand cmCloseAll = new TCommand(TCommand.Type.CLOSE_ALL); + static public final TCommand cmWindowMove = new TCommand(TCommand.Type.WINDOW_MOVE); + static public final TCommand cmWindowZoom = new TCommand(TCommand.Type.WINDOW_ZOOM); + static public final TCommand cmWindowNext = new TCommand(TCommand.Type.WINDOW_NEXT); + static public final TCommand cmWindowPrevious = new TCommand(TCommand.Type.WINDOW_PREVIOUS); + static public final TCommand cmWindowClose = new TCommand(TCommand.Type.WINDOW_CLOSE); + +} diff --git a/src/jexer/TKeypress.java b/src/jexer/TKeypress.java new file mode 100644 index 0000000..4f5f0af --- /dev/null +++ b/src/jexer/TKeypress.java @@ -0,0 +1,862 @@ +/** + * Jexer - Java Text User Interface + * + * Version: $Id$ + * + * Author: Kevin Lamonte, kevin.lamonte@gmail.com + * + * License: LGPLv3 or later + * + * Copyright: 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. + * + * Copyright (C) 2015 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. + * + * 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. + * + * 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 + */ +package jexer; + +/** + * This class represents keystrokes. + */ +public class TKeypress { + + // Various special keystrokes + + /** + * "No key" + */ + static public final int NONE = 255; + + /** + * Function key F1 + */ + static public final int F1 = 1; + + /** + * Function key F2 + */ + static public final int F2 = 2; + + /** + * Function key F3 + */ + static public final int F3 = 3; + + /** + * Function key F4 + */ + static public final int F4 = 4; + + /** + * Function key F5 + */ + static public final int F5 = 5; + + /** + * Function key F6 + */ + static public final int F6 = 6; + + /** + * Function key F7 + */ + static public final int F7 = 7; + + /** + * Function key F8 + */ + static public final int F8 = 8; + + /** + * Function key F9 + */ + static public final int F9 = 9; + + /** + * Function key F10 + */ + static public final int F10 = 10; + + /** + * Function key F11 + */ + static public final int F11 = 11; + + /** + * Function key F12 + */ + static public final int F12 = 12; + + /** + * Home + */ + static public final int HOME = 20; + + /** + * End + */ + static public final int END = 21; + + /** + * Page up + */ + static public final int PGUP = 22; + + /** + * Page down + */ + static public final int PGDN = 23; + + /** + * Insert + */ + static public final int INS = 24; + + /** + * Delete + */ + static public final int DEL = 25; + + /** + * Right arrow + */ + static public final int RIGHT = 30; + + /** + * Left arrow + */ + static public final int LEFT = 31; + + /** + * Up arrow + */ + static public final int UP = 32; + + /** + * Down arrow + */ + static public final int DOWN = 33; + + /** + * Tab + */ + static public final int TAB = 40; + + /** + * Back-tab (shift-tab) + */ + static public final int BTAB = 41; + + /** + * Enter + */ + static public final int ENTER = 42; + + /** + * Escape + */ + static public final int ESC = 43; + + /** + * If true, ch is meaningless, use fnKey instead. + */ + public boolean isKey; + + /** + * Will be set to F1, F2, HOME, END, etc. if isKey is true. + */ + public int fnKey; + + /** + * Keystroke modifier ALT + */ + public boolean alt; + + /** + * Keystroke modifier CTRL + */ + public boolean ctrl; + + /** + * Keystroke modifier SHIFT + */ + public boolean shift; + + /** + * The character received + */ + public char ch; + + /** + * Convenience constructor for immutable instances + * + * @param isKey is true, this is a function key + * @param fnKey the function key code (only valid if isKey is true) + * @param ch the character (only valid if fnKey is false) + * @param alt if true, ALT was pressed with this keystroke + * @param ctrl if true, CTRL was pressed with this keystroke + * @param shift if true, SHIFT was pressed with this keystroke + */ + public TKeypress(boolean isKey, int fnKey, char ch, + boolean alt, boolean ctrl, boolean shift) { + + this.isKey = isKey; + this.fnKey = fnKey; + this.ch = ch; + this.alt = alt; + this.ctrl = ctrl; + this.shift = shift; + } + + /** + * Make human-readable description of this Keystroke. + */ + @Override + public String toString() { + if (isKey) { + switch (fnKey) { + case F1: + return String.format("%s%s%sF1", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case F2: + return String.format("%s%s%sF2", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case F3: + return String.format("%s%s%sF3", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case F4: + return String.format("%s%s%sF4", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case F5: + return String.format("%s%s%sF5", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case F6: + return String.format("%s%s%sF6", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case F7: + return String.format("%s%s%sF7", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case F8: + return String.format("%s%s%sF8", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case F9: + return String.format("%s%s%sF9", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case F10: + return String.format("%s%s%sF10", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case F11: + return String.format("%s%s%sF11", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case F12: + return String.format("%s%s%sF12", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case HOME: + return String.format("%s%s%sHOME", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case END: + return String.format("%s%s%sEND", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case PGUP: + return String.format("%s%s%sPGUP", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case PGDN: + return String.format("%s%s%sPGDN", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case INS: + return String.format("%s%s%sINS", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case DEL: + return String.format("%s%s%sDEL", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case RIGHT: + return String.format("%s%s%sRIGHT", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case LEFT: + return String.format("%s%s%sLEFT", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case UP: + return String.format("%s%s%sUP", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case DOWN: + return String.format("%s%s%sDOWN", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case TAB: + return String.format("%s%s%sTAB", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case BTAB: + return String.format("%s%s%sBTAB", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case ENTER: + return String.format("%s%s%sENTER", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + case ESC: + return String.format("%s%s%sESC", + ctrl ? "Ctrl+" : "", + alt ? "Alt+" : "", + shift ? "Shift+" : ""); + default: + return String.format("--UNKNOWN--"); + } + } else { + if (alt && !shift && !ctrl) { + // Alt-X + return String.format("Alt+%c", Character.toUpperCase(ch)); + } else if (!alt && shift && !ctrl) { + // Shift-X + return String.format("%c", ch); + } else if (!alt && !shift && ctrl) { + // Ctrl-X + return String.format("Ctrl+%c", ch); + } else if (alt && shift && !ctrl) { + // Alt-Shift-X + return String.format("Alt+Shift+%c", ch); + } else if (!alt && shift && ctrl) { + // Ctrl-Shift-X + return String.format("Ctrl+Shift+%c", ch); + } else if (alt && !shift && ctrl) { + // Ctrl-Alt-X + return String.format("Ctrl+Alt+%c", Character.toUpperCase(ch)); + } else if (alt && shift && ctrl) { + // Ctrl-Alt-Shift-X + return String.format("Ctrl+Alt+Shift+%c", + Character.toUpperCase(ch)); + } else { + // X + return String.format("%c", ch); + } + } + } + + /** + * Convert a keypress to lowercase. Function keys and ctrl keys are not + * converted. + * + * @param key keypress to convert + * @return a new instance with the key converted + */ + static public TKeypress toLower(TKeypress key) { + TKeypress newKey = new TKeypress(key.isKey, key.fnKey, key.ch, + key.alt, key.ctrl, key.shift); + if (!(key.isKey) && (key.ch >= 'A') && (key.ch <= 'Z') && (!key.ctrl)) { + newKey.shift = false; + newKey.ch += 32; + } + return newKey; + } + + /** + * Convert a keypress to uppercase. Function keys and ctrl keys are not + * converted. + * + * @param key keypress to convert + * @return a new instance with the key converted + */ + static public TKeypress toUpper(TKeypress key) { + TKeypress newKey = new TKeypress(key.isKey, key.fnKey, key.ch, + key.alt, key.ctrl, key.shift); + if (!(key.isKey) && (key.ch >= 'a') && (key.ch <= 'z') && (!key.ctrl)) { + newKey.shift = true; + newKey.ch -= 32; + } + return newKey; + } + + // Special "no-key" keypress, used to ignore undefined keystrokes + static public final TKeypress kbNoKey = new TKeypress(true, + TKeypress.NONE, ' ', false, false, false); + + // Normal keys + static public final TKeypress kbF1 = new TKeypress(true, + TKeypress.F1, ' ', false, false, false); + static public final TKeypress kbF2 = new TKeypress(true, + TKeypress.F2, ' ', false, false, false); + static public final TKeypress kbF3 = new TKeypress(true, + TKeypress.F3, ' ', false, false, false); + static public final TKeypress kbF4 = new TKeypress(true, + TKeypress.F4, ' ', false, false, false); + static public final TKeypress kbF5 = new TKeypress(true, + TKeypress.F5, ' ', false, false, false); + static public final TKeypress kbF6 = new TKeypress(true, + TKeypress.F6, ' ', false, false, false); + static public final TKeypress kbF7 = new TKeypress(true, + TKeypress.F7, ' ', false, false, false); + static public final TKeypress kbF8 = new TKeypress(true, + TKeypress.F8, ' ', false, false, false); + static public final TKeypress kbF9 = new TKeypress(true, + TKeypress.F9, ' ', false, false, false); + static public final TKeypress kbF10 = new TKeypress(true, + TKeypress.F10, ' ', false, false, false); + static public final TKeypress kbF11 = new TKeypress(true, + TKeypress.F11, ' ', false, false, false); + static public final TKeypress kbF12 = new TKeypress(true, + TKeypress.F12, ' ', false, false, false); + static public final TKeypress kbAltF1 = new TKeypress(true, + TKeypress.F1, ' ', true, false, false); + static public final TKeypress kbAltF2 = new TKeypress(true, + TKeypress.F2, ' ', true, false, false); + static public final TKeypress kbAltF3 = new TKeypress(true, + TKeypress.F3, ' ', true, false, false); + static public final TKeypress kbAltF4 = new TKeypress(true, + TKeypress.F4, ' ', true, false, false); + static public final TKeypress kbAltF5 = new TKeypress(true, + TKeypress.F5, ' ', true, false, false); + static public final TKeypress kbAltF6 = new TKeypress(true, + TKeypress.F6, ' ', true, false, false); + static public final TKeypress kbAltF7 = new TKeypress(true, + TKeypress.F7, ' ', true, false, false); + static public final TKeypress kbAltF8 = new TKeypress(true, + TKeypress.F8, ' ', true, false, false); + static public final TKeypress kbAltF9 = new TKeypress(true, + TKeypress.F9, ' ', true, false, false); + static public final TKeypress kbAltF10 = new TKeypress(true, + TKeypress.F10, ' ', true, false, false); + static public final TKeypress kbAltF11 = new TKeypress(true, + TKeypress.F11, ' ', true, false, false); + static public final TKeypress kbAltF12 = new TKeypress(true, + TKeypress.F12, ' ', true, false, false); + static public final TKeypress kbCtrlF1 = new TKeypress(true, + TKeypress.F1, ' ', false, true, false); + static public final TKeypress kbCtrlF2 = new TKeypress(true, + TKeypress.F2, ' ', false, true, false); + static public final TKeypress kbCtrlF3 = new TKeypress(true, + TKeypress.F3, ' ', false, true, false); + static public final TKeypress kbCtrlF4 = new TKeypress(true, + TKeypress.F4, ' ', false, true, false); + static public final TKeypress kbCtrlF5 = new TKeypress(true, + TKeypress.F5, ' ', false, true, false); + static public final TKeypress kbCtrlF6 = new TKeypress(true, + TKeypress.F6, ' ', false, true, false); + static public final TKeypress kbCtrlF7 = new TKeypress(true, + TKeypress.F7, ' ', false, true, false); + static public final TKeypress kbCtrlF8 = new TKeypress(true, + TKeypress.F8, ' ', false, true, false); + static public final TKeypress kbCtrlF9 = new TKeypress(true, + TKeypress.F9, ' ', false, true, false); + static public final TKeypress kbCtrlF10 = new TKeypress(true, + TKeypress.F10, ' ', false, true, false); + static public final TKeypress kbCtrlF11 = new TKeypress(true, + TKeypress.F11, ' ', false, true, false); + static public final TKeypress kbCtrlF12 = new TKeypress(true, + TKeypress.F12, ' ', false, true, false); + static public final TKeypress kbShiftF1 = new TKeypress(true, + TKeypress.F1, ' ', false, false, true); + static public final TKeypress kbShiftF2 = new TKeypress(true, + TKeypress.F2, ' ', false, false, true); + static public final TKeypress kbShiftF3 = new TKeypress(true, + TKeypress.F3, ' ', false, false, true); + static public final TKeypress kbShiftF4 = new TKeypress(true, + TKeypress.F4, ' ', false, false, true); + static public final TKeypress kbShiftF5 = new TKeypress(true, + TKeypress.F5, ' ', false, false, true); + static public final TKeypress kbShiftF6 = new TKeypress(true, + TKeypress.F6, ' ', false, false, true); + static public final TKeypress kbShiftF7 = new TKeypress(true, + TKeypress.F7, ' ', false, false, true); + static public final TKeypress kbShiftF8 = new TKeypress(true, + TKeypress.F8, ' ', false, false, true); + static public final TKeypress kbShiftF9 = new TKeypress(true, + TKeypress.F9, ' ', false, false, true); + static public final TKeypress kbShiftF10 = new TKeypress(true, + TKeypress.F10, ' ', false, false, true); + static public final TKeypress kbShiftF11 = new TKeypress(true, + TKeypress.F11, ' ', false, false, true); + static public final TKeypress kbShiftF12 = new TKeypress(true, + TKeypress.F12, ' ', false, false, true); + static public final TKeypress kbEnter = new TKeypress(true, + TKeypress.ENTER, ' ', false, false, false); + static public final TKeypress kbTab = new TKeypress(true, + TKeypress.TAB, ' ', false, false, false); + static public final TKeypress kbEsc = new TKeypress(true, + TKeypress.ESC, ' ', false, false, false); + static public final TKeypress kbHome = new TKeypress(true, + TKeypress.HOME, ' ', false, false, false); + static public final TKeypress kbEnd = new TKeypress(true, + TKeypress.END, ' ', false, false, false); + static public final TKeypress kbPgUp = new TKeypress(true, + TKeypress.PGUP, ' ', false, false, false); + static public final TKeypress kbPgDn = new TKeypress(true, + TKeypress.PGDN, ' ', false, false, false); + static public final TKeypress kbIns = new TKeypress(true, + TKeypress.INS, ' ', false, false, false); + static public final TKeypress kbDel = new TKeypress(true, + TKeypress.DEL, ' ', false, false, false); + static public final TKeypress kbUp = new TKeypress(true, + TKeypress.UP, ' ', false, false, false); + static public final TKeypress kbDown = new TKeypress(true, + TKeypress.DOWN, ' ', false, false, false); + static public final TKeypress kbLeft = new TKeypress(true, + TKeypress.LEFT, ' ', false, false, false); + static public final TKeypress kbRight = new TKeypress(true, + TKeypress.RIGHT, ' ', false, false, false); + static public final TKeypress kbAltEnter = new TKeypress(true, + TKeypress.ENTER, ' ', true, false, false); + static public final TKeypress kbAltTab = new TKeypress(true, + TKeypress.TAB, ' ', true, false, false); + static public final TKeypress kbAltEsc = new TKeypress(true, + TKeypress.ESC, ' ', true, false, false); + static public final TKeypress kbAltHome = new TKeypress(true, + TKeypress.HOME, ' ', true, false, false); + static public final TKeypress kbAltEnd = new TKeypress(true, + TKeypress.END, ' ', true, false, false); + static public final TKeypress kbAltPgUp = new TKeypress(true, + TKeypress.PGUP, ' ', true, false, false); + static public final TKeypress kbAltPgDn = new TKeypress(true, + TKeypress.PGDN, ' ', true, false, false); + static public final TKeypress kbAltIns = new TKeypress(true, + TKeypress.INS, ' ', true, false, false); + static public final TKeypress kbAltDel = new TKeypress(true, + TKeypress.DEL, ' ', true, false, false); + static public final TKeypress kbAltUp = new TKeypress(true, + TKeypress.UP, ' ', true, false, false); + static public final TKeypress kbAltDown = new TKeypress(true, + TKeypress.DOWN, ' ', true, false, false); + static public final TKeypress kbAltLeft = new TKeypress(true, + TKeypress.LEFT, ' ', true, false, false); + static public final TKeypress kbAltRight = new TKeypress(true, + TKeypress.RIGHT, ' ', true, false, false); + static public final TKeypress kbCtrlEnter = new TKeypress(true, + TKeypress.ENTER, ' ', false, true, false); + static public final TKeypress kbCtrlTab = new TKeypress(true, + TKeypress.TAB, ' ', false, true, false); + static public final TKeypress kbCtrlEsc = new TKeypress(true, + TKeypress.ESC, ' ', false, true, false); + static public final TKeypress kbCtrlHome = new TKeypress(true, + TKeypress.HOME, ' ', false, true, false); + static public final TKeypress kbCtrlEnd = new TKeypress(true, + TKeypress.END, ' ', false, true, false); + static public final TKeypress kbCtrlPgUp = new TKeypress(true, + TKeypress.PGUP, ' ', false, true, false); + static public final TKeypress kbCtrlPgDn = new TKeypress(true, + TKeypress.PGDN, ' ', false, true, false); + static public final TKeypress kbCtrlIns = new TKeypress(true, + TKeypress.INS, ' ', false, true, false); + static public final TKeypress kbCtrlDel = new TKeypress(true, + TKeypress.DEL, ' ', false, true, false); + static public final TKeypress kbCtrlUp = new TKeypress(true, + TKeypress.UP, ' ', false, true, false); + static public final TKeypress kbCtrlDown = new TKeypress(true, + TKeypress.DOWN, ' ', false, true, false); + static public final TKeypress kbCtrlLeft = new TKeypress(true, + TKeypress.LEFT, ' ', false, true, false); + static public final TKeypress kbCtrlRight = new TKeypress(true, + TKeypress.RIGHT, ' ', false, true, false); + static public final TKeypress kbShiftEnter = new TKeypress(true, + TKeypress.ENTER, ' ', false, false, true); + static public final TKeypress kbShiftTab = new TKeypress(true, + TKeypress.TAB, ' ', false, false, true); + static public final TKeypress kbBackTab = new TKeypress(true, + TKeypress.BTAB, ' ', false, false, false); + static public final TKeypress kbShiftEsc = new TKeypress(true, + TKeypress.ESC, ' ', false, false, true); + static public final TKeypress kbShiftHome = new TKeypress(true, + TKeypress.HOME, ' ', false, false, true); + static public final TKeypress kbShiftEnd = new TKeypress(true, + TKeypress.END, ' ', false, false, true); + static public final TKeypress kbShiftPgUp = new TKeypress(true, + TKeypress.PGUP, ' ', false, false, true); + static public final TKeypress kbShiftPgDn = new TKeypress(true, + TKeypress.PGDN, ' ', false, false, true); + static public final TKeypress kbShiftIns = new TKeypress(true, + TKeypress.INS, ' ', false, false, true); + static public final TKeypress kbShiftDel = new TKeypress(true, + TKeypress.DEL, ' ', false, false, true); + static public final TKeypress kbShiftUp = new TKeypress(true, + TKeypress.UP, ' ', false, false, true); + static public final TKeypress kbShiftDown = new TKeypress(true, + TKeypress.DOWN, ' ', false, false, true); + static public final TKeypress kbShiftLeft = new TKeypress(true, + TKeypress.LEFT, ' ', false, false, true); + static public final TKeypress kbShiftRight = new TKeypress(true, + TKeypress.RIGHT, ' ', false, false, true); + static public final TKeypress kbA = new TKeypress(false, + 0, 'a', false, false, false); + static public final TKeypress kbB = new TKeypress(false, + 0, 'b', false, false, false); + static public final TKeypress kbC = new TKeypress(false, + 0, 'c', false, false, false); + static public final TKeypress kbD = new TKeypress(false, + 0, 'd', false, false, false); + static public final TKeypress kbE = new TKeypress(false, + 0, 'e', false, false, false); + static public final TKeypress kbF = new TKeypress(false, + 0, 'f', false, false, false); + static public final TKeypress kbG = new TKeypress(false, + 0, 'g', false, false, false); + static public final TKeypress kbH = new TKeypress(false, + 0, 'h', false, false, false); + static public final TKeypress kbI = new TKeypress(false, + 0, 'i', false, false, false); + static public final TKeypress kbJ = new TKeypress(false, + 0, 'j', false, false, false); + static public final TKeypress kbK = new TKeypress(false, + 0, 'k', false, false, false); + static public final TKeypress kbL = new TKeypress(false, + 0, 'l', false, false, false); + static public final TKeypress kbM = new TKeypress(false, + 0, 'm', false, false, false); + static public final TKeypress kbN = new TKeypress(false, + 0, 'n', false, false, false); + static public final TKeypress kbO = new TKeypress(false, + 0, 'o', false, false, false); + static public final TKeypress kbP = new TKeypress(false, + 0, 'p', false, false, false); + static public final TKeypress kbQ = new TKeypress(false, + 0, 'q', false, false, false); + static public final TKeypress kbR = new TKeypress(false, + 0, 'r', false, false, false); + static public final TKeypress kbS = new TKeypress(false, + 0, 's', false, false, false); + static public final TKeypress kbT = new TKeypress(false, + 0, 't', false, false, false); + static public final TKeypress kbU = new TKeypress(false, + 0, 'u', false, false, false); + static public final TKeypress kbV = new TKeypress(false, + 0, 'v', false, false, false); + static public final TKeypress kbW = new TKeypress(false, + 0, 'w', false, false, false); + static public final TKeypress kbX = new TKeypress(false, + 0, 'x', false, false, false); + static public final TKeypress kbY = new TKeypress(false, + 0, 'y', false, false, false); + static public final TKeypress kbZ = new TKeypress(false, + 0, 'z', false, false, false); + static public final TKeypress kbSpace = new TKeypress(false, + 0, ' ', false, false, false); + static public final TKeypress kbAltA = new TKeypress(false, + 0, 'a', true, false, false); + static public final TKeypress kbAltB = new TKeypress(false, + 0, 'b', true, false, false); + static public final TKeypress kbAltC = new TKeypress(false, + 0, 'c', true, false, false); + static public final TKeypress kbAltD = new TKeypress(false, + 0, 'd', true, false, false); + static public final TKeypress kbAltE = new TKeypress(false, + 0, 'e', true, false, false); + static public final TKeypress kbAltF = new TKeypress(false, + 0, 'f', true, false, false); + static public final TKeypress kbAltG = new TKeypress(false, + 0, 'g', true, false, false); + static public final TKeypress kbAltH = new TKeypress(false, + 0, 'h', true, false, false); + static public final TKeypress kbAltI = new TKeypress(false, + 0, 'i', true, false, false); + static public final TKeypress kbAltJ = new TKeypress(false, + 0, 'j', true, false, false); + static public final TKeypress kbAltK = new TKeypress(false, + 0, 'k', true, false, false); + static public final TKeypress kbAltL = new TKeypress(false, + 0, 'l', true, false, false); + static public final TKeypress kbAltM = new TKeypress(false, + 0, 'm', true, false, false); + static public final TKeypress kbAltN = new TKeypress(false, + 0, 'n', true, false, false); + static public final TKeypress kbAltO = new TKeypress(false, + 0, 'o', true, false, false); + static public final TKeypress kbAltP = new TKeypress(false, + 0, 'p', true, false, false); + static public final TKeypress kbAltQ = new TKeypress(false, + 0, 'q', true, false, false); + static public final TKeypress kbAltR = new TKeypress(false, + 0, 'r', true, false, false); + static public final TKeypress kbAltS = new TKeypress(false, + 0, 's', true, false, false); + static public final TKeypress kbAltT = new TKeypress(false, + 0, 't', true, false, false); + static public final TKeypress kbAltU = new TKeypress(false, + 0, 'u', true, false, false); + static public final TKeypress kbAltV = new TKeypress(false, + 0, 'v', true, false, false); + static public final TKeypress kbAltW = new TKeypress(false, + 0, 'w', true, false, false); + static public final TKeypress kbAltX = new TKeypress(false, + 0, 'x', true, false, false); + static public final TKeypress kbAltY = new TKeypress(false, + 0, 'y', true, false, false); + static public final TKeypress kbAltZ = new TKeypress(false, + 0, 'z', true, false, false); + static public final TKeypress kbCtrlA = new TKeypress(false, + 0, 'A', false, true, false); + static public final TKeypress kbCtrlB = new TKeypress(false, + 0, 'B', false, true, false); + static public final TKeypress kbCtrlC = new TKeypress(false, + 0, 'C', false, true, false); + static public final TKeypress kbCtrlD = new TKeypress(false, + 0, 'D', false, true, false); + static public final TKeypress kbCtrlE = new TKeypress(false, + 0, 'E', false, true, false); + static public final TKeypress kbCtrlF = new TKeypress(false, + 0, 'F', false, true, false); + static public final TKeypress kbCtrlG = new TKeypress(false, + 0, 'G', false, true, false); + static public final TKeypress kbCtrlH = new TKeypress(false, + 0, 'H', false, true, false); + static public final TKeypress kbCtrlI = new TKeypress(false, + 0, 'I', false, true, false); + static public final TKeypress kbCtrlJ = new TKeypress(false, + 0, 'J', false, true, false); + static public final TKeypress kbCtrlK = new TKeypress(false, + 0, 'K', false, true, false); + static public final TKeypress kbCtrlL = new TKeypress(false, + 0, 'L', false, true, false); + static public final TKeypress kbCtrlM = new TKeypress(false, + 0, 'M', false, true, false); + static public final TKeypress kbCtrlN = new TKeypress(false, + 0, 'N', false, true, false); + static public final TKeypress kbCtrlO = new TKeypress(false, + 0, 'O', false, true, false); + static public final TKeypress kbCtrlP = new TKeypress(false, + 0, 'P', false, true, false); + static public final TKeypress kbCtrlQ = new TKeypress(false, + 0, 'Q', false, true, false); + static public final TKeypress kbCtrlR = new TKeypress(false, + 0, 'R', false, true, false); + static public final TKeypress kbCtrlS = new TKeypress(false, + 0, 'S', false, true, false); + static public final TKeypress kbCtrlT = new TKeypress(false, + 0, 'T', false, true, false); + static public final TKeypress kbCtrlU = new TKeypress(false, + 0, 'U', false, true, false); + static public final TKeypress kbCtrlV = new TKeypress(false, + 0, 'V', false, true, false); + static public final TKeypress kbCtrlW = new TKeypress(false, + 0, 'W', false, true, false); + static public final TKeypress kbCtrlX = new TKeypress(false, + 0, 'X', false, true, false); + static public final TKeypress kbCtrlY = new TKeypress(false, + 0, 'Y', false, true, false); + static public final TKeypress kbCtrlZ = new TKeypress(false, + 0, 'Z', false, true, false); + static public final TKeypress kbAltShiftA = new TKeypress(false, + 0, 'A', true, false, true); + static public final TKeypress kbAltShiftB = new TKeypress(false, + 0, 'B', true, false, true); + static public final TKeypress kbAltShiftC = new TKeypress(false, + 0, 'C', true, false, true); + static public final TKeypress kbAltShiftD = new TKeypress(false, + 0, 'D', true, false, true); + static public final TKeypress kbAltShiftE = new TKeypress(false, + 0, 'E', true, false, true); + static public final TKeypress kbAltShiftF = new TKeypress(false, + 0, 'F', true, false, true); + static public final TKeypress kbAltShiftG = new TKeypress(false, + 0, 'G', true, false, true); + static public final TKeypress kbAltShiftH = new TKeypress(false, + 0, 'H', true, false, true); + static public final TKeypress kbAltShiftI = new TKeypress(false, + 0, 'I', true, false, true); + static public final TKeypress kbAltShiftJ = new TKeypress(false, + 0, 'J', true, false, true); + static public final TKeypress kbAltShiftK = new TKeypress(false, + 0, 'K', true, false, true); + static public final TKeypress kbAltShiftL = new TKeypress(false, + 0, 'L', true, false, true); + static public final TKeypress kbAltShiftM = new TKeypress(false, + 0, 'M', true, false, true); + static public final TKeypress kbAltShiftN = new TKeypress(false, + 0, 'N', true, false, true); + static public final TKeypress kbAltShiftO = new TKeypress(false, + 0, 'O', true, false, true); + static public final TKeypress kbAltShiftP = new TKeypress(false, + 0, 'P', true, false, true); + static public final TKeypress kbAltShiftQ = new TKeypress(false, + 0, 'Q', true, false, true); + static public final TKeypress kbAltShiftR = new TKeypress(false, + 0, 'R', true, false, true); + static public final TKeypress kbAltShiftS = new TKeypress(false, + 0, 'S', true, false, true); + static public final TKeypress kbAltShiftT = new TKeypress(false, + 0, 'T', true, false, true); + static public final TKeypress kbAltShiftU = new TKeypress(false, + 0, 'U', true, false, true); + static public final TKeypress kbAltShiftV = new TKeypress(false, + 0, 'V', true, false, true); + static public final TKeypress kbAltShiftW = new TKeypress(false, + 0, 'W', true, false, true); + static public final TKeypress kbAltShiftX = new TKeypress(false, + 0, 'X', true, false, true); + static public final TKeypress kbAltShiftY = new TKeypress(false, + 0, 'Y', true, false, true); + static public final TKeypress kbAltShiftZ = new TKeypress(false, + 0, 'Z', true, false, true); + + /** + * Backspace as ^H + */ + static public final TKeypress kbBackspace = new TKeypress(false, + 0, 'H', false, true, false); + + /** + * Backspace as ^? + */ + static public final TKeypress kbBackspaceDel = new TKeypress(false, + 0, (char)0x7F, false, false, false); + +} diff --git a/src/jexer/backend/Backend.java b/src/jexer/backend/Backend.java new file mode 100644 index 0000000..15fcf62 --- /dev/null +++ b/src/jexer/backend/Backend.java @@ -0,0 +1,78 @@ +/** + * Jexer - Java Text User Interface + * + * Version: $Id$ + * + * Author: Kevin Lamonte, kevin.lamonte@gmail.com + * + * License: LGPLv3 or later + * + * Copyright: 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. + * + * Copyright (C) 2015 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. + * + * 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. + * + * 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 + */ +package jexer.backend; + +import jexer.event.TInputEvent; +import jexer.io.Screen; +import jexer.session.SessionInfo; + +/** + * This abstract class provides a screen, keyboard, and mouse to + * TApplication. It also exposes session information as gleaned from lower + * levels of the communication stack. + */ +public abstract class Backend { + + /** + * The session information + */ + public SessionInfo session; + + /** + * The screen to draw on + */ + public Screen screen; + + /** + * Subclasses must provide an implementation that syncs the logical + * screen to the physical device. + */ + abstract public void flushScreen(); + + /** + * Subclasses must provide an implementation to get keyboard, mouse, and + * screen resize events. + * + * @param timeout maximum amount of time to wait for an event + * @return events received, or an empty list if the timeout was reached + */ + abstract public TInputEvent [] getEvents(int timeout); + + /** + * Subclasses must provide an implementation that closes sockets, + * restores console, etc. + */ + abstract public void shutdown(); + +} + diff --git a/src/jexer/bits/MnemonicString.java b/src/jexer/bits/MnemonicString.java new file mode 100644 index 0000000..0567c99 --- /dev/null +++ b/src/jexer/bits/MnemonicString.java @@ -0,0 +1,97 @@ +/** + * Jexer - Java Text User Interface + * + * Version: $Id$ + * + * Author: Kevin Lamonte, kevin.lamonte@gmail.com + * + * License: LGPLv3 or later + * + * Copyright: 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. + * + * Copyright (C) 2015 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. + * + * 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. + * + * 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 + */ +package jexer.bits; + +/** + * MnemonicString is used to render a string like "&File" into a highlighted + * 'F' and the rest of 'ile'. To insert a literal '&', use two '&&' + * characters, e.g. "&File && Stuff" would be "File & Stuff" with the first + * 'F' highlighted. + */ +public class MnemonicString { + + /** + * Keyboard shortcut to activate this item + */ + public char shortcut; + + /** + * Location of the highlighted character + */ + public int shortcutIdx = -1; + + /** + * The raw (uncolored) string + */ + public String rawLabel; + + /** + * Public constructor + * + * @param label widget label or title. Label must contain a keyboard + * shortcut, denoted by prefixing a letter with "&", e.g. "&File" + */ + public MnemonicString(String label) { + + // Setup the menu shortcut + String newLabel = ""; + boolean foundAmp = false; + boolean foundShortcut = false; + int shortcutIdx = 0; + for (int i = 0; i < label.length(); i++) { + char c = label.charAt(i); + if (c == '&') { + if (foundAmp == true) { + newLabel += '&'; + shortcutIdx++; + } else { + foundAmp = true; + } + } else { + newLabel += c; + if (foundAmp == true) { + if (foundShortcut == false) { + shortcut = c; + foundAmp = false; + foundShortcut = true; + this.shortcutIdx = shortcutIdx; + } + } else { + shortcutIdx++; + } + } + } + this.rawLabel = newLabel; + } +} + diff --git a/src/jexer/event/TCommandEvent.java b/src/jexer/event/TCommandEvent.java new file mode 100644 index 0000000..d27c7ea --- /dev/null +++ b/src/jexer/event/TCommandEvent.java @@ -0,0 +1,64 @@ +/** + * Jexer - Java Text User Interface + * + * Version: $Id$ + * + * Author: Kevin Lamonte, kevin.lamonte@gmail.com + * + * License: LGPLv3 or later + * + * Copyright: 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. + * + * Copyright (C) 2015 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. + * + * 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. + * + * 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 + */ +package jexer.event; + +import jexer.TCommand; + +/** + * This class encapsulates a user command event. + */ +public class TCommandEvent extends TInputEvent { + + /** + * Command dispatched + */ + public TCommand cmd; + + /** + * Public contructor + * + * @param cmd the TCommand dispatched + */ + public TCommandEvent(TCommand cmd) { + this.cmd = cmd; + } + + /** + * Make human-readable description of this event + */ + @Override + public String toString() { + return String.format("CommandEvent: %s", cmd.toString()); + } +} + diff --git a/src/jexer/event/TInputEvent.java b/src/jexer/event/TInputEvent.java new file mode 100644 index 0000000..aa6c478 --- /dev/null +++ b/src/jexer/event/TInputEvent.java @@ -0,0 +1,54 @@ +/** + * Jexer - Java Text User Interface + * + * Version: $Id$ + * + * Author: Kevin Lamonte, kevin.lamonte@gmail.com + * + * License: LGPLv3 or later + * + * Copyright: 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. + * + * Copyright (C) 2015 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. + * + * 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. + * + * 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 + */ +package jexer.event; + +import java.util.Date; + +/** + * This is the parent class of all events received from the Terminal. + */ +public class TInputEvent { + + /** + * Time at which event was generated + */ + public Date timestamp; + + /** + * Public contructor + */ + public TInputEvent() { + // Save the current time + timestamp = new Date(); + } +} diff --git a/src/jexer/event/TKeypressEvent.java b/src/jexer/event/TKeypressEvent.java new file mode 100644 index 0000000..4f54df9 --- /dev/null +++ b/src/jexer/event/TKeypressEvent.java @@ -0,0 +1,70 @@ +/** + * Jexer - Java Text User Interface + * + * Version: $Id$ + * + * Author: Kevin Lamonte, kevin.lamonte@gmail.com + * + * License: LGPLv3 or later + * + * Copyright: 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. + * + * Copyright (C) 2015 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. + * + * 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. + * + * 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 + */ +package jexer.event; + +import jexer.TKeypress; + +/** + * This class encapsulates a keyboard input event. + */ +public class TKeypressEvent extends TInputEvent { + + /** + * Keystroke received + */ + public TKeypress key; + + /** + * Public contructor + */ + public TKeypressEvent() { + key = new TKeypress(false, 0, ' ', false, false, false); + } + + /** + * Public contructor + * + * @param key the TKeypress received + */ + public TKeypressEvent(TKeypress key) { + this.key = key; + } + + /** + * Make human-readable description of this event + */ + @Override + public String toString() { + return String.format("Keypress: %s", key.toString()); + } +} diff --git a/src/jexer/event/TMenuEvent.java b/src/jexer/event/TMenuEvent.java new file mode 100644 index 0000000..38ec852 --- /dev/null +++ b/src/jexer/event/TMenuEvent.java @@ -0,0 +1,64 @@ +/** + * Jexer - Java Text User Interface + * + * Version: $Id$ + * + * Author: Kevin Lamonte, kevin.lamonte@gmail.com + * + * License: LGPLv3 or later + * + * Copyright: 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. + * + * Copyright (C) 2015 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. + * + * 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. + * + * 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 + */ +package jexer.event; + +/** + * This class encapsulates a menu selection event. + * TApplication.getMenuItem(id) can be used to obtain the TMenuItem itself, + * say for setting enabled/disabled/checked/etc. + */ +public class TMenuEvent extends TInputEvent { + + /** + * MenuItem ID + */ + public short id; + + /** + * Public contructor + * + * @param id the MenuItem ID + */ + public TMenuEvent(short id) { + this.id = id; + } + + /** + * Make human-readable description of this event + */ + @Override + public String toString() { + return String.format("MenuEvent: %d", id); + } +} + diff --git a/src/jexer/event/TMouseEvent.java b/src/jexer/event/TMouseEvent.java new file mode 100644 index 0000000..2e953eb --- /dev/null +++ b/src/jexer/event/TMouseEvent.java @@ -0,0 +1,133 @@ +/** + * Jexer - Java Text User Interface + * + * Version: $Id$ + * + * Author: Kevin Lamonte, kevin.lamonte@gmail.com + * + * License: LGPLv3 or later + * + * Copyright: 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. + * + * Copyright (C) 2015 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. + * + * 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. + * + * 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 + */ +package jexer.event; + +/** + * This class encapsulates several kinds of mouse input events. + */ +public class TMouseEvent extends TInputEvent { + + enum Type { + /** + * Mouse motion. X and Y will have screen coordinates. + */ + MOUSE_MOTION, + + /** + * Mouse button down. X and Y will have screen coordinates. + */ + MOUSE_DOWN, + + /** + * Mouse button up. X and Y will have screen coordinates. + */ + MOUSE_UP + } + + /** + * Type of event, one of MOUSE_MOTION, MOUSE_UP, or MOUSE_DOWN, or + * KEYPRESS + */ + public Type type; + + /** + * Mouse X - relative coordinates + */ + public int x; + + /** + * Mouse Y - relative coordinates + */ + public int y; + + /** + * Mouse X - absolute screen coordinates + */ + public int absoluteX; + + /** + * Mouse Y - absolute screen coordinate + */ + public int absoluteY; + + /** + * Mouse button 1 (left button) + */ + public boolean mouse1; + + /** + * Mouse button 2 (right button) + */ + public boolean mouse2; + + /** + * Mouse button 3 (middle button) + */ + public boolean mouse3; + + /** + * Mouse wheel UP (button 4) + */ + public boolean mouseWheelUp; + + /** + * Mouse wheel DOWN (button 5) + */ + public boolean mouseWheelDown; + + /** + * Public contructor + * + * @param type the type of event, MOUSE_MOTION, MOUSE_DOWN, or MOUSE_UP + */ + public TMouseEvent(Type type) { + this.type = type; + } + + /** + * Make human-readable description of this event + */ + @Override + public String toString() { + return String.format("Mouse: %s x %d y %d absoluteX %d absoluteY %d 1 %s 2 %s 3 %s DOWN %s UP %s", + type, + x, y, + absoluteX, absoluteY, + mouse1, + mouse2, + mouse3, + mouseWheelUp, + mouseWheelDown); + } + +} diff --git a/src/jexer/event/TResizeEvent.java b/src/jexer/event/TResizeEvent.java new file mode 100644 index 0000000..aabf051 --- /dev/null +++ b/src/jexer/event/TResizeEvent.java @@ -0,0 +1,86 @@ +/** + * Jexer - Java Text User Interface + * + * Version: $Id$ + * + * Author: Kevin Lamonte, kevin.lamonte@gmail.com + * + * License: LGPLv3 or later + * + * Copyright: 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. + * + * Copyright (C) 2015 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. + * + * 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. + * + * 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 + */ +package jexer.event; + +/** + * This class encapsulates a screen or window resize event. + */ +public class TResizeEvent extends TInputEvent { + + /** + * Resize events can be generated for either a total screen resize or a + * widget/window resize. + */ + public enum Type { + Screen, + Widget + } + + /** + * The type of resize + */ + public Type type; + + /** + * New width + */ + public int width; + + /** + * New height + */ + public int height; + + /** + * Public contructor + * + * @param type the Type of resize, Screen or Widget + * @param width the new width + * @param width the new height + */ + public TResizeEvent(Type type, int width, int height) { + this.type = type; + this.width = width; + this.height = height; + } + + /** + * Make human-readable description of this event + */ + @Override + public String toString() { + return String.format("Resize: %s width = %d height = %d", + type, width, height); + } + +} diff --git a/src/jexer/io/Screen.java b/src/jexer/io/Screen.java new file mode 100644 index 0000000..6910a66 --- /dev/null +++ b/src/jexer/io/Screen.java @@ -0,0 +1,646 @@ +/** + * Jexer - Java Text User Interface + * + * Version: $Id$ + * + * Author: Kevin Lamonte, kevin.lamonte@gmail.com + * + * License: LGPLv3 or later + * + * Copyright: 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. + * + * Copyright (C) 2015 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. + * + * 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. + * + * 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 + */ +package jexer.io; + +import jexer.bits.Cell; +import jexer.bits.CellAttributes; +import jexer.bits.GraphicsChars; + +/** + * This class represents a text-based screen. Drawing operations write to a + * logical screen. + */ +public abstract class Screen { + + /** + * Emit debugging to stderr + */ + public boolean debugToStderr; + + /** + * Width of the visible window + */ + protected int width; + + /** + * Height of the visible window + */ + protected int height; + + /** + * Drawing offset for x + */ + public int offsetX; + + /** + * Drawing offset for y + */ + public int offsetY; + + /** + * Ignore anything drawn right of clipRight + */ + public int clipRight; + + /** + * Ignore anything drawn below clipBottom + */ + public int clipBottom; + + /** + * Ignore anything drawn left of clipLeft + */ + public int clipLeft; + + /** + * Ignore anything drawn above clipTop + */ + public int clipTop; + + /** + * The physical screen last sent out on flush() + */ + protected Cell [][] physical; + + /** + * The logical screen being rendered to + */ + protected Cell [][] logical; + + /** + * When true, logical != physical + */ + public boolean dirty; + + /** + * Set if the user explicitly wants to redraw everything starting with a + * ECMATerminal.clearAll() + */ + protected boolean reallyCleared; + + /** + * If true, the cursor is visible and should be placed onscreen at + * (cursorX, cursorY) during a call to flushPhysical() + */ + protected boolean cursorVisible; + + /** + * Cursor X position if visible + */ + protected int cursorX; + + /** + * Cursor Y position if visible + */ + protected int cursorY; + + /** + * Get the attributes at one location. + * + * @param x column coordinate. 0 is the left-most column. + * @param y row coordinate. 0 is the top-most row. + * @return attributes at (x, y) + */ + public CellAttributes getAttrXY(int x, int y) { + CellAttributes attr = new CellAttributes(); + attr.setTo(logical[x][y]); + return attr; + } + + /** + * Set the attributes at one location. + * + * @param x column coordinate. 0 is the left-most column. + * @param y row coordinate. 0 is the top-most row. + * @param attr attributes to use (bold, foreColor, backColor) + * @param clip if true, honor clipping/offset + */ + public void putAttrXY(int x, int y, CellAttributes attr) { + putAttrXY(x, y, attr, true); + } + + /** + * Set the attributes at one location. + * + * @param x column coordinate. 0 is the left-most column. + * @param y row coordinate. 0 is the top-most row. + * @param attr attributes to use (bold, foreColor, backColor) + * @param clip if true, honor clipping/offset + */ + public void putAttrXY(int x, int y, CellAttributes attr, boolean clip) { + + int X = x; + int Y = y; + + if (clip) { + if ((x < clipLeft) || (x >= clipRight) || + (y < clipTop) || (y >= clipBottom)) { + return; + } + X += offsetX; + Y += offsetY; + } + + if ((X >= 0) && (X < width) && (Y >= 0) && (Y < height)) { + dirty = true; + logical[X][Y].foreColor = attr.foreColor; + logical[X][Y].backColor = attr.backColor; + logical[X][Y].bold = attr.bold; + logical[X][Y].blink = attr.blink; + logical[X][Y].reverse = attr.reverse; + logical[X][Y].underline = attr.underline; + logical[X][Y].protect = attr.protect; + } + } + + /** + * Fill the entire screen with one character with attributes. + * + * @param ch character to draw + * @param attr attributes to use (bold, foreColor, backColor) + */ + public void putAll(char ch, CellAttributes attr) { + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + putCharXY(x, y, ch, attr); + } + } + } + + /** + * Render one character with attributes. + * + * @param x column coordinate. 0 is the left-most column. + * @param y row coordinate. 0 is the top-most row. + * @param ch character + attributes to draw + */ + public void putCharXY(int x, int y, Cell ch) { + putCharXY(x, y, ch.ch, ch); + } + + /** + * Render one character with attributes. + * + * @param x column coordinate. 0 is the left-most column. + * @param y row coordinate. 0 is the top-most row. + * @param ch character to draw + * @param attr attributes to use (bold, foreColor, backColor) + */ + public void putCharXY(int x, int y, char ch, CellAttributes attr) { + if ((x < clipLeft) || (x >= clipRight) || + (y < clipTop) || (y >= clipBottom)) { + return; + } + + int X = x + offsetX; + int Y = y + offsetY; + + // stderr.writefln("putCharXY: %d, %d, %c", X, Y, ch); + + if ((X >= 0) && (X < width) && (Y >= 0) && (Y < height)) { + dirty = true; + + // Do not put control characters on the display + assert(ch >= 0x20); + assert(ch != 0x7F); + + logical[X][Y].ch = ch; + logical[X][Y].foreColor = attr.foreColor; + logical[X][Y].backColor = attr.backColor; + logical[X][Y].bold = attr.bold; + logical[X][Y].blink = attr.blink; + logical[X][Y].reverse = attr.reverse; + logical[X][Y].underline = attr.underline; + logical[X][Y].protect = attr.protect; + } + } + + /** + * Render one character without changing the underlying attributes. + * + * @param x column coordinate. 0 is the left-most column. + * @param y row coordinate. 0 is the top-most row. + * @param ch character to draw + */ + public void putCharXY(int x, int y, char ch) { + if ((x < clipLeft) || (x >= clipRight) || + (y < clipTop) || (y >= clipBottom)) { + return; + } + + int X = x + offsetX; + int Y = y + offsetY; + + // stderr.writefln("putCharXY: %d, %d, %c", X, Y, ch); + + if ((X >= 0) && (X < width) && (Y >= 0) && (Y < height)) { + dirty = true; + logical[X][Y].ch = ch; + } + } + + /** + * Render a string. Does not wrap if the string exceeds the line. + * + * @param x column coordinate. 0 is the left-most column. + * @param y row coordinate. 0 is the top-most row. + * @param str string to draw + * @param attr attributes to use (bold, foreColor, backColor) + */ + public void putStrXY(int x, int y, String str, CellAttributes attr) { + int i = x; + for (int j = 0; j < str.length(); j++) { + char ch = str.charAt(j); + putCharXY(i, y, ch, attr); + i++; + if (i == width) { + break; + } + } + } + + /** + * Render a string without changing the underlying attribute. Does not + * wrap if the string exceeds the line. + * + * @param x column coordinate. 0 is the left-most column. + * @param y row coordinate. 0 is the top-most row. + * @param str string to draw + */ + public void putStrXY(int x, int y, String str) { + int i = x; + for (int j = 0; j < str.length(); j++) { + char ch = str.charAt(j); + putCharXY(i, y, ch); + i++; + if (i == width) { + break; + } + } + } + + /** + * Draw a vertical line from (x, y) to (x, y + n) + * + * @param x column coordinate. 0 is the left-most column. + * @param y row coordinate. 0 is the top-most row. + * @param n number of characters to draw + * @param ch character to draw + * @param attr attributes to use (bold, foreColor, backColor) + */ + public void vLineXY(int x, int y, int n, char ch, CellAttributes attr) { + for (int i = y; i < y + n; i++) { + putCharXY(x, i, ch, attr); + } + } + + /** + * Draw a horizontal line from (x, y) to (x + n, y) + * + * @param x column coordinate. 0 is the left-most column. + * @param y row coordinate. 0 is the top-most row. + * @param n number of characters to draw + * @param ch character to draw + * @param attr attributes to use (bold, foreColor, backColor) + */ + public void hLineXY(int x, int y, int n, char ch, CellAttributes attr) { + for (int i = x; i < x + n; i++) { + putCharXY(i, y, ch, attr); + } + } + + /** + * Reallocate screen buffers. + * + * @param width new width + * @param height new height + */ + private void reallocate(int width, int height) { + if (logical != null) { + for (int row = 0; row < this.height; row++) { + for (int col = 0; col < this.width; col++) { + logical[col][row] = null; + } + } + logical = null; + } + logical = new Cell[width][height]; + if (physical != null) { + for (int row = 0; row < this.height; row++) { + for (int col = 0; col < this.width; col++) { + physical[col][row] = null; + } + } + physical = null; + } + physical = new Cell[width][height]; + + for (int row = 0; row < height; row++) { + for (int col = 0; col < width; col++) { + physical[col][row] = new Cell(); + logical[col][row] = new Cell(); + } + } + + this.width = width; + this.height = height; + + clipLeft = 0; + clipTop = 0; + clipRight = width; + clipBottom = height; + + reallyCleared = true; + dirty = true; + } + + /** + * Change the width. Everything on-screen will be destroyed and must be + * redrawn. + * + * @param width new screen width + */ + public void setWidth(int width) { + reallocate(width, this.height); + } + + /** + * Change the height. Everything on-screen will be destroyed and must be + * redrawn. + * + * @param height new screen height + */ + public void setHeight(int height) { + reallocate(this.width, height); + } + + /** + * Change the width and height. Everything on-screen will be destroyed + * and must be redrawn. + * + * @param width new screen width + * @param height new screen height + */ + public void setDimensions(int width, int height) { + reallocate(width, height); + } + + /** + * Get the height. + * + * @return current screen height + */ + public int getHeight() { + return this.height; + } + + /** + * Get the width. + * + * @return current screen width + */ + public int getWidth() { + return this.width; + } + + /** + * Public constructor. Sets everything to not-bold, white-on-black. + */ + public Screen() { + debugToStderr = false; + + offsetX = 0; + offsetY = 0; + width = 80; + height = 24; + logical = null; + physical = null; + reallocate(width, height); + } + + /** + * Reset screen to not-bold, white-on-black. Also flushes the offset and + * clip variables. + */ + public void reset() { + dirty = true; + for (int row = 0; row < height; row++) { + for (int col = 0; col < width; col++) { + logical[col][row].reset(); + } + } + resetClipping(); + } + + /** + * Flush the offset and clip variables. + */ + public void resetClipping() { + offsetX = 0; + offsetY = 0; + clipLeft = 0; + clipTop = 0; + clipRight = width; + clipBottom = height; + } + + /** + * Force the screen to be fully cleared and redrawn on the next flush(). + */ + public void clear() { + reset(); + } + + /** + * Draw a box with a border and empty background. + * + * @param left left column of box. 0 is the left-most row. + * @param top top row of the box. 0 is the top-most row. + * @param right right column of box + * @param bottom bottom row of the box + * @param border attributes to use for the border (bold, foreColor, backColor) + * @param background attributes to use for the background + */ + public void drawBox(int left, int top, int right, int bottom, + CellAttributes border, CellAttributes background) { + drawBox(left, top, right, bottom, border, background, 1, false); + } + + /** + * Draw a box with a border and empty background. + * + * @param left left column of box. 0 is the left-most row. + * @param top top row of the box. 0 is the top-most row. + * @param right right column of box + * @param bottom bottom row of the box + * @param border attributes to use for the border (bold, foreColor, backColor) + * @param background attributes to use for the background + * @param borderType = 1: single-line border + * 2: double-line borders + * 3: double-line top/bottom edges and single-line left/right edges + * @param shadow if true, draw a "shadow" on the box + */ + public void drawBox(int left, int top, int right, int bottom, + CellAttributes border, CellAttributes background, int borderType, + boolean shadow) { + + int boxTop = top; + int boxLeft = left; + int boxWidth = right - left; + int boxHeight = bottom - top; + + char cTopLeft; + char cTopRight; + char cBottomLeft; + char cBottomRight; + char cHSide; + char cVSide; + + switch (borderType) { + case 1: + cTopLeft = GraphicsChars.ULCORNER; + cTopRight = GraphicsChars.URCORNER; + cBottomLeft = GraphicsChars.LLCORNER; + cBottomRight = GraphicsChars.LRCORNER; + cHSide = GraphicsChars.SINGLE_BAR; + cVSide = GraphicsChars.WINDOW_SIDE; + break; + + case 2: + cTopLeft = GraphicsChars.WINDOW_LEFT_TOP_DOUBLE; + cTopRight = GraphicsChars.WINDOW_RIGHT_TOP_DOUBLE; + cBottomLeft = GraphicsChars.WINDOW_LEFT_BOTTOM_DOUBLE; + cBottomRight = GraphicsChars.WINDOW_RIGHT_BOTTOM_DOUBLE; + cHSide = GraphicsChars.DOUBLE_BAR; + cVSide = GraphicsChars.WINDOW_SIDE_DOUBLE; + break; + + case 3: + cTopLeft = GraphicsChars.WINDOW_LEFT_TOP; + cTopRight = GraphicsChars.WINDOW_RIGHT_TOP; + cBottomLeft = GraphicsChars.WINDOW_LEFT_BOTTOM; + cBottomRight = GraphicsChars.WINDOW_RIGHT_BOTTOM; + cHSide = GraphicsChars.WINDOW_TOP; + cVSide = GraphicsChars.WINDOW_SIDE; + break; + default: + throw new IllegalArgumentException("Invalid border type: " + borderType); + } + + // Place the corner characters + putCharXY(left, top, cTopLeft, border); + putCharXY(left + boxWidth - 1, top, cTopRight, border); + putCharXY(left, top + boxHeight - 1, cBottomLeft, border); + putCharXY(left + boxWidth - 1, top + boxHeight - 1, cBottomRight, + border); + + // Draw the box lines + hLineXY(left + 1, top, boxWidth - 2, cHSide, border); + vLineXY(left, top + 1, boxHeight - 2, cVSide, border); + hLineXY(left + 1, top + boxHeight - 1, boxWidth - 2, cHSide, border); + vLineXY(left + boxWidth - 1, top + 1, boxHeight - 2, cVSide, border); + + // Fill in the interior background + for (int i = 1; i < boxHeight - 1; i++) { + hLineXY(1 + left, i + top, boxWidth - 2, ' ', background); + } + + if (shadow) { + // Draw a shadow + drawBoxShadow(left, top, right, bottom); + } + } + + /** + * Draw a box shadow + * + * @param left left column of box. 0 is the left-most row. + * @param top top row of the box. 0 is the top-most row. + * @param right right column of box + * @param bottom bottom row of the box + */ + public void drawBoxShadow(int left, int top, int right, int bottom) { + + int boxTop = top; + int boxLeft = left; + int boxWidth = right - left; + int boxHeight = bottom - top; + CellAttributes shadowAttr = new CellAttributes(); + + // Shadows do not honor clipping but they DO honor offset. + int oldClipRight = clipRight; + int oldClipBottom = clipBottom; + /* + clipRight = boxWidth + 2; + clipBottom = boxHeight + 1; + */ + clipRight = width; + clipBottom = height; + + for (int i = 0; i < boxHeight; i++) { + putAttrXY(boxLeft + boxWidth, boxTop + 1 + i, shadowAttr); + putAttrXY(boxLeft + boxWidth + 1, boxTop + 1 + i, shadowAttr); + } + for (int i = 0; i < boxWidth; i++) { + putAttrXY(boxLeft + 2 + i, boxTop + boxHeight, shadowAttr); + } + clipRight = oldClipRight; + clipBottom = oldClipBottom; + } + + /** + * Subclasses must provide an implementation to push the logical screen + * to the physical device. + */ + abstract public void flushPhysical(); + + /** + * Put the cursor at (x,y). + * + * @param visible if true, the cursor should be visible + * @param x column coordinate to put the cursor on + * @param y row coordinate to put the cursor on + */ + public void putCursor(boolean visible, int x, int y) { + cursorVisible = visible; + cursorX = x; + cursorY = y; + } + + /** + * Hide the cursor + */ + public void hideCursor() { + cursorVisible = false; + } +} diff --git a/src/jexer/session/SessionInfo.java b/src/jexer/session/SessionInfo.java new file mode 100644 index 0000000..0c10637 --- /dev/null +++ b/src/jexer/session/SessionInfo.java @@ -0,0 +1,78 @@ +/** + * Jexer - Java Text User Interface + * + * Version: $Id$ + * + * Author: Kevin Lamonte, kevin.lamonte@gmail.com + * + * License: LGPLv3 or later + * + * Copyright: 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. + * + * Copyright (C) 2015 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. + * + * 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. + * + * 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 + */ +package jexer.session; + +/** + * SessionInfo is used to store per-session properties that are determined at + * different layers of the communication stack. + */ +public interface SessionInfo { + + /** + * Username getter + * + * @return the username + */ + public String getUsername(); + + /** + * Username setter + * + * @param username the value + */ + public void setUsername(String username); + + /** + * Language getter + * + * @return the language + */ + public String getLanguage(); + + /** + * Language setter + * + * @param language the value + */ + public void setLanguage(String language); + + /** + * Text window width getter + */ + public int getWindowWidth(); + + /** + * Text window height getter + */ + public int getWindowHeight(); +} diff --git a/src/jexer/session/TSessionInfo.java b/src/jexer/session/TSessionInfo.java new file mode 100644 index 0000000..a0dc75c --- /dev/null +++ b/src/jexer/session/TSessionInfo.java @@ -0,0 +1,110 @@ +/** + * Jexer - Java Text User Interface + * + * Version: $Id$ + * + * Author: Kevin Lamonte, kevin.lamonte@gmail.com + * + * License: LGPLv3 or later + * + * Copyright: 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. + * + * Copyright (C) 2015 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. + * + * 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. + * + * 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 + */ +package jexer.session; + +/** + * TSessionInfo provides a default session implementation. The username is + * blank, language is "en_US", with a 80x24 text window. + */ +public class TSessionInfo implements SessionInfo { + + /** + * User name + */ + private String username = ""; + + /** + * Language + */ + private String language = "en_US"; + + /** + * Text window width + */ + private int windowWidth = 80; + + /** + * Text window height + */ + private int windowHeight = 24; + + /** + * Username getter + * + * @return the username + */ + public String getUsername() { + return this.username; + } + + /** + * Username setter + * + * @param username the value + */ + public void setUsername(String username) { + this.username = username; + } + + /** + * Language getter + * + * @return the language + */ + public String getLanguage() { + return this.language; + } + + /** + * Language setter + * + * @param language the value + */ + public void setLanguage(String language) { + this.language = language; + } + + /** + * Text window width getter + */ + public int getWindowWidth() { + return windowWidth; + } + + /** + * Text window height getter + */ + public int getWindowHeight() { + return windowHeight; + } +} -- 2.27.0