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