LICENSE CHANGED TO MIT
[nikiroo-utils.git] / src / jexer / menu / TSubMenu.java
1 /*
2 * Jexer - Java Text User Interface
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (C) 2016 Kevin Lamonte
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
27 * @version 1
28 */
29 package jexer.menu;
30
31 import jexer.TKeypress;
32 import jexer.TWidget;
33 import jexer.bits.CellAttributes;
34 import jexer.bits.GraphicsChars;
35 import jexer.event.TKeypressEvent;
36 import static jexer.TKeypress.*;
37
38 /**
39 * TSubMenu is a special case menu item that wraps another TMenu.
40 */
41 public final class TSubMenu extends TMenuItem {
42
43 /**
44 * The menu window. Note package private access.
45 */
46 TMenu menu;
47
48 /**
49 * Package private constructor.
50 *
51 * @param parent parent widget
52 * @param title menu title. Title must contain a keyboard shortcut,
53 * denoted by prefixing a letter with "&", e.g. "&File"
54 * @param x column relative to parent
55 * @param y row relative to parent
56 */
57 TSubMenu(final TMenu parent, final String title, final int x, final int y) {
58 super(parent, TMenu.MID_UNUSED, x, y, title);
59
60 setActive(false);
61 setEnabled(true);
62
63 this.menu = new TMenu(parent.getApplication(), x, getAbsoluteY() - 1,
64 title);
65 setWidth(menu.getWidth() + 2);
66
67 this.menu.isSubMenu = true;
68 }
69
70 /**
71 * Draw the menu title.
72 */
73 @Override
74 public void draw() {
75 super.draw();
76
77 CellAttributes menuColor;
78 if (isAbsoluteActive()) {
79 menuColor = getTheme().getColor("tmenu.highlighted");
80 } else {
81 if (isEnabled()) {
82 menuColor = getTheme().getColor("tmenu");
83 } else {
84 menuColor = getTheme().getColor("tmenu.disabled");
85 }
86 }
87
88 // Add the arrow
89 getScreen().putCharXY(getWidth() - 2, 0, GraphicsChars.CP437[0x10],
90 menuColor);
91 }
92
93 /**
94 * Handle keystrokes.
95 *
96 * @param keypress keystroke event
97 */
98 @Override
99 public void onKeypress(final TKeypressEvent keypress) {
100
101 // Open me if they hit my mnemonic.
102 if (!keypress.getKey().isFnKey()
103 && !keypress.getKey().isAlt()
104 && !keypress.getKey().isCtrl()
105 && (getMnemonic() != null)
106 && (Character.toLowerCase(getMnemonic().getShortcut())
107 == Character.toLowerCase(keypress.getKey().getChar()))
108 ) {
109 dispatch();
110 return;
111 }
112
113 if (menu.isActive()) {
114 menu.onKeypress(keypress);
115 return;
116 }
117
118 if (keypress.equals(kbEnter)) {
119 dispatch();
120 return;
121 }
122
123 if (keypress.equals(kbRight)) {
124 dispatch();
125 return;
126 }
127
128 if (keypress.equals(kbDown)) {
129 getParent().switchWidget(true);
130 return;
131 }
132
133 if (keypress.equals(kbUp)) {
134 getParent().switchWidget(false);
135 return;
136 }
137
138 if (keypress.equals(kbLeft)) {
139 TMenu parentMenu = (TMenu) getParent();
140 if (parentMenu.isSubMenu) {
141 getApplication().closeSubMenu();
142 } else {
143 getApplication().switchMenu(false);
144 }
145 return;
146 }
147
148 if (keypress.equals(kbEsc)) {
149 getApplication().closeMenu();
150 return;
151 }
152 }
153
154 /**
155 * Override dispatch() to do nothing.
156 */
157 @Override
158 public void dispatch() {
159 assert (isEnabled());
160 if (isAbsoluteActive()) {
161 if (!menu.isActive()) {
162 getApplication().addSubMenu(menu);
163 menu.setActive(true);
164 }
165 }
166 }
167
168 /**
169 * Returns my active widget.
170 *
171 * @return widget that is active, or this if no children
172 */
173 @Override
174 public TWidget getActiveChild() {
175 if (menu.isActive()) {
176 return menu;
177 }
178 // Menu not active, return me
179 return this;
180 }
181
182 /**
183 * Convenience function to add a custom menu item.
184 *
185 * @param id menu item ID. Must be greater than 1024.
186 * @param label menu item label
187 * @param key global keyboard accelerator
188 * @return the new menu item
189 */
190 public TMenuItem addItem(final int id, final String label,
191 final TKeypress key) {
192
193 return menu.addItem(id, label, key);
194 }
195
196 /**
197 * Convenience function to add a menu item.
198 *
199 * @param id menu item ID. Must be greater than 1024.
200 * @param label menu item label
201 * @return the new menu item
202 */
203 public TMenuItem addItem(final int id, final String label) {
204 return menu.addItem(id, label);
205 }
206
207 /**
208 * Convenience function to add one of the default menu items.
209 *
210 * @param id menu item ID. Must be between 0 (inclusive) and 1023
211 * (inclusive).
212 * @return the new menu item
213 */
214 public TMenuItem addDefaultItem(final int id) {
215 return menu.addDefaultItem(id);
216 }
217
218 /**
219 * Convenience function to add a menu separator.
220 */
221 public void addSeparator() {
222 menu.addSeparator();
223 }
224
225 /**
226 * Convenience function to add a sub-menu.
227 *
228 * @param title menu title. Title must contain a keyboard shortcut,
229 * denoted by prefixing a letter with "&", e.g. "&File"
230 * @return the new sub-menu
231 */
232 public TSubMenu addSubMenu(final String title) {
233 return menu.addSubMenu(title);
234 }
235
236
237 }