make Windows look like X11, why does this work
[fanfix.git] / src / jexer / TButton.java
CommitLineData
30d336cc
KL
1/**
2 * Jexer - Java Text User Interface
3 *
4 * License: LGPLv3 or later
5 *
6 * This module is licensed under the GNU Lesser General Public License
7 * Version 3. Please see the file "COPYING" in this directory for more
8 * information about the GNU Lesser General Public License Version 3.
9 *
10 * Copyright (C) 2015 Kevin Lamonte
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 3 of
15 * the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this program; if not, see
24 * http://www.gnu.org/licenses/, or write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * 02110-1301 USA
27 *
28 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
29 * @version 1
30 */
31package jexer;
32
33import jexer.bits.CellAttributes;
34import jexer.bits.Color;
35import jexer.bits.GraphicsChars;
36import jexer.bits.MnemonicString;
37import jexer.event.TKeypressEvent;
38import jexer.event.TMouseEvent;
39import static jexer.TKeypress.*;
40
41/**
42 * TButton implements a simple button. To make the button do something, pass
43 * a TAction class to its constructor.
44 *
45 * @see TAction#DO()
46 */
47public final class TButton extends TWidget {
48
49 /**
50 * The shortcut and button text.
51 */
52 private MnemonicString mnemonic;
53
92554d64
KL
54 /**
55 * Get the mnemonic string for this button.
56 *
57 * @return mnemonic string
58 */
59 public final MnemonicString getMnemonic() {
60 return mnemonic;
61 }
62
30d336cc
KL
63 /**
64 * Remember mouse state.
65 */
66 private TMouseEvent mouse;
67
68 /**
69 * True when the button is being pressed and held down.
70 */
71 private boolean inButtonPress = false;
72
73 /**
74 * The action to perform when the button is clicked.
75 */
76 private TAction action;
77
78 /**
79 * Private constructor.
80 *
81 * @param parent parent widget
82 * @param text label on the button
83 * @param x column relative to parent
84 * @param y row relative to parent
85 */
86 private TButton(final TWidget parent, final String text,
87 final int x, final int y) {
88
89 // Set parent and window
90 super(parent);
91
92 mnemonic = new MnemonicString(text);
93
94 setX(x);
95 setY(y);
96 setHeight(2);
97 setWidth(mnemonic.getRawLabel().length() + 3);
98 }
99
100 /**
101 * Public constructor.
102 *
103 * @param parent parent widget
104 * @param text label on the button
105 * @param x column relative to parent
106 * @param y row relative to parent
107 * @param action to call when button is pressed
108 */
109 public TButton(final TWidget parent, final String text,
110 final int x, final int y, final TAction action) {
111
112 this(parent, text, x, y);
113 this.action = action;
114 }
115
116 /**
117 * Returns true if the mouse is currently on the button.
118 *
119 * @return if true the mouse is currently on the button
120 */
121 private boolean mouseOnButton() {
122 int rightEdge = getWidth() - 1;
123 if (inButtonPress) {
124 rightEdge++;
125 }
126 if ((mouse != null)
127 && (mouse.getY() == 0)
128 && (mouse.getX() >= 0)
129 && (mouse.getX() < rightEdge)
130 ) {
131 return true;
132 }
133 return false;
134 }
135
136 /**
137 * Draw a button with a shadow.
138 */
139 @Override
140 public void draw() {
141 CellAttributes buttonColor;
142 CellAttributes menuMnemonicColor;
143 CellAttributes shadowColor = new CellAttributes();
144 shadowColor.setTo(getWindow().getBackground());
145 shadowColor.setForeColor(Color.BLACK);
146 shadowColor.setBold(false);
147
7c870d89 148 if (!isEnabled()) {
30d336cc
KL
149 buttonColor = getTheme().getColor("tbutton.disabled");
150 menuMnemonicColor = getTheme().getColor("tbutton.disabled");
7c870d89 151 } else if (isAbsoluteActive()) {
30d336cc
KL
152 buttonColor = getTheme().getColor("tbutton.active");
153 menuMnemonicColor = getTheme().getColor("tbutton.mnemonic.highlighted");
154 } else {
155 buttonColor = getTheme().getColor("tbutton.inactive");
156 menuMnemonicColor = getTheme().getColor("tbutton.mnemonic");
157 }
158
159 if (inButtonPress) {
160 getScreen().putCharXY(1, 0, ' ', buttonColor);
0d47c546 161 getScreen().putStringXY(2, 0, mnemonic.getRawLabel(), buttonColor);
30d336cc
KL
162 getScreen().putCharXY(getWidth() - 1, 0, ' ', buttonColor);
163 } else {
164 getScreen().putCharXY(0, 0, ' ', buttonColor);
0d47c546 165 getScreen().putStringXY(1, 0, mnemonic.getRawLabel(), buttonColor);
30d336cc
KL
166 getScreen().putCharXY(getWidth() - 2, 0, ' ', buttonColor);
167
168 getScreen().putCharXY(getWidth() - 1, 0,
169 GraphicsChars.CP437[0xDC], shadowColor);
170 getScreen().hLineXY(1, 1, getWidth() - 1,
171 GraphicsChars.CP437[0xDF], shadowColor);
172 }
173 if (mnemonic.getShortcutIdx() >= 0) {
174 if (inButtonPress) {
175 getScreen().putCharXY(2 + mnemonic.getShortcutIdx(), 0,
176 mnemonic.getShortcut(), menuMnemonicColor);
177 } else {
178 getScreen().putCharXY(1 + mnemonic.getShortcutIdx(), 0,
179 mnemonic.getShortcut(), menuMnemonicColor);
180 }
181
182 }
183 }
184
185 /**
186 * Handle mouse button presses.
187 *
188 * @param mouse mouse button event
189 */
190 @Override
191 public void onMouseDown(final TMouseEvent mouse) {
192 this.mouse = mouse;
193
7c870d89 194 if ((mouseOnButton()) && (mouse.isMouse1())) {
30d336cc
KL
195 // Begin button press
196 inButtonPress = true;
197 }
198 }
199
200 /**
201 * Handle mouse button releases.
202 *
203 * @param mouse mouse button release event
204 */
205 @Override
206 public void onMouseUp(final TMouseEvent mouse) {
207 this.mouse = mouse;
208
7c870d89 209 if (inButtonPress && mouse.isMouse1()) {
30d336cc
KL
210 inButtonPress = false;
211 // Dispatch the event
212 if (action != null) {
213 action.DO();
214 }
215 }
216
217 }
218
219 /**
220 * Handle mouse movements.
221 *
222 * @param mouse mouse motion event
223 */
224 @Override
225 public void onMouseMotion(final TMouseEvent mouse) {
226 this.mouse = mouse;
227
228 if (!mouseOnButton()) {
229 inButtonPress = false;
230 }
231 }
232
233 /**
234 * Handle keystrokes.
235 *
236 * @param keypress keystroke event
237 */
238 @Override
239 public void onKeypress(final TKeypressEvent keypress) {
240 if (keypress.equals(kbEnter)
241 || keypress.equals(kbSpace)
242 ) {
243 // Dispatch
244 if (action != null) {
245 action.DO();
246 }
247 return;
248 }
249
250 // Pass to parent for the things we don't care about.
251 super.onKeypress(keypress);
252 }
253
254}