update README
[fanfix.git] / src / jexer / TButton.java
CommitLineData
daa4106c 1/*
30d336cc
KL
2 * Jexer - Java Text User Interface
3 *
e16dda65 4 * The MIT License (MIT)
30d336cc 5 *
a69ed767 6 * Copyright (C) 2019 Kevin Lamonte
30d336cc 7 *
e16dda65
KL
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:
30d336cc 14 *
e16dda65
KL
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
30d336cc 17 *
e16dda65
KL
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.
30d336cc
KL
25 *
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
27 * @version 1
28 */
29package jexer;
30
31import jexer.bits.CellAttributes;
32import jexer.bits.Color;
33import jexer.bits.GraphicsChars;
34import jexer.bits.MnemonicString;
35import jexer.event.TKeypressEvent;
36import jexer.event.TMouseEvent;
37import static jexer.TKeypress.*;
38
39/**
40 * TButton implements a simple button. To make the button do something, pass
41 * a TAction class to its constructor.
42 *
43 * @see TAction#DO()
44 */
051e2913 45public class TButton extends TWidget {
30d336cc 46
d36057df
KL
47 // ------------------------------------------------------------------------
48 // Variables --------------------------------------------------------------
49 // ------------------------------------------------------------------------
50
30d336cc
KL
51 /**
52 * The shortcut and button text.
53 */
54 private MnemonicString mnemonic;
55
56 /**
57 * Remember mouse state.
58 */
59 private TMouseEvent mouse;
60
61 /**
62 * True when the button is being pressed and held down.
63 */
64 private boolean inButtonPress = false;
65
66 /**
67 * The action to perform when the button is clicked.
68 */
69 private TAction action;
70
e23ea538
KL
71 /**
72 * The background color used for the button "shadow".
73 */
74 private CellAttributes shadowColor;
75
d36057df
KL
76 // ------------------------------------------------------------------------
77 // Constructors -----------------------------------------------------------
78 // ------------------------------------------------------------------------
91c9a837 79
30d336cc
KL
80 /**
81 * Private constructor.
82 *
83 * @param parent parent widget
84 * @param text label on the button
85 * @param x column relative to parent
86 * @param y row relative to parent
87 */
88 private TButton(final TWidget parent, final String text,
89 final int x, final int y) {
90
91 // Set parent and window
92 super(parent);
93
94 mnemonic = new MnemonicString(text);
95
96 setX(x);
97 setY(y);
98 setHeight(2);
99 setWidth(mnemonic.getRawLabel().length() + 3);
e23ea538
KL
100
101 shadowColor = new CellAttributes();
102 shadowColor.setTo(getWindow().getBackground());
103 shadowColor.setForeColor(Color.BLACK);
104 shadowColor.setBold(false);
30d336cc
KL
105 }
106
107 /**
108 * Public constructor.
109 *
110 * @param parent parent widget
111 * @param text label on the button
112 * @param x column relative to parent
113 * @param y row relative to parent
114 * @param action to call when button is pressed
115 */
116 public TButton(final TWidget parent, final String text,
117 final int x, final int y, final TAction action) {
118
119 this(parent, text, x, y);
120 this.action = action;
121 }
122
d36057df
KL
123 // ------------------------------------------------------------------------
124 // Event handlers ---------------------------------------------------------
125 // ------------------------------------------------------------------------
126
30d336cc
KL
127 /**
128 * Returns true if the mouse is currently on the button.
129 *
130 * @return if true the mouse is currently on the button
131 */
132 private boolean mouseOnButton() {
133 int rightEdge = getWidth() - 1;
134 if (inButtonPress) {
135 rightEdge++;
136 }
137 if ((mouse != null)
138 && (mouse.getY() == 0)
139 && (mouse.getX() >= 0)
140 && (mouse.getX() < rightEdge)
141 ) {
142 return true;
143 }
144 return false;
145 }
146
30d336cc
KL
147 /**
148 * Handle mouse button presses.
149 *
150 * @param mouse mouse button event
151 */
152 @Override
153 public void onMouseDown(final TMouseEvent mouse) {
154 this.mouse = mouse;
155
7c870d89 156 if ((mouseOnButton()) && (mouse.isMouse1())) {
30d336cc
KL
157 // Begin button press
158 inButtonPress = true;
159 }
160 }
161
162 /**
163 * Handle mouse button releases.
164 *
165 * @param mouse mouse button release event
166 */
167 @Override
168 public void onMouseUp(final TMouseEvent mouse) {
169 this.mouse = mouse;
170
7c870d89 171 if (inButtonPress && mouse.isMouse1()) {
30d336cc 172 // Dispatch the event
a325f111 173 dispatch();
30d336cc
KL
174 }
175
176 }
177
178 /**
179 * Handle mouse movements.
180 *
181 * @param mouse mouse motion event
182 */
183 @Override
184 public void onMouseMotion(final TMouseEvent mouse) {
185 this.mouse = mouse;
186
187 if (!mouseOnButton()) {
188 inButtonPress = false;
189 }
190 }
191
192 /**
193 * Handle keystrokes.
194 *
195 * @param keypress keystroke event
196 */
197 @Override
198 public void onKeypress(final TKeypressEvent keypress) {
199 if (keypress.equals(kbEnter)
200 || keypress.equals(kbSpace)
201 ) {
202 // Dispatch
a325f111 203 dispatch();
30d336cc
KL
204 return;
205 }
206
207 // Pass to parent for the things we don't care about.
208 super.onKeypress(keypress);
209 }
210
d36057df
KL
211 // ------------------------------------------------------------------------
212 // TWidget ----------------------------------------------------------------
213 // ------------------------------------------------------------------------
214
215 /**
216 * Draw a button with a shadow.
217 */
218 @Override
219 public void draw() {
220 CellAttributes buttonColor;
221 CellAttributes menuMnemonicColor;
d36057df
KL
222
223 if (!isEnabled()) {
224 buttonColor = getTheme().getColor("tbutton.disabled");
225 menuMnemonicColor = getTheme().getColor("tbutton.disabled");
226 } else if (isAbsoluteActive()) {
227 buttonColor = getTheme().getColor("tbutton.active");
228 menuMnemonicColor = getTheme().getColor("tbutton.mnemonic.highlighted");
229 } else {
230 buttonColor = getTheme().getColor("tbutton.inactive");
231 menuMnemonicColor = getTheme().getColor("tbutton.mnemonic");
232 }
233
234 if (inButtonPress) {
a69ed767
KL
235 putCharXY(1, 0, ' ', buttonColor);
236 putStringXY(2, 0, mnemonic.getRawLabel(), buttonColor);
237 putCharXY(getWidth() - 1, 0, ' ', buttonColor);
d36057df 238 } else {
a69ed767
KL
239 putCharXY(0, 0, ' ', buttonColor);
240 putStringXY(1, 0, mnemonic.getRawLabel(), buttonColor);
241 putCharXY(getWidth() - 2, 0, ' ', buttonColor);
d36057df 242
a69ed767 243 putCharXY(getWidth() - 1, 0,
d36057df 244 GraphicsChars.CP437[0xDC], shadowColor);
a69ed767 245 hLineXY(1, 1, getWidth() - 1,
d36057df
KL
246 GraphicsChars.CP437[0xDF], shadowColor);
247 }
248 if (mnemonic.getShortcutIdx() >= 0) {
249 if (inButtonPress) {
a69ed767 250 putCharXY(2 + mnemonic.getShortcutIdx(), 0,
d36057df
KL
251 mnemonic.getShortcut(), menuMnemonicColor);
252 } else {
a69ed767 253 putCharXY(1 + mnemonic.getShortcutIdx(), 0,
d36057df
KL
254 mnemonic.getShortcut(), menuMnemonicColor);
255 }
d36057df
KL
256 }
257 }
258
259 // ------------------------------------------------------------------------
260 // TButton ----------------------------------------------------------------
261 // ------------------------------------------------------------------------
262
263 /**
264 * Get the mnemonic string for this button.
265 *
266 * @return mnemonic string
267 */
268 public MnemonicString getMnemonic() {
269 return mnemonic;
270 }
271
272 /**
273 * Act as though the button was pressed. This is useful for other UI
274 * elements to get the same action as if the user clicked the button.
275 */
276 public void dispatch() {
277 if (action != null) {
278 action.DO();
279 inButtonPress = false;
280 }
281 }
282
e23ea538
KL
283 /**
284 * Set the background color used for the button "shadow".
285 *
286 * @param color the new background color
287 */
288 public void setShadowColor(final CellAttributes color) {
289 shadowColor = new CellAttributes();
290 shadowColor.setTo(color);
291 shadowColor.setForeColor(Color.BLACK);
292 shadowColor.setBold(false);
293 }
294
30d336cc 295}