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