]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/menu/item/inputbox.qc
Merge branch 'master' into terencehill/accuracy_shotgun
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / item / inputbox.qc
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                 if (me.text) strunzone(me.text);
26                 SUPER(InputBox).setText(me, strzone(txt));
27         }
28
29         float over_ClearButton(entity me, vector pos)
30         {
31                 if (pos.x >= 1 + me.cb_offset - me.cb_width)
32                         if (pos.x < 1 + me.cb_offset)
33                                 if (pos.y >= 0)
34                                         if (pos.y < 1) return 1;
35                 return 0;
36         }
37
38         float InputBox_mouseMove(entity me, vector pos)
39         {
40                 if (me.enableClearButton)
41                 {
42                         if (over_ClearButton(me, pos))
43                         {
44                                 me.cb_focused = 1;
45                                 return 1;
46                         }
47                         me.cb_focused = 0;
48                 }
49                 return 1;
50         }
51
52         float InputBox_mouseDrag(entity me, vector pos)
53         {
54                 float p;
55                 if (me.pressed)
56                 {
57                         me.dragScrollPos = pos;
58                         p = me.scrollPos + pos.x - me.keepspaceLeft;
59                         me.cursorPos = draw_TextLengthUpToWidth(me.text, p, 0, me.realFontSize);
60                         me.lastChangeTime = time;
61                 }
62                 else if (me.enableClearButton)
63                 {
64                         if (over_ClearButton(me, pos))
65                         {
66                                 me.cb_pressed = 1;
67                                 return 1;
68                         }
69                 }
70                 me.cb_pressed = 0;
71                 return 1;
72         }
73
74         METHOD(InputBox, mousePress, bool(InputBox this, vector pos))
75         {
76                 if (this.enableClearButton)
77                         if (over_ClearButton(this, pos))
78                         {
79                                 this.cb_pressed = 1;
80                                 return true;
81                         }
82                 this.dragScrollTimer = time;
83                 this.pressed = 1;
84                 return InputBox_mouseDrag(this, pos);
85         }
86
87         float InputBox_mouseRelease(entity me, vector pos)
88         {
89                 if (me.cb_pressed)
90                         if (over_ClearButton(me, pos))
91                         {
92                                 m_play_click_sound(MENU_SOUND_CLEAR);
93                                 me.setText(me, "");
94                                 if(me.applyButton)
95                                         me.applyButton.disabled = false;
96                                 me.cb_pressed = 0;
97                                 return 1;
98                         }
99                 float r = InputBox_mouseDrag(me, pos);
100                 // reset cb_pressed after mouseDrag, mouseDrag could set cb_pressed in this case:
101                 // mouse press out of the clear button, drag and then mouse release over the clear button
102                 me.cb_pressed = 0;
103                 me.pressed = 0;
104                 return r;
105         }
106
107         void InputBox_enterText(entity me, string ch)
108         {
109                 float i;
110                 for (i = 0; i < strlen(ch); ++i)
111                         if (strstrofs(me.forbiddenCharacters, substring(ch, i, 1), 0) > -1) return;
112                 if (me.maxLength > 0)
113                 {
114                         if (strlen(ch) + strlen(me.text) > me.maxLength) return;
115                 }
116                 else if (me.maxLength < 0)
117                 {
118                         if (u8_strsize(ch) + u8_strsize(me.text) > -me.maxLength) return;
119                 }
120                 me.setText(me, strcat(substring(me.text, 0, me.cursorPos), ch, substring(me.text, me.cursorPos, strlen(me.text) - me.cursorPos)));
121                 me.cursorPos += strlen(ch);
122         }
123
124         float InputBox_keyDown(entity me, float key, float ascii, float shift)
125         {
126                 me.lastChangeTime = time;
127                 me.dragScrollTimer = time;
128                 if (ascii >= 32 && ascii != 127)
129                 {
130                         me.enterText(me, chr(ascii));
131                         if(me.applyButton)
132                                 me.applyButton.disabled = false;
133                         return 1;
134                 }
135                 switch (key)
136                 {
137                         case K_KP_LEFTARROW:
138                         case K_LEFTARROW:
139                                 me.cursorPos -= 1;
140                                 return 1;
141                         case K_KP_RIGHTARROW:
142                         case K_RIGHTARROW:
143                                 me.cursorPos += 1;
144                                 return 1;
145                         case K_KP_HOME:
146                         case K_HOME:
147                                 me.cursorPos = 0;
148                                 return 1;
149                         case K_KP_END:
150                         case K_END:
151                                 me.cursorPos = strlen(me.text);
152                                 return 1;
153                         case K_BACKSPACE:
154                                 if (me.cursorPos > 0)
155                                 {
156                                         me.cursorPos -= 1;
157                                         me.setText(me, strcat(substring(me.text, 0, me.cursorPos), substring(me.text, me.cursorPos + 1, strlen(me.text) - me.cursorPos - 1)));
158                                         if(me.applyButton)
159                                                 me.applyButton.disabled = false;
160                                 }
161                                 return 1;
162                         case K_KP_DEL:
163                         case K_DEL:
164                                 if (shift & S_CTRL)
165                                 {
166                                         m_play_click_sound(MENU_SOUND_CLEAR);
167                                         me.setText(me, "");
168                                 }
169                                 else
170                                         me.setText(me, strcat(substring(me.text, 0, me.cursorPos), substring(me.text, me.cursorPos + 1, strlen(me.text) - me.cursorPos - 1)));
171                                 if(me.applyButton)
172                                         me.applyButton.disabled = false;
173                                 return 1;
174                 }
175                 return 0;
176         }
177
178         void InputBox_draw(entity me)
179         {
180                 string CURSOR = "_";
181                 float cursorPosInWidths, totalSizeInWidths;
182
183                 if (me.pressed) me.mouseDrag(me, me.dragScrollPos);  // simulate mouseDrag event
184
185                 if (me.recalcPos) me.recalcPositionWithText(me, me.text);
186
187                 me.focusable = !me.disabled;
188                 if (me.disabled) draw_alpha *= me.disabledAlpha;
189
190                 if (me.src)
191                 {
192                         if (me.focused && !me.disabled) draw_ButtonPicture('0 0 0', strcat(me.src, "_f"), '1 1 0', me.colorF, 1);
193                         else draw_ButtonPicture('0 0 0', strcat(me.src, "_n"), '1 1 0', me.color, 1);
194                 }
195
196                 me.cursorPos = bound(0, me.cursorPos, strlen(me.text));
197                 cursorPosInWidths = draw_TextWidth(substring(me.text, 0, me.cursorPos), 0, me.realFontSize);
198                 totalSizeInWidths = draw_TextWidth(strcat(me.text, CURSOR), 0, me.realFontSize);
199
200                 if (me.dragScrollTimer < time)
201                 {
202                         float save;
203                         save = me.scrollPos;
204                         me.scrollPos = bound(cursorPosInWidths - (0.875 - me.keepspaceLeft - me.keepspaceRight), me.scrollPos, cursorPosInWidths - 0.125);
205                         if (me.scrollPos != save) me.dragScrollTimer = time + 0.2;
206                 }
207                 me.scrollPos = min(me.scrollPos, totalSizeInWidths - (1 - me.keepspaceRight - me.keepspaceLeft));
208                 me.scrollPos = max(0, me.scrollPos);
209
210                 draw_SetClipRect(eX * me.keepspaceLeft, eX * (1 - me.keepspaceLeft - me.keepspaceRight) + eY);
211                 if (me.editColorCodes)
212                 {
213                         string ch, ch2;
214                         float i, n;
215                         vector theColor;
216                         float theAlpha;  // float theVariableAlpha;
217                         vector p;
218                         vector theTempColor;
219                         float component;
220
221                         p = me.realOrigin - eX * me.scrollPos;
222                         theColor = '1 1 1';
223                         theAlpha = 1;  // theVariableAlpha = 1; // changes when ^ax found
224
225                         n = strlen(me.text);
226                         for (i = 0; i < n; ++i)
227                         {
228                                 ch = substring(me.text, i, 1);
229                                 if (ch == "^")
230                                 {
231                                         float w;
232                                         ch2 = substring(me.text, i + 1, 1);
233                                         w = draw_TextWidth(strcat(ch, ch2), 0, me.realFontSize);
234                                         if (ch2 == "^")
235                                         {
236                                                 draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5);
237                                                 draw_Text(p + eX * 0.25 * w, "^", me.realFontSize, theColor, theAlpha, 0);
238                                         }
239                                         else if (ch2 == "0" || stof(ch2))  // digit?
240                                         {
241                                                 switch (stof(ch2))
242                                                 {
243                                                         case 0: theColor = '0 0 0';
244                                                                 theAlpha = 1;
245                                                                 break;
246                                                         case 1: theColor = '1 0 0';
247                                                                 theAlpha = 1;
248                                                                 break;
249                                                         case 2: theColor = '0 1 0';
250                                                                 theAlpha = 1;
251                                                                 break;
252                                                         case 3: theColor = '1 1 0';
253                                                                 theAlpha = 1;
254                                                                 break;
255                                                         case 4: theColor = '0 0 1';
256                                                                 theAlpha = 1;
257                                                                 break;
258                                                         case 5: theColor = '0 1 1';
259                                                                 theAlpha = 1;
260                                                                 break;
261                                                         case 6: theColor = '1 0 1';
262                                                                 theAlpha = 1;
263                                                                 break;
264                                                         case 7: theColor = '1 1 1';
265                                                                 theAlpha = 1;
266                                                                 break;
267                                                         case 8: theColor = '1 1 1';
268                                                                 theAlpha = 0.5;
269                                                                 break;
270                                                         case 9: theColor = '0.5 0.5 0.5';
271                                                                 theAlpha = 1;
272                                                                 break;
273                                                 }
274                                                 draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5);
275                                                 draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0);
276                                         }
277                                         else if (ch2 == "x")  // ^x found
278                                         {
279                                                 theColor = '1 1 1';
280
281                                                 component = HEXDIGIT_TO_DEC(substring(me.text, i + 2, 1));
282                                                 if (component >= 0)  // ^xr found
283                                                 {
284                                                         theTempColor.x = component / 15;
285
286                                                         component = HEXDIGIT_TO_DEC(substring(me.text, i + 3, 1));
287                                                         if (component >= 0)  // ^xrg found
288                                                         {
289                                                                 theTempColor.y = component / 15;
290
291                                                                 component = HEXDIGIT_TO_DEC(substring(me.text, i + 4, 1));
292                                                                 if (component >= 0)  // ^xrgb found
293                                                                 {
294                                                                         theTempColor.z = component / 15;
295                                                                         theColor = theTempColor;
296                                                                         w = draw_TextWidth(substring(me.text, i, 5), 0, me.realFontSize);
297
298                                                                         draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5);
299                                                                         draw_Text(p, substring(me.text, i, 5), me.realFontSize, theColor, 1, 0);  // theVariableAlpha instead of 1 using alpha tags ^ax
300                                                                         i += 3;
301                                                                 }
302                                                                 else
303                                                                 {
304                                                                         // blue missing
305                                                                         w = draw_TextWidth(substring(me.text, i, 4), 0, me.realFontSize);
306                                                                         draw_Fill(p, eX * w + eY * me.realFontSize.y, eZ, 0.5);
307                                                                         draw_Text(p, substring(me.text, i, 4), me.realFontSize, '1 1 1', theAlpha, 0);
308                                                                         i += 2;
309                                                                 }
310                                                         }
311                                                         else
312                                                         {
313                                                                 // green missing
314                                                                 w = draw_TextWidth(substring(me.text, i, 3), 0, me.realFontSize);
315                                                                 draw_Fill(p, eX * w + eY * me.realFontSize.y, eY, 0.5);
316                                                                 draw_Text(p, substring(me.text, i, 3), me.realFontSize, '1 1 1', theAlpha, 0);
317                                                                 i += 1;
318                                                         }
319                                                 }
320                                                 else
321                                                 {
322                                                         // red missing
323                                                         // w = draw_TextWidth(substring(me.text, i, 2), 0) * me.realFontSize_x;
324                                                         draw_Fill(p, eX * w + eY * me.realFontSize.y, eX, 0.5);
325                                                         draw_Text(p, substring(me.text, i, 2), me.realFontSize, '1 1 1', theAlpha, 0);
326                                                 }
327                                         }
328                                         else
329                                         {
330                                                 draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5);
331                                                 draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0);
332                                         }
333                                         p += w * eX;
334                                         ++i;
335                                         continue;
336                                 }
337                                 draw_Text(p, ch, me.realFontSize, theColor, theAlpha, 0);  // TODO theVariableAlpha
338                                 p += eX * draw_TextWidth(ch, 0, me.realFontSize);
339                         }
340                 }
341                 else
342                 {
343                         draw_Text(me.realOrigin - eX * me.scrollPos, me.text, me.realFontSize, '1 1 1', 1, 0);
344                 }
345
346                 if (!me.focused || (time - me.lastChangeTime) < floor(time - me.lastChangeTime) + 0.5) draw_Text(me.realOrigin + eX * (cursorPosInWidths - me.scrollPos), CURSOR, me.realFontSize, '1 1 1', 1, 0);
347
348                 draw_ClearClip();
349
350                 if (me.enableClearButton)
351                         if (me.text != "")
352                         {
353                                 if (me.focused && me.cb_pressed) draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_c"), eX * me.cb_width + eY, me.cb_colorC, 1);
354                                 else if (me.focused && me.cb_focused) draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_f"), eX * me.cb_width + eY, me.cb_colorF, 1);
355                                 else draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_n"), eX * me.cb_width + eY, me.cb_color, 1);
356                         }
357
358                 // skipping SUPER(InputBox).draw(me);
359                 Item_draw(me);
360         }
361
362         void InputBox_showNotify(entity me)
363         {
364                 me.focusable = !me.disabled;
365         }