1 #ifndef ITEM_INPUTBOX_H
2 #define ITEM_INPUTBOX_H
5 METHOD(InputBox, configureInputBox, void(entity, string, float, float, string))
6 METHOD(InputBox, draw, void(entity))
7 METHOD(InputBox, setText, void(entity, string))
8 METHOD(InputBox, enterText, void(entity, string))
9 METHOD(InputBox, keyDown, float(entity, float, float, float))
10 METHOD(InputBox, mouseMove, float(entity, vector))
11 METHOD(InputBox, mouseRelease, float(entity, vector))
12 METHOD(InputBox, mousePress, float(entity, vector))
13 METHOD(InputBox, mouseDrag, float(entity, vector))
14 METHOD(InputBox, showNotify, void(entity))
15 METHOD(InputBox, resizeNotify, void(entity, vector, vector, vector, vector))
17 ATTRIB(InputBox, src, string, string_null)
19 ATTRIB(InputBox, cursorPos, float, 0) // characters
20 ATTRIB(InputBox, scrollPos, float, 0) // widths
22 ATTRIB(InputBox, focusable, float, 1)
23 ATTRIB(InputBox, allowFocusSound, float, 1)
24 ATTRIB(InputBox, disabled, float, 0)
25 ATTRIB(InputBox, lastChangeTime, float, 0)
26 ATTRIB(InputBox, dragScrollTimer, float, 0)
27 ATTRIB(InputBox, dragScrollPos, vector, '0 0 0')
28 ATTRIB(InputBox, pressed, float, 0)
29 ATTRIB(InputBox, editColorCodes, float, 1)
30 ATTRIB(InputBox, forbiddenCharacters, string, "")
31 ATTRIB(InputBox, color, vector, '1 1 1')
32 ATTRIB(InputBox, colorF, vector, '1 1 1')
33 ATTRIB(InputBox, maxLength, float, 255) // if negative, it counts bytes, not chars
35 ATTRIB(InputBox, enableClearButton, float, 1)
36 ATTRIB(InputBox, clearButton, entity, NULL)
37 ATTRIB(InputBox, cb_width, float, 0)
38 ATTRIB(InputBox, cb_pressed, float, 0)
39 ATTRIB(InputBox, cb_focused, float, 0)
40 ATTRIB(InputBox, cb_color, vector, '1 1 1')
41 ATTRIB(InputBox, cb_colorF, vector, '1 1 1')
42 ATTRIB(InputBox, cb_colorC, vector, '1 1 1')
47 void InputBox_configureInputBox(entity me, string theText, float theCursorPos, float theFontSize, string gfx)
49 SUPER(InputBox).configureLabel(me, theText, theFontSize, 0.0);
51 me.cursorPos = theCursorPos;
53 void InputBox_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
55 SUPER(InputBox).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
56 if (me.enableClearButton)
58 me.cb_width = absSize.y / absSize.x;
59 me.cb_offset = bound(-1, me.cb_offset, 0) * me.cb_width; // bound to range -1, 0
60 me.keepspaceRight = me.keepspaceRight - me.cb_offset + me.cb_width;
64 void InputBox_setText(entity me, string txt)
68 SUPER(InputBox).setText(me, strzone(txt));
71 float over_ClearButton(entity me, vector pos)
73 if (pos.x >= 1 + me.cb_offset - me.cb_width)
74 if (pos.x < 1 + me.cb_offset)
81 float InputBox_mouseMove(entity me, vector pos)
83 if (me.enableClearButton)
85 if (over_ClearButton(me, pos))
95 float InputBox_mouseDrag(entity me, vector pos)
100 me.dragScrollPos = pos;
101 p = me.scrollPos + pos.x - me.keepspaceLeft;
102 me.cursorPos = draw_TextLengthUpToWidth(me.text, p, 0, me.realFontSize);
103 me.lastChangeTime = time;
105 else if (me.enableClearButton)
107 if (over_ClearButton(me, pos))
117 float InputBox_mousePress(entity me, vector pos)
119 if (me.enableClearButton)
120 if (over_ClearButton(me, pos))
125 me.dragScrollTimer = time;
127 return InputBox_mouseDrag(me, pos);
130 float InputBox_mouseRelease(entity me, vector pos)
133 if (over_ClearButton(me, pos))
135 m_play_click_sound(MENU_SOUND_CLEAR);
140 float r = InputBox_mouseDrag(me, pos);
141 //reset cb_pressed after mouseDrag, mouseDrag could set cb_pressed in this case:
142 //mouse press out of the clear button, drag and then mouse release over the clear button
148 void InputBox_enterText(entity me, string ch)
151 for(i = 0; i < strlen(ch); ++i)
152 if(strstrofs(me.forbiddenCharacters, substring(ch, i, 1), 0) > -1)
156 if(strlen(ch) + strlen(me.text) > me.maxLength)
159 else if(me.maxLength < 0)
161 if(u8_strsize(ch) + u8_strsize(me.text) > -me.maxLength)
164 me.setText(me, strcat(substring(me.text, 0, me.cursorPos), ch, substring(me.text, me.cursorPos, strlen(me.text) - me.cursorPos)));
165 me.cursorPos += strlen(ch);
168 float InputBox_keyDown(entity me, float key, float ascii, float shift)
170 me.lastChangeTime = time;
171 me.dragScrollTimer = time;
172 if(ascii >= 32 && ascii != 127)
174 me.enterText(me, chr(ascii));
183 case K_KP_RIGHTARROW:
193 me.cursorPos = strlen(me.text);
199 me.setText(me, strcat(substring(me.text, 0, me.cursorPos), substring(me.text, me.cursorPos + 1, strlen(me.text) - me.cursorPos - 1)));
206 m_play_click_sound(MENU_SOUND_CLEAR);
210 me.setText(me, strcat(substring(me.text, 0, me.cursorPos), substring(me.text, me.cursorPos + 1, strlen(me.text) - me.cursorPos - 1)));
216 void InputBox_draw(entity me)
219 float cursorPosInWidths, totalSizeInWidths;
222 me.mouseDrag(me, me.dragScrollPos); // simulate mouseDrag event
225 me.recalcPositionWithText(me, me.text);
227 me.focusable = !me.disabled;
229 draw_alpha *= me.disabledAlpha;
233 if(me.focused && !me.disabled)
234 draw_ButtonPicture('0 0 0', strcat(me.src, "_f"), '1 1 0', me.colorF, 1);
236 draw_ButtonPicture('0 0 0', strcat(me.src, "_n"), '1 1 0', me.color, 1);
239 me.cursorPos = bound(0, me.cursorPos, strlen(me.text));
240 cursorPosInWidths = draw_TextWidth(substring(me.text, 0, me.cursorPos), 0, me.realFontSize);
241 totalSizeInWidths = draw_TextWidth(strcat(me.text, CURSOR), 0, me.realFontSize);
243 if(me.dragScrollTimer < time)
247 me.scrollPos = bound(cursorPosInWidths - (0.875 - me.keepspaceLeft - me.keepspaceRight), me.scrollPos, cursorPosInWidths - 0.125);
248 if(me.scrollPos != save)
249 me.dragScrollTimer = time + 0.2;
251 me.scrollPos = min(me.scrollPos, totalSizeInWidths - (1 - me.keepspaceRight - me.keepspaceLeft));
252 me.scrollPos = max(0, me.scrollPos);
254 draw_SetClipRect(eX * me.keepspaceLeft, eX * (1 - me.keepspaceLeft - me.keepspaceRight) + eY);
255 if(me.editColorCodes)
260 float theAlpha; //float theVariableAlpha;
265 p = me.realOrigin - eX * me.scrollPos;
267 theAlpha = 1; //theVariableAlpha = 1; // changes when ^ax found
270 for(i = 0; i < n; ++i)
272 ch = substring(me.text, i, 1);
276 ch2 = substring(me.text, i+1, 1);
277 w = draw_TextWidth(strcat(ch, ch2), 0, me.realFontSize);
280 draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5);
281 draw_Text(p + eX * 0.25 * w, "^", me.realFontSize, theColor, theAlpha, 0);
283 else if(ch2 == "0" || stof(ch2)) // digit?
287 case 0: theColor = '0 0 0'; theAlpha = 1; break;
288 case 1: theColor = '1 0 0'; theAlpha = 1; break;
289 case 2: theColor = '0 1 0'; theAlpha = 1; break;
290 case 3: theColor = '1 1 0'; theAlpha = 1; break;
291 case 4: theColor = '0 0 1'; theAlpha = 1; break;
292 case 5: theColor = '0 1 1'; theAlpha = 1; break;
293 case 6: theColor = '1 0 1'; theAlpha = 1; break;
294 case 7: theColor = '1 1 1'; theAlpha = 1; break;
295 case 8: theColor = '1 1 1'; theAlpha = 0.5; break;
296 case 9: theColor = '0.5 0.5 0.5'; theAlpha = 1; break;
298 draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5);
299 draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0);
301 else if(ch2 == "x") // ^x found
305 component = HEXDIGIT_TO_DEC(substring(me.text, i+2, 1));
306 if (component >= 0) // ^xr found
308 theTempColor.x = component/15;
310 component = HEXDIGIT_TO_DEC(substring(me.text, i+3, 1));
311 if (component >= 0) // ^xrg found
313 theTempColor.y = component/15;
315 component = HEXDIGIT_TO_DEC(substring(me.text, i+4, 1));
316 if (component >= 0) // ^xrgb found
318 theTempColor.z = component/15;
319 theColor = theTempColor;
320 w = draw_TextWidth(substring(me.text, i, 5), 0, me.realFontSize);
322 draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5);
323 draw_Text(p, substring(me.text, i, 5), me.realFontSize, theColor, 1, 0); // theVariableAlpha instead of 1 using alpha tags ^ax
329 w = draw_TextWidth(substring(me.text, i, 4), 0, me.realFontSize);
330 draw_Fill(p, eX * w + eY * me.realFontSize.y, eZ, 0.5);
331 draw_Text(p, substring(me.text, i, 4), me.realFontSize, '1 1 1', theAlpha, 0);
338 w = draw_TextWidth(substring(me.text, i, 3), 0, me.realFontSize);
339 draw_Fill(p, eX * w + eY * me.realFontSize.y, eY, 0.5);
340 draw_Text(p, substring(me.text, i, 3), me.realFontSize, '1 1 1', theAlpha, 0);
347 //w = draw_TextWidth(substring(me.text, i, 2), 0) * me.realFontSize_x;
348 draw_Fill(p, eX * w + eY * me.realFontSize.y, eX, 0.5);
349 draw_Text(p, substring(me.text, i, 2), me.realFontSize, '1 1 1', theAlpha, 0);
354 draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5);
355 draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0);
361 draw_Text(p, ch, me.realFontSize, theColor, theAlpha, 0); // TODO theVariableAlpha
362 p += eX * draw_TextWidth(ch, 0, me.realFontSize);
366 draw_Text(me.realOrigin - eX * me.scrollPos, me.text, me.realFontSize, '1 1 1', 1, 0);
368 if(!me.focused || (time - me.lastChangeTime) < floor(time - me.lastChangeTime) + 0.5)
369 draw_Text(me.realOrigin + eX * (cursorPosInWidths - me.scrollPos), CURSOR, me.realFontSize, '1 1 1', 1, 0);
373 if (me.enableClearButton)
376 if(me.focused && me.cb_pressed)
377 draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_c"), eX * me.cb_width + eY, me.cb_colorC, 1);
378 else if(me.focused && me.cb_focused)
379 draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_f"), eX * me.cb_width + eY, me.cb_colorF, 1);
381 draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_n"), eX * me.cb_width + eY, me.cb_color, 1);
384 // skipping SUPER(InputBox).draw(me);
388 void InputBox_showNotify(entity me)
390 me.focusable = !me.disabled;