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 parent parent widget
129 * @param text text for the bar on the bottom row
131 public TStatusBar(final TWidget parent
, final String text
) {
133 // Set parent and window
134 super(parent
, false, 0, 0, text
.length(), 1);
140 * Public constructor.
142 * @param parent parent widget
144 public TStatusBar(final TWidget parent
) {
148 // ------------------------------------------------------------------------
149 // Event handlers ---------------------------------------------------------
150 // ------------------------------------------------------------------------
155 * @param keypress keystroke event
156 * @return true if this keypress was consumed
158 public boolean statusBarKeypress(final TKeypressEvent keypress
) {
159 for (TStatusBarKey key
: keys
) {
160 if (keypress
.equals(key
.key
)) {
161 getApplication().postMenuEvent(new TCommandEvent(key
.cmd
));
169 * Returns true if the mouse is currently on the button.
171 * @param statusBarKey the status bar item
172 * @return if true the mouse is currently on the button
174 private boolean mouseOnShortcut(final TStatusBarKey statusBarKey
) {
176 && (mouse
.getAbsoluteY() == getApplication().getDesktopBottom())
177 && (mouse
.getAbsoluteX() >= statusBarKey
.x
)
178 && (mouse
.getAbsoluteX() < statusBarKey
.x
+ statusBarKey
.width())
186 * Handle mouse button presses.
188 * @param mouse mouse button event
189 * @return true if this mouse event was consumed
191 public boolean statusBarMouseDown(final TMouseEvent mouse
) {
194 for (TStatusBarKey key
: keys
) {
195 if ((mouseOnShortcut(key
)) && (mouse
.isMouse1())) {
204 * Handle mouse button releases.
206 * @param mouse mouse button release event
207 * @return true if this mouse event was consumed
209 public boolean statusBarMouseUp(final TMouseEvent mouse
) {
212 for (TStatusBarKey key
: keys
) {
213 if (key
.selected
&& mouse
.isMouse1()) {
214 key
.selected
= false;
216 // Dispatch the event
217 getApplication().postMenuEvent(new TCommandEvent(key
.cmd
));
225 * Handle mouse movements.
227 * @param mouse mouse motion event
229 public void statusBarMouseMotion(final TMouseEvent mouse
) {
232 for (TStatusBarKey key
: keys
) {
233 if (!mouseOnShortcut(key
)) {
234 key
.selected
= false;
239 // ------------------------------------------------------------------------
240 // TWidget ----------------------------------------------------------------
241 // ------------------------------------------------------------------------
248 CellAttributes barColor
= new CellAttributes();
249 barColor
.setTo(getTheme().getColor("tstatusbar.text"));
250 CellAttributes keyColor
= new CellAttributes();
251 keyColor
.setTo(getTheme().getColor("tstatusbar.button"));
252 CellAttributes selectedColor
= new CellAttributes();
253 selectedColor
.setTo(getTheme().getColor("tstatusbar.selected"));
255 // Status bar is weird. Its draw() method is called directly by
256 // TApplication after everything is drawn, and after
257 // Screen.resetClipping(). So at this point we are drawing in
258 // absolute coordinates, not relative to our TWindow.
259 int row
= getScreen().getHeight() - 1;
260 int width
= getScreen().getWidth();
262 hLineXY(0, row
, width
, ' ', barColor
);
265 for (TStatusBarKey key
: keys
) {
266 String keyStr
= key
.key
.toString();
268 putCharXY(col
++, row
, ' ', selectedColor
);
269 putStringXY(col
, row
, keyStr
, selectedColor
);
270 col
+= keyStr
.length();
271 putCharXY(col
++, row
, ' ', selectedColor
);
272 putStringXY(col
, row
, key
.label
, selectedColor
);
273 col
+= key
.label
.length();
274 putCharXY(col
++, row
, ' ', selectedColor
);
276 putCharXY(col
++, row
, ' ', barColor
);
277 putStringXY(col
, row
, keyStr
, keyColor
);
278 col
+= keyStr
.length() + 1;
279 putStringXY(col
, row
, key
.label
, barColor
);
280 col
+= key
.label
.length();
281 putCharXY(col
++, row
, ' ', barColor
);
284 if (text
.length() > 0) {
285 if (keys
.size() > 0) {
286 putCharXY(col
++, row
, GraphicsChars
.VERTICAL_BAR
, barColor
);
288 putCharXY(col
++, row
, ' ', barColor
);
289 putStringXY(col
, row
, text
, barColor
);
293 // ------------------------------------------------------------------------
294 // TStatusBar -------------------------------------------------------------
295 // ------------------------------------------------------------------------
298 * Add a key to this status bar.
300 * @param key the key to trigger on
301 * @param cmd the command event to issue when key is pressed or this item
303 * @param label the label for this action
305 public void addShortcutKeypress(final TKeypress key
, final TCommand cmd
,
306 final String label
) {
308 TStatusBarKey newKey
= new TStatusBarKey(key
, cmd
, label
);
309 if (keys
.size() > 0) {
310 TStatusBarKey oldKey
= keys
.get(keys
.size() - 1);
311 newKey
.x
= oldKey
.x
+ oldKey
.width();
317 * Set the text to display on the right side of the shortcut keys.
319 * @param text the new text
321 public void setText(final String text
) {