1 #ifndef ITEM_INPUTBOX_H
2 #define ITEM_INPUTBOX_H
4 METHOD(InputBox, configureInputBox, void(entity, string, float, float, string))
5 METHOD(InputBox, draw, void(entity))
6 METHOD(InputBox, setText, void(entity, string))
7 METHOD(InputBox, enterText, void(entity, string))
8 METHOD(InputBox, keyDown, float(entity, float, float, float))
9 METHOD(InputBox, mouseMove, float(entity, vector))
10 METHOD(InputBox, mouseRelease, float(entity, vector))
11 METHOD(InputBox, mousePress, float(entity, vector))
12 METHOD(InputBox, mouseDrag, float(entity, vector))
13 METHOD(InputBox, showNotify, void(entity))
14 METHOD(InputBox, resizeNotify, void(entity, vector, vector, vector, vector))
16 ATTRIB(InputBox, src, string, string_null)
18 ATTRIB(InputBox, cursorPos, float, 0) // characters
19 ATTRIB(InputBox, scrollPos, float, 0) // widths
21 ATTRIB(InputBox, focusable, float, 1)
22 ATTRIB(InputBox, allowFocusSound, float, 1)
23 ATTRIB(InputBox, disabled, float, 0)
24 ATTRIB(InputBox, lastChangeTime, float, 0)
25 ATTRIB(InputBox, dragScrollTimer, float, 0)
26 ATTRIB(InputBox, dragScrollPos, vector, '0 0 0')
27 ATTRIB(InputBox, pressed, float, 0)
28 ATTRIB(InputBox, editColorCodes, float, 1)
29 ATTRIB(InputBox, forbiddenCharacters, string, "")
30 ATTRIB(InputBox, color, vector, '1 1 1')
31 ATTRIB(InputBox, colorF, vector, '1 1 1')
32 ATTRIB(InputBox, maxLength, float, 255) // if negative, it counts bytes, not chars
34 ATTRIB(InputBox, enableClearButton, float, 1)
35 ATTRIB(InputBox, clearButton, entity, NULL)
36 ATTRIB(InputBox, cb_width, float, 0)
37 ATTRIB(InputBox, cb_pressed, float, 0)
38 ATTRIB(InputBox, cb_focused, float, 0)
39 ATTRIB(InputBox, cb_color, vector, '1 1 1')
40 ATTRIB(InputBox, cb_colorF, vector, '1 1 1')
41 ATTRIB(InputBox, cb_colorC, vector, '1 1 1')
46 void InputBox_configureInputBox(entity me, string theText, float theCursorPos, float theFontSize, string gfx)
48 SUPER(InputBox).configureLabel(me, theText, theFontSize, 0.0);
50 me.cursorPos = theCursorPos;
52 void InputBox_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
54 SUPER(InputBox).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
55 if (me.enableClearButton)
57 me.cb_width = absSize.y / absSize.x;
58 me.cb_offset = bound(-1, me.cb_offset, 0) * me.cb_width; // bound to range -1, 0
59 me.keepspaceRight = me.keepspaceRight - me.cb_offset + me.cb_width;
63 void InputBox_setText(entity me, string txt)
67 SUPER(InputBox).setText(me, strzone(txt));
70 float over_ClearButton(entity me, vector pos)
72 if (pos.x >= 1 + me.cb_offset - me.cb_width)
73 if (pos.x < 1 + me.cb_offset)
80 float InputBox_mouseMove(entity me, vector pos)
82 if (me.enableClearButton)
84 if (over_ClearButton(me, pos))
94 float InputBox_mouseDrag(entity me, vector pos)
99 me.dragScrollPos = pos;
100 p = me.scrollPos + pos.x - me.keepspaceLeft;
101 me.cursorPos = draw_TextLengthUpToWidth(me.text, p, 0, me.realFontSize);
102 me.lastChangeTime = time;
104 else if (me.enableClearButton)
106 if (over_ClearButton(me, pos))
116 float InputBox_mousePress(entity me, vector pos)
118 if (me.enableClearButton)
119 if (over_ClearButton(me, pos))
124 me.dragScrollTimer = time;
126 return InputBox_mouseDrag(me, pos);
129 float InputBox_mouseRelease(entity me, vector pos)
132 if (over_ClearButton(me, pos))
134 m_play_click_sound(MENU_SOUND_CLEAR);
139 float r = InputBox_mouseDrag(me, pos);
140 //reset cb_pressed after mouseDrag, mouseDrag could set cb_pressed in this case:
141 //mouse press out of the clear button, drag and then mouse release over the clear button
147 void InputBox_enterText(entity me, string ch)
150 for(i = 0; i < strlen(ch); ++i)
151 if(strstrofs(me.forbiddenCharacters, substring(ch, i, 1), 0) > -1)
155 if(strlen(ch) + strlen(me.text) > me.maxLength)
158 else if(me.maxLength < 0)
160 if(u8_strsize(ch) + u8_strsize(me.text) > -me.maxLength)
163 me.setText(me, strcat(substring(me.text, 0, me.cursorPos), ch, substring(me.text, me.cursorPos, strlen(me.text) - me.cursorPos)));
164 me.cursorPos += strlen(ch);
167 float InputBox_keyDown(entity me, float key, float ascii, float shift)
169 me.lastChangeTime = time;
170 me.dragScrollTimer = time;
171 if(ascii >= 32 && ascii != 127)
173 me.enterText(me, chr(ascii));
182 case K_KP_RIGHTARROW:
192 me.cursorPos = strlen(me.text);
198 me.setText(me, strcat(substring(me.text, 0, me.cursorPos), substring(me.text, me.cursorPos + 1, strlen(me.text) - me.cursorPos - 1)));
205 m_play_click_sound(MENU_SOUND_CLEAR);
209 me.setText(me, strcat(substring(me.text, 0, me.cursorPos), substring(me.text, me.cursorPos + 1, strlen(me.text) - me.cursorPos - 1)));
215 void InputBox_draw(entity me)
218 float cursorPosInWidths, totalSizeInWidths;
221 me.mouseDrag(me, me.dragScrollPos); // simulate mouseDrag event
224 me.recalcPositionWithText(me, me.text);
226 me.focusable = !me.disabled;
228 draw_alpha *= me.disabledAlpha;
232 if(me.focused && !me.disabled)
233 draw_ButtonPicture('0 0 0', strcat(me.src, "_f"), '1 1 0', me.colorF, 1);
235 draw_ButtonPicture('0 0 0', strcat(me.src, "_n"), '1 1 0', me.color, 1);
238 me.cursorPos = bound(0, me.cursorPos, strlen(me.text));
239 cursorPosInWidths = draw_TextWidth(substring(me.text, 0, me.cursorPos), 0, me.realFontSize);
240 totalSizeInWidths = draw_TextWidth(strcat(me.text, CURSOR), 0, me.realFontSize);
242 if(me.dragScrollTimer < time)
246 me.scrollPos = bound(cursorPosInWidths - (0.875 - me.keepspaceLeft - me.keepspaceRight), me.scrollPos, cursorPosInWidths - 0.125);
247 if(me.scrollPos != save)
248 me.dragScrollTimer = time + 0.2;
250 me.scrollPos = min(me.scrollPos, totalSizeInWidths - (1 - me.keepspaceRight - me.keepspaceLeft));
251 me.scrollPos = max(0, me.scrollPos);
253 draw_SetClipRect(eX * me.keepspaceLeft, eX * (1 - me.keepspaceLeft - me.keepspaceRight) + eY);
254 if(me.editColorCodes)
259 float theAlpha; //float theVariableAlpha;
264 p = me.realOrigin - eX * me.scrollPos;
266 theAlpha = 1; //theVariableAlpha = 1; // changes when ^ax found
269 for(i = 0; i < n; ++i)
271 ch = substring(me.text, i, 1);
275 ch2 = substring(me.text, i+1, 1);
276 w = draw_TextWidth(strcat(ch, ch2), 0, me.realFontSize);
279 draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5);
280 draw_Text(p + eX * 0.25 * w, "^", me.realFontSize, theColor, theAlpha, 0);
282 else if(ch2 == "0" || stof(ch2)) // digit?
286 case 0: theColor = '0 0 0'; theAlpha = 1; break;
287 case 1: theColor = '1 0 0'; theAlpha = 1; break;
288 case 2: theColor = '0 1 0'; theAlpha = 1; break;
289 case 3: theColor = '1 1 0'; theAlpha = 1; break;
290 case 4: theColor = '0 0 1'; theAlpha = 1; break;
291 case 5: theColor = '0 1 1'; theAlpha = 1; break;
292 case 6: theColor = '1 0 1'; theAlpha = 1; break;
293 case 7: theColor = '1 1 1'; theAlpha = 1; break;
294 case 8: theColor = '1 1 1'; theAlpha = 0.5; break;
295 case 9: theColor = '0.5 0.5 0.5'; theAlpha = 1; break;
297 draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5);
298 draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0);
300 else if(ch2 == "x") // ^x found
304 component = HEXDIGIT_TO_DEC(substring(me.text, i+2, 1));
305 if (component >= 0) // ^xr found
307 theTempColor.x = component/15;
309 component = HEXDIGIT_TO_DEC(substring(me.text, i+3, 1));
310 if (component >= 0) // ^xrg found
312 theTempColor.y = component/15;
314 component = HEXDIGIT_TO_DEC(substring(me.text, i+4, 1));
315 if (component >= 0) // ^xrgb found
317 theTempColor.z = component/15;
318 theColor = theTempColor;
319 w = draw_TextWidth(substring(me.text, i, 5), 0, me.realFontSize);
321 draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5);
322 draw_Text(p, substring(me.text, i, 5), me.realFontSize, theColor, 1, 0); // theVariableAlpha instead of 1 using alpha tags ^ax
328 w = draw_TextWidth(substring(me.text, i, 4), 0, me.realFontSize);
329 draw_Fill(p, eX * w + eY * me.realFontSize.y, eZ, 0.5);
330 draw_Text(p, substring(me.text, i, 4), me.realFontSize, '1 1 1', theAlpha, 0);
337 w = draw_TextWidth(substring(me.text, i, 3), 0, me.realFontSize);
338 draw_Fill(p, eX * w + eY * me.realFontSize.y, eY, 0.5);
339 draw_Text(p, substring(me.text, i, 3), me.realFontSize, '1 1 1', theAlpha, 0);
346 //w = draw_TextWidth(substring(me.text, i, 2), 0) * me.realFontSize_x;
347 draw_Fill(p, eX * w + eY * me.realFontSize.y, eX, 0.5);
348 draw_Text(p, substring(me.text, i, 2), me.realFontSize, '1 1 1', theAlpha, 0);
353 draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5);
354 draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0);
360 draw_Text(p, ch, me.realFontSize, theColor, theAlpha, 0); // TODO theVariableAlpha
361 p += eX * draw_TextWidth(ch, 0, me.realFontSize);
365 draw_Text(me.realOrigin - eX * me.scrollPos, me.text, me.realFontSize, '1 1 1', 1, 0);
367 if(!me.focused || (time - me.lastChangeTime) < floor(time - me.lastChangeTime) + 0.5)
368 draw_Text(me.realOrigin + eX * (cursorPosInWidths - me.scrollPos), CURSOR, me.realFontSize, '1 1 1', 1, 0);
372 if (me.enableClearButton)
375 if(me.focused && me.cb_pressed)
376 draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_c"), eX * me.cb_width + eY, me.cb_colorC, 1);
377 else if(me.focused && me.cb_focused)
378 draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_f"), eX * me.cb_width + eY, me.cb_colorF, 1);
380 draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_n"), eX * me.cb_width + eY, me.cb_color, 1);
383 // skipping SUPER(InputBox).draw(me);
387 void InputBox_showNotify(entity me)
389 me.focusable = !me.disabled;