Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
inputbox.qc
Go to the documentation of this file.
1#include "inputbox.qh"
2
3.float cb_offset;
4.string cb_src;
5
6 void InputBox_configureInputBox(entity me, string theText, float theCursorPos, float theFontSize, string gfx)
7 {
8 SUPER(InputBox).configureLabel(me, theText, theFontSize, 0.0);
9 me.src = gfx;
10 me.cursorPos = theCursorPos;
11 }
12 void InputBox_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
13 {
14 SUPER(InputBox).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
15 if (me.enableClearButton)
16 {
17 me.cb_width = absSize.y / absSize.x;
18 me.cb_offset = bound(-1, me.cb_offset, 0) * me.cb_width; // bound to range -1, 0
19 me.keepspaceRight = me.keepspaceRight - me.cb_offset + me.cb_width;
20 }
21 }
22
23 void InputBox_setText(entity me, string txt)
24 {
25 strfree(me.text);
26 SUPER(InputBox).setText(me, strzone(txt));
27 }
28
30 {
31 if (me.text == "")
32 return 0;
33 if (pos.x >= 1 + me.cb_offset - me.cb_width)
34 if (pos.x < 1 + me.cb_offset)
35 if (pos.y >= 0)
36 if (pos.y < 1) return 1;
37 return 0;
38 }
39
41 {
42 if (me.enableClearButton)
43 {
44 if (over_ClearButton(me, pos))
45 {
46 me.cb_focused = true;
47 return 1;
48 }
49 me.cb_focused = false;
50 }
51 return 1;
52 }
53
55 {
56 float p;
57 if (me.pressed)
58 {
59 me.dragScrollPos = pos;
60 p = me.scrollPos + pos.x - me.keepspaceLeft;
61 me.cursorPos = draw_TextLengthUpToWidth(me.text, p, 0, me.realFontSize);
62 me.lastChangeTime = time;
63 }
64 else if (me.enableClearButton)
65 {
66 if (over_ClearButton(me, pos))
67 {
68 me.cb_pressed = true;
69 return 1;
70 }
71 }
72 me.cb_pressed = false;
73 return 1;
74 }
75
77 {
78 if (this.enableClearButton)
79 if (over_ClearButton(this, pos))
80 {
81 this.cb_pressed = true;
82 return true;
83 }
84 this.dragScrollTimer = time;
85 this.pressed = 1;
86 return InputBox_mouseDrag(this, pos);
87 }
88
90 {
91 if (me.cb_pressed)
92 if (over_ClearButton(me, pos))
93 {
95 me.setText(me, "");
96 if(me.applyButton)
97 me.applyButton.disabled = false;
98 me.cb_pressed = false;
99 return 1;
100 }
101 float r = InputBox_mouseDrag(me, pos);
102 // reset cb_pressed after mouseDrag, mouseDrag could set cb_pressed in this case:
103 // mouse press out of the clear button, drag and then mouse release over the clear button
104 me.cb_pressed = false;
105 me.pressed = 0;
106 return r;
107 }
108
109 void InputBox_enterText(entity me, string ch)
110 {
111 int len = strlen(ch);
112 for (int i = 0; i < len; ++i)
113 {
114 // if there is a list of allowed characters, forbid all other
115 if (me.allowedCharacters != string_null
116 && strstrofs(me.allowedCharacters, substring(ch, i, 1), 0) == -1) return;
117
118 // don't allow forbidden characters
119 if (strstrofs(me.forbiddenCharacters, substring(ch, i, 1), 0) > -1) return;
120 }
121 if (me.maxLength > 0)
122 {
123 if (len + strlen(me.text) > me.maxLength) return;
124 }
125 else if (me.maxLength < 0)
126 {
127 if (u8_strsize(ch) + u8_strsize(me.text) > -me.maxLength) return;
128 }
129 me.setText(me, strcat(substring(me.text, 0, me.cursorPos), ch, substring(me.text, me.cursorPos, strlen(me.text) - me.cursorPos)));
130 me.cursorPos += len;
131 }
132
133 float InputBox_keyDown(entity me, float key, float ascii, float shift)
134 {
135 me.lastChangeTime = time;
136 me.dragScrollTimer = time;
137 if (ascii >= 32 && ascii != 127)
138 {
139 me.enterText(me, chr(ascii));
140 if(me.applyButton)
141 me.applyButton.disabled = false;
142 return 1;
143 }
144 switch (key)
145 {
146 case K_KP_LEFTARROW:
147 case K_LEFTARROW:
148 --me.cursorPos;
149 return 1;
150 case K_KP_RIGHTARROW:
151 case K_RIGHTARROW:
152 ++me.cursorPos;
153 return 1;
154 case K_KP_HOME:
155 case K_HOME:
156 me.cursorPos = 0;
157 return 1;
158 case K_KP_END:
159 case K_END:
160 me.cursorPos = strlen(me.text);
161 return 1;
162 case K_BACKSPACE:
163 if (me.cursorPos > 0)
164 {
165 --me.cursorPos;
166 me.setText(me, strcat(substring(me.text, 0, me.cursorPos), substring(me.text, me.cursorPos + 1, strlen(me.text) - me.cursorPos - 1)));
167 if(me.applyButton)
168 me.applyButton.disabled = false;
169 }
170 return 1;
171 case K_KP_DEL:
172 case K_DEL:
173 if (shift & S_CTRL)
174 {
176 me.setText(me, "");
177 }
178 else
179 me.setText(me, strcat(substring(me.text, 0, me.cursorPos), substring(me.text, me.cursorPos + 1, strlen(me.text) - me.cursorPos - 1)));
180 if(me.applyButton)
181 me.applyButton.disabled = false;
182 return 1;
183 }
184 return 0;
185 }
186
188 {
189 string CURSOR = "_";
190 float cursorPosInWidths, totalSizeInWidths;
191
192 if (me.pressed) me.mouseDrag(me, me.dragScrollPos); // simulate mouseDrag event
193
194 if (me.recalcPos) me.recalcPositionWithText(me, me.text);
195
196 me.focusable = !me.disabled;
197 if (me.disabled) draw_alpha *= me.disabledAlpha;
198
199 if (me.src)
200 {
201 if (me.focused && !me.disabled) draw_ButtonPicture('0 0 0', strcat(me.src, "_f"), '1 1 0', me.colorF, 1);
202 else draw_ButtonPicture('0 0 0', strcat(me.src, "_n"), '1 1 0', me.color, 1);
203 }
204
205 me.cursorPos = bound(0, me.cursorPos, strlen(me.text));
206 cursorPosInWidths = draw_TextWidth(substring(me.text, 0, me.cursorPos), 0, me.realFontSize);
207 totalSizeInWidths = draw_TextWidth(strcat(me.text, CURSOR), 0, me.realFontSize);
208
209 if (me.dragScrollTimer < time)
210 {
211 float save;
212 save = me.scrollPos;
213 me.scrollPos = bound(cursorPosInWidths - (0.875 - me.keepspaceLeft - me.keepspaceRight), me.scrollPos, cursorPosInWidths - 0.125);
214 if (me.scrollPos != save) me.dragScrollTimer = time + 0.2;
215 }
216 me.scrollPos = min(me.scrollPos, totalSizeInWidths - (1 - me.keepspaceRight - me.keepspaceLeft));
217 me.scrollPos = max(0, me.scrollPos);
218
219 draw_SetClipRect(eX * me.keepspaceLeft, eX * (1 - me.keepspaceLeft - me.keepspaceRight) + eY);
220 if (me.editColorCodes)
221 {
222 vector p = me.realOrigin - eX * me.scrollPos;
223 vector theColor = '1 1 1';
224 float theAlpha = 1;
225
226 for (int i = 0, n = strlen(me.text); i < n; ++i)
227 {
228 string ch = substring(me.text, i, 1);
229 if (ch == "^")
230 {
231 float w;
232 string ch2 = substring(me.text, i + 1, 1);
233 w = draw_TextWidth(strcat(ch, ch2), 0, me.realFontSize);
234 float fill_alpha = 0.4;
235 if (ch2 == "^")
236 {
237 if (me.cursorPos > i && me.cursorPos <= i + 2)
238 fill_alpha = 0.6;
239 draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', fill_alpha);
240 draw_Text(p + eX * 0.25 * w, "^", me.realFontSize, theColor, theAlpha, 0);
241 }
242 else if (IS_DIGIT(ch2))
243 {
244 theAlpha = 1;
245 switch (stof(ch2))
246 {
247 case 0: theColor = '0 0 0'; break;
248 case 1: theColor = '1 0 0'; break;
249 case 2: theColor = '0 1 0'; break;
250 case 3: theColor = '1 1 0'; break;
251 case 4: theColor = '0 0 1'; break;
252 case 5: theColor = '0 1 1'; break;
253 case 6: theColor = '1 0 1'; break;
254 case 7: theColor = '1 1 1'; break;
255 case 8: theColor = '1 1 1'; theAlpha = 0.5; break;
256 case 9: theColor = '0.5 0.5 0.5'; break;
257 }
258 if (me.cursorPos > i && me.cursorPos <= i + 2)
259 fill_alpha = 0.6;
260 draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', fill_alpha);
261 draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0);
262 }
263 else if (ch2 == "x") // ^x found
264 {
265 vector theTempColor;
266 theColor = '1 1 1';
267 float component = HEXDIGIT_TO_DEC(substring(me.text, i + 2, 1));
268 if (component >= 0) // ^xr found
269 {
270 theTempColor.x = component / 15;
271
272 component = HEXDIGIT_TO_DEC(substring(me.text, i + 3, 1));
273 if (component >= 0) // ^xrg found
274 {
275 theTempColor.y = component / 15;
276
277 component = HEXDIGIT_TO_DEC(substring(me.text, i + 4, 1));
278 if (component >= 0) // ^xrgb found
279 {
280 theTempColor.z = component / 15;
281 theColor = theTempColor;
282 w = draw_TextWidth(substring(me.text, i, 5), 0, me.realFontSize);
283
284 if (me.cursorPos > i && me.cursorPos <= i + 5)
285 fill_alpha = 0.8;
286 draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', fill_alpha);
287 draw_Text(p, substring(me.text, i, 5), me.realFontSize, theColor, 1, 0);
288 i += 3;
289 }
290 else
291 {
292 // blue missing
293 w = draw_TextWidth(substring(me.text, i, 4), 0, me.realFontSize);
294 draw_Fill(p, eX * w + eY * me.realFontSize.y, eZ, fill_alpha);
295 draw_Text(p, substring(me.text, i, 4), me.realFontSize, '1 1 1', theAlpha, 0);
296 i += 2;
297 }
298 }
299 else
300 {
301 // green missing
302 w = draw_TextWidth(substring(me.text, i, 3), 0, me.realFontSize);
303 draw_Fill(p, eX * w + eY * me.realFontSize.y, eY, fill_alpha);
304 draw_Text(p, substring(me.text, i, 3), me.realFontSize, '1 1 1', theAlpha, 0);
305 ++i;
306 }
307 }
308 else
309 {
310 // red missing
311 // w = draw_TextWidth(substring(me.text, i, 2), 0) * me.realFontSize_x;
312 draw_Fill(p, eX * w + eY * me.realFontSize.y, eX, fill_alpha);
313 draw_Text(p, substring(me.text, i, 2), me.realFontSize, '1 1 1', theAlpha, 0);
314 }
315 }
316 else
317 {
318 draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', fill_alpha);
319 draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0);
320 }
321 p += w * eX;
322 ++i;
323 continue;
324 }
325 draw_Text(p, ch, me.realFontSize, theColor, theAlpha, 0);
326 p += eX * draw_TextWidth(ch, 0, me.realFontSize);
327 }
328 }
329 else
330 {
331 draw_Text(me.realOrigin - eX * me.scrollPos, me.text, me.realFontSize, '1 1 1', 1, 0);
332 }
333
334 if (!me.focused || (time - me.lastChangeTime) < floor(time - me.lastChangeTime) + 0.5)
335 draw_Text(me.realOrigin + eX * (cursorPosInWidths - me.scrollPos), CURSOR, me.realFontSize, '1 1 1', 1, 0);
336
338
339 if (me.enableClearButton && me.text != "")
340 {
341 if (me.focused && me.cb_pressed)
342 draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_c"), eX * me.cb_width + eY, me.cb_colorC, 1);
343 else if (me.focused && me.cb_focused)
344 draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_f"), eX * me.cb_width + eY, me.cb_colorF, 1);
345 else
346 draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_n"), eX * me.cb_width + eY, me.cb_color, 1);
347 }
348
349 // skipping SUPER(InputBox).draw(me);
350 MenuItem_draw(me);
351 }
352
354 {
355 me.focusable = !me.disabled;
356 }
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
bool enableClearButton
Definition inputbox.qh:37
float dragScrollTimer
Definition inputbox.qh:26
bool pressed
Definition inputbox.qh:28
bool cb_pressed
Definition inputbox.qh:40
virtual void mousePress()
Definition inputbox.qc:76
float time
#define strstrofs
#define strlen
const int S_CTRL
Definition hud.qh:130
void InputBox_configureInputBox(entity me, string theText, float theCursorPos, float theFontSize, string gfx)
Definition inputbox.qc:6
float InputBox_mouseDrag(entity me, vector pos)
Definition inputbox.qc:54
void InputBox_setText(entity me, string txt)
Definition inputbox.qc:23
void InputBox_enterText(entity me, string ch)
Definition inputbox.qc:109
float over_ClearButton(entity me, vector pos)
Definition inputbox.qc:29
void InputBox_showNotify(entity me)
Definition inputbox.qc:353
float cb_offset
Definition inputbox.qc:3
string cb_src
Definition inputbox.qc:4
void InputBox_draw(entity me)
Definition inputbox.qc:187
void InputBox_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
Definition inputbox.qc:12
float InputBox_mouseMove(entity me, vector pos)
Definition inputbox.qc:40
float InputBox_keyDown(entity me, float key, float ascii, float shift)
Definition inputbox.qc:133
float InputBox_mouseRelease(entity me, vector pos)
Definition inputbox.qc:89
float K_KP_RIGHTARROW
Definition keycodes.qc:60
float K_BACKSPACE
Definition keycodes.qc:14
float K_RIGHTARROW
Definition keycodes.qc:18
float K_DEL
Definition keycodes.qc:38
float K_KP_LEFTARROW
Definition keycodes.qc:57
float K_KP_DEL
Definition keycodes.qc:68
float K_KP_HOME
Definition keycodes.qc:62
float K_LEFTARROW
Definition keycodes.qc:17
float K_HOME
Definition keycodes.qc:41
float K_END
Definition keycodes.qc:42
float K_KP_END
Definition keycodes.qc:51
void draw_Picture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha)
Definition draw.qc:72
void draw_Text(vector theOrigin, string theText, vector theSize, vector theColor, float theAlpha, float ICanHasKallerz)
Definition draw.qc:282
float draw_TextWidth(string theText, float ICanHasKallerz, vector SizeThxBye)
Definition draw.qc:304
void draw_ButtonPicture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha)
Definition draw.qc:108
float draw_TextLengthUpToWidth(string theText, float maxWidth, float allowColorCodes, vector theFontSize)
Definition draw.qc:401
void draw_Fill(vector theOrigin, vector theSize, vector theColor, float theAlpha)
Definition draw.qc:97
void draw_ClearClip()
Definition draw.qc:362
void draw_SetClipRect(vector theOrigin, vector theScale)
Definition draw.qc:354
float draw_alpha
Definition draw.qh:9
void m_play_click_sound(string soundfile)
Definition menu.qc:1106
const string MENU_SOUND_CLEAR
Definition menu.qh:49
string chr(float ascii)
float stof(string val,...)
float bound(float min, float value, float max)
string substring(string s, float start, float length)
float min(float f,...)
float floor(float f)
string strzone(string s)
float max(float f,...)
string string_null
Definition nil.qh:9
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
#define SUPER(cname)
Definition oo.qh:231
#define METHOD(cname, name, prototype)
Definition oo.qh:269
vector
Definition self.qh:92
#define IS_DIGIT(d)
Definition string.qh:576
#define HEXDIGIT_TO_DEC(d)
Definition string.qh:571
#define strfree(this)
Definition string.qh:59
ERASEABLE int u8_strsize(string s)
Definition string.qh:373
const vector eY
Definition vector.qh:45
const vector eZ
Definition vector.qh:46
const vector eX
Definition vector.qh:44