Commit | Line | Data |
---|---|---|
051e2913 KL |
1 | /* |
2 | * Jexer - Java Text User Interface | |
3 | * | |
4 | * The MIT License (MIT) | |
5 | * | |
6 | * Copyright (C) 2017 Kevin Lamonte | |
7 | * | |
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: | |
14 | * | |
15 | * The above copyright notice and this permission notice shall be included in | |
16 | * all copies or substantial portions of the Software. | |
17 | * | |
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. | |
25 | * | |
26 | * @author Kevin Lamonte [kevin.lamonte@gmail.com] | |
27 | * @version 1 | |
28 | */ | |
29 | package jexer; | |
30 | ||
31 | import java.util.List; | |
32 | ||
33 | import jexer.bits.CellAttributes; | |
34 | import jexer.bits.GraphicsChars; | |
35 | import jexer.event.TKeypressEvent; | |
36 | import jexer.event.TMouseEvent; | |
37 | import static jexer.TKeypress.*; | |
38 | ||
39 | /** | |
40 | * TComboBox implements a combobox containing a drop-down list and edit | |
41 | * field. Alt-Down can be used to show the drop-down. | |
42 | */ | |
43 | public class TComboBox extends TWidget { | |
44 | ||
45 | // ------------------------------------------------------------------------ | |
46 | // Variables -------------------------------------------------------------- | |
47 | // ------------------------------------------------------------------------ | |
48 | ||
49 | /** | |
50 | * The list of items in the drop-down. | |
51 | */ | |
52 | private TList list; | |
53 | ||
54 | /** | |
55 | * The edit field containing the value to return. | |
56 | */ | |
57 | private TField field; | |
58 | ||
59 | /** | |
60 | * The action to perform when the user selects an item (clicks or enter). | |
61 | */ | |
62 | private TAction updateAction = null; | |
63 | ||
64 | // ------------------------------------------------------------------------ | |
65 | // Constructors ----------------------------------------------------------- | |
66 | // ------------------------------------------------------------------------ | |
67 | ||
68 | /** | |
69 | * Public constructor. | |
70 | * | |
71 | * @param parent parent widget | |
72 | * @param x column relative to parent | |
73 | * @param y row relative to parent | |
74 | * @param width visible combobox width, including the down-arrow | |
75 | * @param values the possible values for the box, shown in the drop-down | |
76 | * @param valuesIndex the initial index in values, or -1 for no default | |
77 | * value | |
78 | * @param valuesHeight the height of the values drop-down when it is | |
79 | * visible | |
80 | * @param updateAction action to call when a new value is selected from | |
81 | * the list or enter is pressed in the edit field | |
82 | */ | |
83 | public TComboBox(final TWidget parent, final int x, final int y, | |
84 | final int width, final List<String> values, final int valuesIndex, | |
85 | final int valuesHeight, final TAction updateAction) { | |
86 | ||
87 | // Set parent and window | |
88 | super(parent, x, y, width, 1); | |
89 | ||
90 | this.updateAction = updateAction; | |
91 | ||
92 | field = new TField(this, 0, 0, width - 1, false, "", | |
93 | updateAction, null); | |
94 | if (valuesIndex >= 0) { | |
95 | field.setText(values.get(valuesIndex)); | |
96 | } | |
97 | ||
98 | list = new TList(this, values, 0, 1, width, valuesHeight, | |
99 | new TAction() { | |
100 | public void DO() { | |
101 | field.setText(list.getSelected()); | |
102 | list.setEnabled(false); | |
103 | list.setVisible(false); | |
104 | TComboBox.this.setHeight(1); | |
105 | TComboBox.this.activate(field); | |
106 | if (updateAction != null) { | |
107 | updateAction.DO(); | |
108 | } | |
109 | } | |
110 | } | |
111 | ); | |
112 | ||
113 | list.setEnabled(false); | |
114 | list.setVisible(false); | |
115 | setHeight(1); | |
116 | activate(field); | |
117 | } | |
118 | ||
119 | // ------------------------------------------------------------------------ | |
120 | // Event handlers --------------------------------------------------------- | |
121 | // ------------------------------------------------------------------------ | |
122 | ||
123 | /** | |
124 | * Returns true if the mouse is currently on the down arrow. | |
125 | * | |
126 | * @param mouse mouse event | |
127 | * @return true if the mouse is currently on the down arrow | |
128 | */ | |
129 | private boolean mouseOnArrow(final TMouseEvent mouse) { | |
130 | if ((mouse.getY() == 0) | |
131 | && (mouse.getX() == getWidth() - 1) | |
132 | ) { | |
133 | return true; | |
134 | } | |
135 | return false; | |
136 | } | |
137 | ||
138 | /** | |
139 | * Handle mouse down clicks. | |
140 | * | |
141 | * @param mouse mouse button down event | |
142 | */ | |
143 | @Override | |
144 | public void onMouseDown(final TMouseEvent mouse) { | |
145 | if ((mouseOnArrow(mouse)) && (mouse.isMouse1())) { | |
146 | // Make the list visible or not. | |
147 | if (list.isActive()) { | |
148 | list.setEnabled(false); | |
149 | list.setVisible(false); | |
150 | setHeight(1); | |
151 | activate(field); | |
152 | } else { | |
153 | list.setEnabled(true); | |
154 | list.setVisible(true); | |
155 | setHeight(list.getHeight() + 1); | |
156 | activate(list); | |
157 | } | |
158 | } | |
159 | } | |
160 | ||
161 | /** | |
162 | * Handle keystrokes. | |
163 | * | |
164 | * @param keypress keystroke event | |
165 | */ | |
166 | @Override | |
167 | public void onKeypress(final TKeypressEvent keypress) { | |
168 | if (keypress.equals(kbAltDown)) { | |
169 | list.setEnabled(true); | |
170 | list.setVisible(true); | |
171 | setHeight(list.getHeight() + 1); | |
172 | activate(list); | |
173 | return; | |
174 | } | |
175 | ||
176 | if (keypress.equals(kbTab) | |
177 | || (keypress.equals(kbShiftTab)) | |
178 | || (keypress.equals(kbBackTab)) | |
179 | ) { | |
180 | if (list.isActive()) { | |
181 | list.setEnabled(false); | |
182 | list.setVisible(false); | |
183 | setHeight(1); | |
184 | activate(field); | |
185 | return; | |
186 | } | |
187 | } | |
188 | ||
189 | // Pass to parent for the things we don't care about. | |
190 | super.onKeypress(keypress); | |
191 | } | |
192 | ||
193 | // ------------------------------------------------------------------------ | |
194 | // TWidget ---------------------------------------------------------------- | |
195 | // ------------------------------------------------------------------------ | |
196 | ||
197 | /** | |
198 | * Draw the combobox down arrow. | |
199 | */ | |
200 | @Override | |
201 | public void draw() { | |
202 | CellAttributes comboBoxColor; | |
203 | ||
204 | if (isAbsoluteActive()) { | |
205 | comboBoxColor = getTheme().getColor("tcombobox.active"); | |
206 | } else { | |
207 | comboBoxColor = getTheme().getColor("tcombobox.inactive"); | |
208 | } | |
209 | ||
210 | getScreen().putCharXY(getWidth() - 1, 0, GraphicsChars.DOWNARROW, | |
211 | comboBoxColor); | |
212 | } | |
213 | ||
214 | // ------------------------------------------------------------------------ | |
215 | // TComboBox -------------------------------------------------------------- | |
216 | // ------------------------------------------------------------------------ | |
217 | ||
218 | /** | |
219 | * Get combobox text value. | |
220 | * | |
221 | * @return text in the edit field | |
222 | */ | |
223 | public String getText() { | |
224 | return field.getText(); | |
225 | } | |
226 | ||
227 | /** | |
228 | * Set combobox text value. | |
229 | * | |
230 | * @param text the new text in the edit field | |
231 | */ | |
232 | public void setText(final String text) { | |
233 | field.setText(text); | |
234 | for (int i = 0; i < list.getMaxSelectedIndex(); i++) { | |
235 | if (list.getSelected().equals(text)) { | |
236 | list.setSelectedIndex(i); | |
237 | return; | |
238 | } | |
239 | } | |
240 | list.setSelectedIndex(-1); | |
241 | } | |
242 | ||
243 | } |