stubs for TFileOpenBox, cleanup putStringXY
[nikiroo-utils.git] / src / jexer / menu / TMenuItem.java
1 /**
2 * Jexer - Java Text User Interface
3 *
4 * License: LGPLv3 or later
5 *
6 * This module is licensed under the GNU Lesser General Public License
7 * Version 3. Please see the file "COPYING" in this directory for more
8 * information about the GNU Lesser General Public License Version 3.
9 *
10 * Copyright (C) 2015 Kevin Lamonte
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 3 of
15 * the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this program; if not, see
24 * http://www.gnu.org/licenses/, or write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * 02110-1301 USA
27 *
28 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
29 * @version 1
30 */
31 package jexer.menu;
32
33 import jexer.TKeypress;
34 import jexer.TWidget;
35 import jexer.bits.CellAttributes;
36 import jexer.bits.GraphicsChars;
37 import jexer.bits.MnemonicString;
38 import jexer.event.TKeypressEvent;
39 import jexer.event.TMouseEvent;
40 import jexer.event.TMenuEvent;
41 import static jexer.TKeypress.*;
42
43 /**
44 * TMenuItem implements a menu item.
45 */
46 public class TMenuItem extends TWidget {
47
48 /**
49 * Label for this menu item.
50 */
51 private String label;
52
53 /**
54 * Menu ID. IDs less than 1024 are reserved for common system
55 * functions. Existing ones are defined in TMenu, i.e. TMenu.MID_EXIT.
56 */
57 private int id = TMenu.MID_UNUSED;
58
59 /**
60 * When true, this item can be checked or unchecked.
61 */
62 private boolean checkable = false;
63
64 /**
65 * Set checkable flag.
66 *
67 * @param checkable if true, this menu item can be checked/unchecked
68 */
69 public final void setCheckable(final boolean checkable) {
70 this.checkable = checkable;
71 }
72
73 /**
74 * When true, this item is checked.
75 */
76 private boolean checked = false;
77
78 /**
79 * Global shortcut key.
80 */
81 private TKeypress key;
82
83 /**
84 * When true, a global accelerator can be used to select this item.
85 */
86 private boolean hasKey = false;
87
88 /**
89 * The title string. Use '&' to specify a mnemonic, i.e. "&File" will
90 * highlight the 'F' and allow 'f' or 'F' to select it.
91 */
92 private MnemonicString mnemonic;
93
94 /**
95 * Get the mnemonic string for this menu item.
96 *
97 * @return mnemonic string
98 */
99 public final MnemonicString getMnemonic() {
100 return mnemonic;
101 }
102
103 /**
104 * Set a global accelerator key for this menu item.
105 *
106 * @param key global keyboard accelerator
107 */
108 public final void setKey(final TKeypress key) {
109 hasKey = true;
110 this.key = key;
111
112 int newWidth = (label.length() + 4 + key.toString().length() + 2);
113 if (newWidth > getWidth()) {
114 setWidth(newWidth);
115 }
116 }
117
118 /**
119 * Package private constructor.
120 *
121 * @param parent parent widget
122 * @param id menu id
123 * @param x column relative to parent
124 * @param y row relative to parent
125 * @param label menu item title
126 */
127 TMenuItem(final TMenu parent, final int id, final int x, final int y,
128 final String label) {
129
130 // Set parent and window
131 super(parent);
132
133 mnemonic = new MnemonicString(label);
134
135 setX(x);
136 setY(y);
137 setHeight(1);
138 this.label = mnemonic.getRawLabel();
139 setWidth(label.length() + 4);
140 this.id = id;
141
142 // Default state for some known menu items
143 switch (id) {
144
145 case TMenu.MID_CUT:
146 setEnabled(false);
147 break;
148 case TMenu.MID_COPY:
149 setEnabled(false);
150 break;
151 case TMenu.MID_PASTE:
152 setEnabled(false);
153 break;
154 case TMenu.MID_CLEAR:
155 setEnabled(false);
156 break;
157
158 case TMenu.MID_TILE:
159 break;
160 case TMenu.MID_CASCADE:
161 break;
162 case TMenu.MID_CLOSE_ALL:
163 break;
164 case TMenu.MID_WINDOW_MOVE:
165 break;
166 case TMenu.MID_WINDOW_ZOOM:
167 break;
168 case TMenu.MID_WINDOW_NEXT:
169 break;
170 case TMenu.MID_WINDOW_PREVIOUS:
171 break;
172 case TMenu.MID_WINDOW_CLOSE:
173 break;
174 default:
175 break;
176 }
177
178 }
179
180 /**
181 * Returns true if the mouse is currently on the menu item.
182 *
183 * @param mouse mouse event
184 */
185 private boolean mouseOnMenuItem(final TMouseEvent mouse) {
186 if ((mouse.getY() == 0)
187 && (mouse.getX() >= 0)
188 && (mouse.getX() < getWidth())
189 ) {
190 return true;
191 }
192 return false;
193 }
194
195 /**
196 * Draw a menu item with label.
197 */
198 @Override
199 public void draw() {
200 CellAttributes background = getTheme().getColor("tmenu");
201 CellAttributes menuColor;
202 CellAttributes menuMnemonicColor;
203 if (isAbsoluteActive()) {
204 menuColor = getTheme().getColor("tmenu.highlighted");
205 menuMnemonicColor = getTheme().getColor("tmenu.mnemonic.highlighted");
206 } else {
207 if (isEnabled()) {
208 menuColor = getTheme().getColor("tmenu");
209 menuMnemonicColor = getTheme().getColor("tmenu.mnemonic");
210 } else {
211 menuColor = getTheme().getColor("tmenu.disabled");
212 menuMnemonicColor = getTheme().getColor("tmenu.disabled");
213 }
214 }
215
216 char cVSide = GraphicsChars.WINDOW_SIDE;
217 getScreen().vLineXY(0, 0, 1, cVSide, background);
218 getScreen().vLineXY(getWidth() - 1, 0, 1, cVSide, background);
219
220 getScreen().hLineXY(1, 0, getWidth() - 2, ' ', menuColor);
221 getScreen().putStringXY(2, 0, mnemonic.getRawLabel(), menuColor);
222 if (hasKey) {
223 String keyLabel = key.toString();
224 getScreen().putStringXY((getWidth() - keyLabel.length() - 2), 0,
225 keyLabel, menuColor);
226 }
227 if (mnemonic.getShortcutIdx() >= 0) {
228 getScreen().putCharXY(2 + mnemonic.getShortcutIdx(), 0,
229 mnemonic.getShortcut(), menuMnemonicColor);
230 }
231 if (checked) {
232 assert (checkable);
233 getScreen().putCharXY(1, 0, GraphicsChars.CHECK, menuColor);
234 }
235
236 }
237
238 /**
239 * Dispatch event(s) due to selection or click.
240 */
241 public void dispatch() {
242 assert (isEnabled());
243
244 getApplication().addMenuEvent(new TMenuEvent(id));
245 if (checkable) {
246 checked = !checked;
247 }
248 }
249
250 /**
251 * Handle mouse button presses.
252 *
253 * @param event mouse button press event
254 */
255 /* TODO: this was commented out in d-tui, why?
256 @Override
257 public void onMouseDown(final TMouseEvent event) {
258 if ((mouseOnMenuItem(event)) && (event.mouse1)) {
259 dispatch();
260 return;
261 }
262 }
263 */
264
265 /**
266 * Handle mouse button releases.
267 *
268 * @param mouse mouse button release event
269 */
270 @Override
271 public void onMouseUp(final TMouseEvent mouse) {
272 if ((mouseOnMenuItem(mouse)) && (mouse.isMouse1())) {
273 dispatch();
274 return;
275 }
276 }
277
278 /**
279 * Handle keystrokes.
280 *
281 * @param keypress keystroke event
282 */
283 @Override
284 public void onKeypress(final TKeypressEvent keypress) {
285 if (keypress.equals(kbEnter)) {
286 dispatch();
287 return;
288 }
289
290 // Pass to parent for the things we don't care about.
291 super.onKeypress(keypress);
292 }
293 }