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