2 * Jexer - Java Text User Interface
4 * The MIT License (MIT)
6 * Copyright (C) 2017 Kevin Lamonte
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:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
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.
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
31 import jexer
.TKeypress
;
33 import jexer
.bits
.CellAttributes
;
34 import jexer
.bits
.GraphicsChars
;
35 import jexer
.bits
.MnemonicString
;
36 import jexer
.event
.TKeypressEvent
;
37 import jexer
.event
.TMouseEvent
;
38 import jexer
.event
.TMenuEvent
;
39 import static jexer
.TKeypress
.*;
42 * TMenuItem implements a menu item.
44 public class TMenuItem
extends TWidget
{
47 * Label for this menu item.
52 * Menu ID. IDs less than 1024 are reserved for common system
53 * functions. Existing ones are defined in TMenu, i.e. TMenu.MID_EXIT.
55 private int id
= TMenu
.MID_UNUSED
;
58 * Get the menu item ID.
62 public final int getId() {
67 * When true, this item can be checked or unchecked.
69 private boolean checkable
= false;
74 * @param checkable if true, this menu item can be checked/unchecked
76 public final void setCheckable(final boolean checkable
) {
77 this.checkable
= checkable
;
81 * When true, this item is checked.
83 private boolean checked
= false;
86 * Global shortcut key.
88 private TKeypress key
;
91 * The title string. Use '&' to specify a mnemonic, i.e. "&File" will
92 * highlight the 'F' and allow 'f' or 'F' to select it.
94 private MnemonicString mnemonic
;
97 * Get the mnemonic string for this menu item.
99 * @return mnemonic string
101 public final MnemonicString
getMnemonic() {
106 * Get a global accelerator key for this menu item.
108 * @return global keyboard accelerator, or null if no key is associated
111 public final TKeypress
getKey() {
116 * Set a global accelerator key for this menu item.
118 * @param key global keyboard accelerator
120 public final void setKey(final TKeypress key
) {
124 int newWidth
= (label
.length() + 4 + key
.toString().length() + 2);
125 if (newWidth
> getWidth()) {
132 * Package private constructor.
134 * @param parent parent widget
136 * @param x column relative to parent
137 * @param y row relative to parent
138 * @param label menu item title
140 TMenuItem(final TMenu parent
, final int id
, final int x
, final int y
,
141 final String label
) {
143 // Set parent and window
146 mnemonic
= new MnemonicString(label
);
151 this.label
= mnemonic
.getRawLabel();
152 setWidth(label
.length() + 4);
155 // Default state for some known menu items
164 case TMenu
.MID_PASTE
:
167 case TMenu
.MID_CLEAR
:
173 case TMenu
.MID_CASCADE
:
175 case TMenu
.MID_CLOSE_ALL
:
177 case TMenu
.MID_WINDOW_MOVE
:
179 case TMenu
.MID_WINDOW_ZOOM
:
181 case TMenu
.MID_WINDOW_NEXT
:
183 case TMenu
.MID_WINDOW_PREVIOUS
:
185 case TMenu
.MID_WINDOW_CLOSE
:
194 * Returns true if the mouse is currently on the menu item.
196 * @param mouse mouse event
197 * @return if true then the mouse is currently on this item
199 private boolean mouseOnMenuItem(final TMouseEvent mouse
) {
200 if ((mouse
.getY() == 0)
201 && (mouse
.getX() >= 0)
202 && (mouse
.getX() < getWidth())
210 * Draw a menu item with label.
214 CellAttributes background
= getTheme().getColor("tmenu");
215 CellAttributes menuColor
;
216 CellAttributes menuMnemonicColor
;
217 if (isAbsoluteActive()) {
218 menuColor
= getTheme().getColor("tmenu.highlighted");
219 menuMnemonicColor
= getTheme().getColor("tmenu.mnemonic.highlighted");
222 menuColor
= getTheme().getColor("tmenu");
223 menuMnemonicColor
= getTheme().getColor("tmenu.mnemonic");
225 menuColor
= getTheme().getColor("tmenu.disabled");
226 menuMnemonicColor
= getTheme().getColor("tmenu.disabled");
230 char cVSide
= GraphicsChars
.WINDOW_SIDE
;
231 getScreen().vLineXY(0, 0, 1, cVSide
, background
);
232 getScreen().vLineXY(getWidth() - 1, 0, 1, cVSide
, background
);
234 getScreen().hLineXY(1, 0, getWidth() - 2, ' ', menuColor
);
235 getScreen().putStringXY(2, 0, mnemonic
.getRawLabel(), menuColor
);
237 String keyLabel
= key
.toString();
238 getScreen().putStringXY((getWidth() - keyLabel
.length() - 2), 0,
239 keyLabel
, menuColor
);
241 if (mnemonic
.getShortcutIdx() >= 0) {
242 getScreen().putCharXY(2 + mnemonic
.getShortcutIdx(), 0,
243 mnemonic
.getShortcut(), menuMnemonicColor
);
247 getScreen().putCharXY(1, 0, GraphicsChars
.CHECK
, menuColor
);
253 * Dispatch event(s) due to selection or click.
255 public void dispatch() {
256 assert (isEnabled());
258 getApplication().postMenuEvent(new TMenuEvent(id
));
265 * Handle mouse button releases.
267 * @param mouse mouse button release event
270 public void onMouseUp(final TMouseEvent mouse
) {
271 if ((mouseOnMenuItem(mouse
)) && (mouse
.isMouse1())) {
280 * @param keypress keystroke event
283 public void onKeypress(final TKeypressEvent keypress
) {
284 if (keypress
.equals(kbEnter
)) {
289 // Pass to parent for the things we don't care about.
290 super.onKeypress(keypress
);