#51 wip
[fanfix.git] / examples / JexerTilingWindowManager2.java
CommitLineData
2bc32111
KL
1import jexer.TAction;
2import jexer.TApplication;
3import jexer.TDesktop;
469c2b3c 4import jexer.TPanel;
2bc32111 5import jexer.TTerminalWidget;
469c2b3c 6import jexer.TSplitPane;
2bc32111
KL
7import jexer.TWidget;
8import jexer.event.TKeypressEvent;
9import jexer.event.TMenuEvent;
2bc32111
KL
10import 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 */
21public 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;
469c2b3c 37
2bc32111
KL
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
469c2b3c 81 createRootTerminal();
2bc32111
KL
82 }
83
84 /**
85 * Process menu events.
86 */
87 @Override
88 protected boolean onMenu(TMenuEvent event) {
89 if (event.getId() == MENU_SPLIT_VERTICAL) {
469c2b3c 90 if (root == null) {
90d87fca 91 assert (getDesktop().getActiveChild() == null);
469c2b3c
KL
92 createRootTerminal();
93 return true;
94 }
90d87fca 95 TWidget active = getDesktop().getActiveChild();
469c2b3c 96 TSplitPane split = active.splitVertical(false,
90d87fca 97 new TTerminalWidget(active, active.getX(),
469c2b3c
KL
98 active.getY(), active.getWidth(), active.getHeight(),
99 new TAction() {
100 public void DO() {
a524aa2e
KL
101 if (source.getParent() instanceof TSplitPane) {
102 ((TSplitPane) source.getParent()).removeSplit(source, true);
103 } else if (source == root) {
104 assert (root != null);
105 root.remove();
106 root = null;
107 }
469c2b3c
KL
108 }
109 }));
110 if (active == root) {
111 root = split;
112 }
90d87fca
KL
113 System.err.println("\nAfter vertical split:");
114 System.err.println(getDesktop().toPrettyString());
2bc32111
KL
115 return true;
116 }
117 if (event.getId() == MENU_SPLIT_HORIZONTAL) {
469c2b3c 118 if (root == null) {
90d87fca 119 assert (getDesktop().getActiveChild() == null);
469c2b3c
KL
120 createRootTerminal();
121 return true;
122 }
90d87fca 123 TWidget active = getDesktop().getActiveChild();
469c2b3c 124 TSplitPane split = active.splitHorizontal(false,
90d87fca 125 new TTerminalWidget(active, active.getX(),
469c2b3c
KL
126 active.getY(), active.getWidth(), active.getHeight(),
127 new TAction() {
128 public void DO() {
a524aa2e
KL
129 if (source.getParent() instanceof TSplitPane) {
130 ((TSplitPane) source.getParent()).removeSplit(source, true);
131 } else if (source == root) {
132 assert (root != null);
133 root.remove();
134 root = null;
135 }
469c2b3c
KL
136 }
137 }));
90d87fca
KL
138 if (active == root) {
139 root = split;
140 }
141 System.err.println("\nAfter horizontal split:");
142 System.err.println(getDesktop().toPrettyString());
2bc32111
KL
143 return true;
144 }
145
146 return super.onMenu(event);
147 }
148
149 /**
469c2b3c 150 * Create the root terminal.
2bc32111 151 */
469c2b3c
KL
152 private void createRootTerminal() {
153 assert (root == null);
154 root = new TTerminalWidget(getDesktop(), 0, 0,
155 getDesktop().getWidth(), getDesktop().getHeight(),
156 new TAction() {
157 public void DO() {
a524aa2e
KL
158 if (source.getParent() instanceof TSplitPane) {
159 ((TSplitPane) source.getParent()).removeSplit(source, true);
160 } else if (source == root) {
469c2b3c
KL
161 assert (root != null);
162 root.remove();
163 root = null;
164 }
165 }
166 });
2bc32111
KL
167 }
168
169}