forked from FionaWright/High5ive
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathW_Dropdown.pde
339 lines (299 loc) · 8.76 KB
/
W_Dropdown.pde
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
/**
* A. Robertson
*
* Dropdown widget which can be used to display and select from a list of options.
*
* @extends Widget
* @implements IClickable
* @implements IWheelInpput
*/
class DropdownUI<T> extends Widget implements IClickable, IWheelInput {
private EventType<EventInfoType> m_onClickEvent;
private EventType<MouseWheelEventInfoType> m_onMouseWheelMoved;
private EventType<ListboxSelectedEntryChangedEventInfoType> m_onSelectionChanged;
private Function<T, String> m_getDisplayString;
private ListboxUI<T> m_listbox;
private TextboxUI m_textbox;
private ButtonUI m_dropdownButton;
private boolean m_isOpen = false;
/**
* A. Robertson
*
* Creates a dropdown widget.
*
* @param posX The x position of the widget.
* @param posY The y position of the widget.
* @param width The width of the widget.
* @param height The height of the widget.
* @param entryHeight The height of each individual entry in the drop down menu.
* @param getDisplayString A lambda to convert each individual menu item into a string to be displayed.
*/
public DropdownUI(int posX, int posY, int scaleX, int scaleY, int entryHeight, Function<T, String> getDisplayString) {
super(posX, posY, scaleX, scaleY);
m_getDisplayString = getDisplayString;
m_onClickEvent = new EventType<EventInfoType>();
m_onMouseWheelMoved = new EventType<MouseWheelEventInfoType>();
m_onSelectionChanged = new EventType<ListboxSelectedEntryChangedEventInfoType>();
m_onMouseWheelMoved.addHandler(e -> onMouseWheelMoved(e));
int tbHeight = max((int)(m_scale.y * 0.1), 40);
m_textbox = new TextboxUI(posX, posY, (int)(m_scale.x - tbHeight), tbHeight);
m_dropdownButton = new ButtonUI((int)(posX + m_textbox.getScale().x), posY, (int)m_textbox.getScale().y, (int)m_textbox.getScale().y);
m_dropdownButton.getLabel().setCentreAligned(true);
m_dropdownButton.setTextSize(20);
m_listbox = new ListboxUI<T>((int)m_pos.x, (int)m_pos.y + (int)m_textbox.getScale().y, (int)m_scale.x, (int)(m_scale.y - m_textbox.getScale().y), entryHeight, getDisplayString);
m_listbox.setOnlyUseNeededHeight(true);
m_textbox.setUserModifiable(false);
m_dropdownButton.getOnClickEvent().addHandler(e -> onDropdownButtonClicked(e));
m_listbox.getOnClickEvent().addHandler(e -> onListboxClick(e));
m_listbox.getOnSelectedEntryChangedEvent().addHandler(e -> onListboxSelectionChanged(e));
m_onFocusLostEvent.addHandler(e -> onFocusLost(e));
m_textbox.getOnKeyPressedEvent().addHandler(e -> textboxChanged(e));
m_textbox.getOnStringEnteredEvent().addHandler(e -> textboxTextEntered(e));
m_textbox.getOnClickEvent().addHandler(e -> openList());
m_children.add(m_listbox);
m_children.add(m_textbox);
m_children.add(m_dropdownButton);
closeList();
}
/**
* A. Robertson
*
* Draws the dropdown widget.
*/
@ Override
public void draw() {
super.draw();
m_textbox.draw();
m_dropdownButton.draw();
m_listbox.setActive(m_isOpen);
if (m_isOpen)
m_listbox.draw();
}
/**
* A. Robertson
*
* Adds a menu item to the dropdown.
*
* @param data The menu item to be added.
*/
public void add(T data) {
m_listbox.add(data);
}
/**
* A. Robertson
*
* Removes an item from the dropdown menu.
* @param data The item to be removed.
*/
public void remove(T data) {
m_listbox.remove(data);
}
/**
* A. Robertson
*
* Gets the selected entry in the menu box.
*
* @returns The selected item in the menu.
*/
public T getSelected() {
return m_listbox.getSelectedEntry();
}
/**
* A. Robertson
*
* Gets the index of the selected entry in the menu box.
*
* @returns The index of the selected item. -1 if no item is selected.
*/
public int getSelectedIndex() {
return m_listbox.getSelectedIndex();
}
/**
* A. Robertson
*
* An override of the Widget.isPositionInside method to ensure that it adapts to the box
* being hidden or shown.
*
* @param mx The x component of the position to be checked.
* @param my The y component of the position to be checked.
* @returns Whether the given position is inside the widget.
*/
@ Override
public boolean isPositionInside(int mx, int my) {
if (m_listbox.getActive()) {
return mx >= m_pos.x && mx <= (m_pos.x + m_scale.x) &&
my >= m_pos.y && my <= (m_pos.y + m_textbox.getScale().y + m_listbox.shownHeight());
}
return mx >= m_pos.x && mx <= (m_pos.x + m_scale.x) &&
my >= m_pos.y && my <= (m_pos.y + m_textbox.getScale().y);
}
/**
* A. Robertson
*
* Gets the class's onClickEvent so that handlers can be added and it can be raised.
*
* @returns The onClickEvent of the class.
*/
public EventType<EventInfoType> getOnClickEvent() {
return m_onClickEvent;
}
/**
* A. Robertson
*
* Gets the class's onMouseWheelEvent so that handlers can be added and it can be raised.
*
* @returns The onMouseWheelEvent of the class.
*/
public EventType<MouseWheelEventInfoType> getOnMouseWheelEvent() {
return m_onMouseWheelMoved;
}
/**
* A. Robertson
*
* Gets the onSelectionChangedEvent, which is raised when the selected item is changed.
*
* @returns The onSelectionChangedEvent.
*/
public EventType<ListboxSelectedEntryChangedEventInfoType> getOnSelectionChanged() {
return m_onSelectionChanged;
}
/**
* A. Robertson
*
* Sets if the textbox of the dropdown menu is searchable.
*
* @param searchable Whether the dropdown is searchable.
*/
public void setSearchable(boolean searchable) {
if (!searchable)
m_listbox.removeFilter();
m_textbox.setUserModifiable(searchable);
}
/**
* A. Robertson
*
* An event handler for the dropdown button clicked event.
*
* @param e The event info from the button click event.
*/
private void onDropdownButtonClicked(EventInfoType e) {
if (m_listbox.getActive()) {
closeList();
return;
}
openList();
}
/**
* A. Robertson
*
* An event handler for the listbox selection changed.
*
* @param e The event info from the selection changed event.
*/
private void onListboxSelectionChanged(ListboxSelectedEntryChangedEventInfoType<T> e) {
m_textbox.setText(m_getDisplayString.apply(e.Data));
closeList();
m_onSelectionChanged.raise(e);
}
/**
* A. Robertson
*
* An event handler for when the menu is clicked.
*
* @param e The event info from the click event.
*/
private void onListboxClick(EventInfoType e) {
closeList();
}
/**
* A. Robertson
*
* An event handler for when the mouse wheel is moved.
*
* @param e The event info from the mouse wheel moved event.
*/
private void onMouseWheelMoved(MouseWheelEventInfoType e) {
if (m_listbox.isFocused() || m_listbox.isPositionInside(e.X, e.Y)) {
e.Widget = m_listbox;
m_listbox.getOnMouseWheelEvent().raise(e);
}
}
/**
* A. Robertson
*
* An event handler for the textbox text changing.
*
* @param e The event info from the textbox text changing.
*/
private void textboxChanged(KeyPressedEventInfoType e) {
TextboxUI tb = ((TextboxUI)e.Widget);
if (tb.getText() == "") {
m_listbox.removeFilter();
return;
}
m_listbox.filterEntries(o -> m_getDisplayString.apply(o).startsWith(tb.getText()));
}
/**
* A. Robertson
*
* An event handler for when the text box text is entered.
*
* @param e The event info from the string being entered.
*/
private void textboxTextEntered(StringEnteredEventInfoType e) {
m_listbox.selectFirstShown();
}
/**
* A. Robertson
*
* An event handler for when the focus is lost. Closes the list of items.
*
* @param e The event info from the on focus lost event.
*/
private void onFocusLost(EventInfoType e) {
closeList();
}
/**
* A. Robertson
*
* Opens the list of items for the dropdown.
*/
private void openList() {
m_isOpen = true;
m_dropdownButton.setText("- ");
}
/**
* A. Robertson
*
* Closes the list of items for the dropdown.
*/
private void closeList() {
m_isOpen = false;
m_dropdownButton.setText("+ ");
}
/**
* F. Wright
*
* Override to add parent to all subwidgets of the dropdown
*
* @param parent The widget to be the parent
*/
@Override
public void setParent(Widget parent) {
super.setParent(parent);
m_textbox.setParent(parent);
m_dropdownButton.setParent(parent);
m_listbox.setParent(parent);
}
/**
* F. Wright
*
* Sets the text in the textbox
*
* @param text The text as a string
*/
public void setTextboxText(String text) {
m_textbox.setText(text);
}
}
// A. Robertson, Dropdown widget created, 20:30 13/03/2024