2 * Jexer - Java Text User Interface
4 * The MIT License (MIT)
6 * Copyright (C) 2019 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 java
.util
.ArrayList
;
32 import java
.util
.List
;
34 import jexer
.bits
.CellAttributes
;
35 import jexer
.bits
.GraphicsChars
;
36 import jexer
.event
.TCommandEvent
;
37 import jexer
.event
.TKeypressEvent
;
38 import jexer
.event
.TMouseEvent
;
41 * TStatusBar implements a status line with clickable buttons.
43 public class TStatusBar
extends TWidget
{
45 // ------------------------------------------------------------------------
46 // Variables --------------------------------------------------------------
47 // ------------------------------------------------------------------------
50 * Remember mouse state.
52 private TMouseEvent mouse
;
55 * The text to display on the right side of the shortcut keys.
57 private String text
= null;
62 private List
<TStatusBarKey
> keys
= new ArrayList
<TStatusBarKey
>();
65 * A single shortcut key.
67 private class TStatusBarKey
{
70 * The keypress for this action.
75 * The command to issue.
85 * If true, the mouse is on this key.
87 public boolean selected
;
90 * The left edge coordinate to draw this key with.
95 * The width of this key on the screen.
97 * @return the number of columns this takes when drawn
100 return this.label
.length() + this.key
.toString().length() + 3;
104 * Add a key to this status bar.
106 * @param key the key to trigger on
107 * @param cmd the command event to issue when key is pressed or this
109 * @param label the label for this action
111 public TStatusBarKey(final TKeypress key
, final TCommand cmd
,
112 final String label
) {
121 // ------------------------------------------------------------------------
122 // Constructors -----------------------------------------------------------
123 // ------------------------------------------------------------------------
126 * Public constructor.
128 * @param window the window associated with this status bar
129 * @param text text for the bar on the bottom row
131 public TStatusBar(final TWindow window
, final String text
) {
133 // TStatusBar is a parentless widget, because TApplication handles
134 // its drawing and event routing directly.
135 super(null, false, 0, 0, text
.length(), 1);
142 * Public constructor.
144 * @param window the window associated with this status bar
146 public TStatusBar(final TWindow window
) {
150 // ------------------------------------------------------------------------
151 // Event handlers ---------------------------------------------------------
152 // ------------------------------------------------------------------------
157 * @param keypress keystroke event
158 * @return true if this keypress was consumed
160 public boolean statusBarKeypress(final TKeypressEvent keypress
) {
161 for (TStatusBarKey key
: keys
) {
162 if (keypress
.equals(key
.key
)) {
163 getApplication().postMenuEvent(new TCommandEvent(key
.cmd
));
171 * Returns true if the mouse is currently on the button.
173 * @param statusBarKey the status bar item
174 * @return if true the mouse is currently on the button
176 private boolean mouseOnShortcut(final TStatusBarKey statusBarKey
) {
178 && (mouse
.getAbsoluteY() == getApplication().getDesktopBottom())
179 && (mouse
.getAbsoluteX() >= statusBarKey
.x
)
180 && (mouse
.getAbsoluteX() < statusBarKey
.x
+ statusBarKey
.width())
188 * Handle mouse button presses.
190 * @param mouse mouse button event
191 * @return true if this mouse event was consumed
193 public boolean statusBarMouseDown(final TMouseEvent mouse
) {
196 for (TStatusBarKey key
: keys
) {
197 if ((mouseOnShortcut(key
)) && (mouse
.isMouse1())) {
206 * Handle mouse button releases.
208 * @param mouse mouse button release event
209 * @return true if this mouse event was consumed
211 public boolean statusBarMouseUp(final TMouseEvent mouse
) {
214 for (TStatusBarKey key
: keys
) {
215 if (key
.selected
&& mouse
.isMouse1()) {
216 key
.selected
= false;
218 // Dispatch the event
219 getApplication().postMenuEvent(new TCommandEvent(key
.cmd
));
227 * Handle mouse movements.
229 * @param mouse mouse motion event
231 public void statusBarMouseMotion(final TMouseEvent mouse
) {
234 for (TStatusBarKey key
: keys
) {
235 if (!mouseOnShortcut(key
)) {
236 key
.selected
= false;
241 // ------------------------------------------------------------------------
242 // TWidget ----------------------------------------------------------------
243 // ------------------------------------------------------------------------
250 CellAttributes barColor
= new CellAttributes();
251 barColor
.setTo(getTheme().getColor("tstatusbar.text"));
252 CellAttributes keyColor
= new CellAttributes();
253 keyColor
.setTo(getTheme().getColor("tstatusbar.button"));
254 CellAttributes selectedColor
= new CellAttributes();
255 selectedColor
.setTo(getTheme().getColor("tstatusbar.selected"));
257 // Status bar is weird. Its draw() method is called directly by
258 // TApplication after everything is drawn, and after
259 // Screen.resetClipping(). So at this point we are drawing in
260 // absolute coordinates, not relative to our TWindow.
261 int row
= getScreen().getHeight() - 1;
262 int width
= getScreen().getWidth();
264 hLineXY(0, row
, width
, ' ', barColor
);
267 for (TStatusBarKey key
: keys
) {
268 String keyStr
= key
.key
.toString();
270 putCharXY(col
++, row
, ' ', selectedColor
);
271 putStringXY(col
, row
, keyStr
, selectedColor
);
272 col
+= keyStr
.length();
273 putCharXY(col
++, row
, ' ', selectedColor
);
274 putStringXY(col
, row
, key
.label
, selectedColor
);
275 col
+= key
.label
.length();
276 putCharXY(col
++, row
, ' ', selectedColor
);
278 putCharXY(col
++, row
, ' ', barColor
);
279 putStringXY(col
, row
, keyStr
, keyColor
);
280 col
+= keyStr
.length() + 1;
281 putStringXY(col
, row
, key
.label
, barColor
);
282 col
+= key
.label
.length();
283 putCharXY(col
++, row
, ' ', barColor
);
286 if (text
.length() > 0) {
287 if (keys
.size() > 0) {
288 putCharXY(col
++, row
, GraphicsChars
.VERTICAL_BAR
, barColor
);
290 putCharXY(col
++, row
, ' ', barColor
);
291 putStringXY(col
, row
, text
, barColor
);
295 // ------------------------------------------------------------------------
296 // TStatusBar -------------------------------------------------------------
297 // ------------------------------------------------------------------------
300 * Add a key to this status bar.
302 * @param key the key to trigger on
303 * @param cmd the command event to issue when key is pressed or this item
305 * @param label the label for this action
307 public void addShortcutKeypress(final TKeypress key
, final TCommand cmd
,
308 final String label
) {
310 TStatusBarKey newKey
= new TStatusBarKey(key
, cmd
, label
);
311 if (keys
.size() > 0) {
312 TStatusBarKey oldKey
= keys
.get(keys
.size() - 1);
313 newKey
.x
= oldKey
.x
+ oldKey
.width();
319 * Set the text to display on the right side of the shortcut keys.
321 * @param text the new text
323 public void setText(final String text
) {