| 1 | import jexer.TAction; |
| 2 | import jexer.TApplication; |
| 3 | import jexer.TDesktop; |
| 4 | import jexer.TPanel; |
| 5 | import jexer.TTerminalWidget; |
| 6 | import jexer.TSplitPane; |
| 7 | import jexer.TWidget; |
| 8 | import jexer.event.TKeypressEvent; |
| 9 | import jexer.event.TMenuEvent; |
| 10 | import jexer.menu.TMenu; |
| 11 | |
| 12 | /** |
| 13 | * Implements a simple tiling window manager. A terminal widget is added to |
| 14 | * the desktop, which can be split horizontally or vertically. A close |
| 15 | * action is provided to each window to remove the split when its shell |
| 16 | * exits. |
| 17 | * |
| 18 | * This example shows what can be done with minimal changes to stock Jexer |
| 19 | * widgets. |
| 20 | */ |
| 21 | public class JexerTilingWindowManager2 extends TApplication { |
| 22 | |
| 23 | /** |
| 24 | * Menu item: split the terminal vertically. |
| 25 | */ |
| 26 | private static final int MENU_SPLIT_VERTICAL = 2000; |
| 27 | |
| 28 | /** |
| 29 | * Menu item: split the terminal horizontally. |
| 30 | */ |
| 31 | private static final int MENU_SPLIT_HORIZONTAL = 2001; |
| 32 | |
| 33 | /** |
| 34 | * Handle to the root widget. |
| 35 | */ |
| 36 | private TWidget root = null; |
| 37 | |
| 38 | /** |
| 39 | * Main entry point. |
| 40 | */ |
| 41 | public static void main(String [] args) throws Exception { |
| 42 | // For this application, we must use ptypipe so that the terminal |
| 43 | // shells can be aware of their size. |
| 44 | System.setProperty("jexer.TTerminal.ptypipe", "true"); |
| 45 | |
| 46 | // Let's also suppress the status line. |
| 47 | System.setProperty("jexer.hideStatusBar", "true"); |
| 48 | |
| 49 | JexerTilingWindowManager2 jtwm = new JexerTilingWindowManager2(); |
| 50 | (new Thread(jtwm)).start(); |
| 51 | } |
| 52 | |
| 53 | /** |
| 54 | * Public constructor chooses the ECMA-48 / Xterm backend. |
| 55 | */ |
| 56 | public JexerTilingWindowManager2() throws Exception { |
| 57 | super(BackendType.SWING); |
| 58 | |
| 59 | // The stock tool menu has items for redrawing the screen, opening |
| 60 | // images, and (when using the Swing backend) setting the font. |
| 61 | addToolMenu(); |
| 62 | |
| 63 | // We will have one menu containing a mix of new and stock commands |
| 64 | TMenu tileMenu = addMenu("&Tile"); |
| 65 | |
| 66 | // New commands for this example: split vertical and horizontal. |
| 67 | tileMenu.addItem(MENU_SPLIT_VERTICAL, "&Vertical Split"); |
| 68 | tileMenu.addItem(MENU_SPLIT_HORIZONTAL, "&Horizontal Split"); |
| 69 | |
| 70 | // Stock commands: a new shell with resizable window, previous, next, |
| 71 | // close, and exit program. |
| 72 | tileMenu.addItem(TMenu.MID_SHELL, "&Floating"); |
| 73 | tileMenu.addSeparator(); |
| 74 | tileMenu.addDefaultItem(TMenu.MID_WINDOW_PREVIOUS); |
| 75 | tileMenu.addDefaultItem(TMenu.MID_WINDOW_NEXT); |
| 76 | tileMenu.addDefaultItem(TMenu.MID_WINDOW_CLOSE); |
| 77 | tileMenu.addSeparator(); |
| 78 | tileMenu.addDefaultItem(TMenu.MID_EXIT); |
| 79 | |
| 80 | // Spin up the root terminal |
| 81 | createRootTerminal(); |
| 82 | } |
| 83 | |
| 84 | /** |
| 85 | * Process menu events. |
| 86 | */ |
| 87 | @Override |
| 88 | protected boolean onMenu(TMenuEvent event) { |
| 89 | if (event.getId() == MENU_SPLIT_VERTICAL) { |
| 90 | if (root == null) { |
| 91 | createRootTerminal(); |
| 92 | return true; |
| 93 | } |
| 94 | TWidget active = root.getActiveChild(); |
| 95 | TSplitPane split = active.splitVertical(false, |
| 96 | new TTerminalWidget(getDesktop(), active.getX(), |
| 97 | active.getY(), active.getWidth(), active.getHeight(), |
| 98 | new TAction() { |
| 99 | public void DO() { |
| 100 | // TODO |
| 101 | } |
| 102 | })); |
| 103 | if (active == root) { |
| 104 | root = split; |
| 105 | } |
| 106 | return true; |
| 107 | } |
| 108 | if (event.getId() == MENU_SPLIT_HORIZONTAL) { |
| 109 | if (root == null) { |
| 110 | createRootTerminal(); |
| 111 | return true; |
| 112 | } |
| 113 | TWidget active = root.getActiveChild(); |
| 114 | TSplitPane split = active.splitHorizontal(false, |
| 115 | new TTerminalWidget(getDesktop(), active.getX(), |
| 116 | active.getY(), active.getWidth(), active.getHeight(), |
| 117 | new TAction() { |
| 118 | public void DO() { |
| 119 | // TODO |
| 120 | } |
| 121 | })); |
| 122 | return true; |
| 123 | } |
| 124 | |
| 125 | return super.onMenu(event); |
| 126 | } |
| 127 | |
| 128 | /** |
| 129 | * Create the root terminal. |
| 130 | */ |
| 131 | private void createRootTerminal() { |
| 132 | assert (root == null); |
| 133 | root = new TTerminalWidget(getDesktop(), 0, 0, |
| 134 | getDesktop().getWidth(), getDesktop().getHeight(), |
| 135 | new TAction() { |
| 136 | public void DO() { |
| 137 | TWidget target = (TWidget) data; |
| 138 | if (target.getParent() instanceof TPanel) { |
| 139 | ((TSplitPane) target.getParent().getParent()).removeSplit(target, true); |
| 140 | } else { |
| 141 | assert (root != null); |
| 142 | root.remove(); |
| 143 | root = null; |
| 144 | } |
| 145 | } |
| 146 | }); |
| 147 | } |
| 148 | |
| 149 | } |