cleanup
[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
d36057df
KL
71 // ------------------------------------------------------------------------
72 // Constructors -----------------------------------------------------------
73 // ------------------------------------------------------------------------
91c9a837 74
30d336cc
KL
75 /**
76 * Private constructor.
77 *
78 * @param parent parent widget
79 * @param text label on the button
80 * @param x column relative to parent
81 * @param y row relative to parent
82 */
83 private TButton(final TWidget parent, final String text,
84 final int x, final int y) {
85
86 // Set parent and window
87 super(parent);
88
89 mnemonic = new MnemonicString(text);
90
91 setX(x);
92 setY(y);
93 setHeight(2);
94 setWidth(mnemonic.getRawLabel().length() + 3);
95 }
96
97 /**
98 * Public constructor.
99 *
100 * @param parent parent widget
101 * @param text label on the button
102 * @param x column relative to parent
103 * @param y row relative to parent
104 * @param action to call when button is pressed
105 */
106 public TButton(final TWidget parent, final String text,
107 final int x, final int y, final TAction action) {
108
109 this(parent, text, x, y);
110 this.action = action;
111 }
112
d36057df
KL
113 // ------------------------------------------------------------------------
114 // Event handlers ---------------------------------------------------------
115 // ------------------------------------------------------------------------
116
30d336cc
KL
117 /**
118 * Returns true if the mouse is currently on the button.
119 *
120 * @return if true the mouse is currently on the button
121 */
122 private boolean mouseOnButton() {
123 int rightEdge = getWidth() - 1;
124 if (inButtonPress) {
125 rightEdge++;
126 }
127 if ((mouse != null)
128 && (mouse.getY() == 0)
129 && (mouse.getX() >= 0)
130 && (mouse.getX() < rightEdge)
131 ) {
132 return true;
133 }
134 return false;
135 }
136
30d336cc
KL
137 /**
138 * Handle mouse button presses.
139 *
140 * @param mouse mouse button event
141 */
142 @Override
143 public void onMouseDown(final TMouseEvent mouse) {
144 this.mouse = mouse;
145
7c870d89 146 if ((mouseOnButton()) && (mouse.isMouse1())) {
30d336cc
KL
147 // Begin button press
148 inButtonPress = true;
149 }
150 }
151
152 /**
153 * Handle mouse button releases.
154 *
155 * @param mouse mouse button release event
156 */
157 @Override
158 public void onMouseUp(final TMouseEvent mouse) {
159 this.mouse = mouse;
160
7c870d89 161 if (inButtonPress && mouse.isMouse1()) {
30d336cc 162 // Dispatch the event
a325f111 163 dispatch();
30d336cc
KL
164 }
165
166 }
167
168 /**
169 * Handle mouse movements.
170 *
171 * @param mouse mouse motion event
172 */
173 @Override
174 public void onMouseMotion(final TMouseEvent mouse) {
175 this.mouse = mouse;
176
177 if (!mouseOnButton()) {
178 inButtonPress = false;
179 }
180 }
181
182 /**
183 * Handle keystrokes.
184 *
185 * @param keypress keystroke event
186 */
187 @Override
188 public void onKeypress(final TKeypressEvent keypress) {
189 if (keypress.equals(kbEnter)
190 || keypress.equals(kbSpace)
191 ) {
192 // Dispatch
a325f111 193 dispatch();
30d336cc
KL
194 return;
195 }
196
197 // Pass to parent for the things we don't care about.
198 super.onKeypress(keypress);
199 }
200
d36057df
KL
201 // ------------------------------------------------------------------------
202 // TWidget ----------------------------------------------------------------
203 // ------------------------------------------------------------------------
204
205 /**
206 * Draw a button with a shadow.
207 */
208 @Override
209 public void draw() {
210 CellAttributes buttonColor;
211 CellAttributes menuMnemonicColor;
212 CellAttributes shadowColor = new CellAttributes();
213 shadowColor.setTo(getWindow().getBackground());
214 shadowColor.setForeColor(Color.BLACK);
215 shadowColor.setBold(false);
216
217 if (!isEnabled()) {
218 buttonColor = getTheme().getColor("tbutton.disabled");
219 menuMnemonicColor = getTheme().getColor("tbutton.disabled");
220 } else if (isAbsoluteActive()) {
221 buttonColor = getTheme().getColor("tbutton.active");
222 menuMnemonicColor = getTheme().getColor("tbutton.mnemonic.highlighted");
223 } else {
224 buttonColor = getTheme().getColor("tbutton.inactive");
225 menuMnemonicColor = getTheme().getColor("tbutton.mnemonic");
226 }
227
228 if (inButtonPress) {
a69ed767
KL
229 putCharXY(1, 0, ' ', buttonColor);
230 putStringXY(2, 0, mnemonic.getRawLabel(), buttonColor);
231 putCharXY(getWidth() - 1, 0, ' ', buttonColor);
d36057df 232 } else {
a69ed767
KL
233 putCharXY(0, 0, ' ', buttonColor);
234 putStringXY(1, 0, mnemonic.getRawLabel(), buttonColor);
235 putCharXY(getWidth() - 2, 0, ' ', buttonColor);
d36057df 236
a69ed767 237 putCharXY(getWidth() - 1, 0,
d36057df 238 GraphicsChars.CP437[0xDC], shadowColor);
a69ed767 239 hLineXY(1, 1, getWidth() - 1,
d36057df
KL
240 GraphicsChars.CP437[0xDF], shadowColor);
241 }
242 if (mnemonic.getShortcutIdx() >= 0) {
243 if (inButtonPress) {
a69ed767 244 putCharXY(2 + mnemonic.getShortcutIdx(), 0,
d36057df
KL
245 mnemonic.getShortcut(), menuMnemonicColor);
246 } else {
a69ed767 247 putCharXY(1 + mnemonic.getShortcutIdx(), 0,
d36057df
KL
248 mnemonic.getShortcut(), menuMnemonicColor);
249 }
250
251 }
252 }
253
254 // ------------------------------------------------------------------------
255 // TButton ----------------------------------------------------------------
256 // ------------------------------------------------------------------------
257
258 /**
259 * Get the mnemonic string for this button.
260 *
261 * @return mnemonic string
262 */
263 public MnemonicString getMnemonic() {
264 return mnemonic;
265 }
266
267 /**
268 * Act as though the button was pressed. This is useful for other UI
269 * elements to get the same action as if the user clicked the button.
270 */
271 public void dispatch() {
272 if (action != null) {
273 action.DO();
274 inButtonPress = false;
275 }
276 }
277
30d336cc 278}