Many changes:
[fanfix.git] / src / jexer / TComboBox.java
CommitLineData
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 */
29package jexer;
30
31import java.util.List;
32
33import jexer.bits.CellAttributes;
34import jexer.bits.GraphicsChars;
35import jexer.event.TKeypressEvent;
36import jexer.event.TMouseEvent;
37import 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 */
43public 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}