]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/menu-div0test/item/inputbox.c
better support odd resolutions (like widescreen)
[divverent/nexuiz.git] / data / qcsrc / menu-div0test / item / inputbox.c
1 #ifdef INTERFACE
2 CLASS(InputBox) EXTENDS(Label)
3         METHOD(InputBox, configureInputBox, void(entity, string, float, float, string))
4         METHOD(InputBox, draw, void(entity))
5         METHOD(InputBox, setText, void(entity, string))
6         METHOD(InputBox, enterText, void(entity, string))
7         METHOD(InputBox, keyDown, float(entity, float, float, float))
8         METHOD(InputBox, mouseRelease, float(entity, vector))
9         METHOD(InputBox, mousePress, float(entity, vector))
10         METHOD(InputBox, mouseDrag, float(entity, vector))
11
12         ATTRIB(InputBox, src, string, string_null)
13
14         ATTRIB(InputBox, cursorPos, float, 0) // characters
15         ATTRIB(InputBox, scrollPos, float, 0) // widths
16
17         ATTRIB(InputBox, focusable, float, 1)
18         ATTRIB(InputBox, lastChangeTime, float, 0)
19         ATTRIB(InputBox, dragScrollTimer, float, 0)
20         ATTRIB(InputBox, dragScrollPos, vector, '0 0 0')
21         ATTRIB(InputBox, pressed, float, 0)
22         ATTRIB(InputBox, editColorCodes, float, 1)
23         ATTRIB(InputBox, forbiddenCharacters, string, "")
24         ATTRIB(InputBox, color, vector, '1 1 1')
25         ATTRIB(InputBox, colorF, vector, '1 1 1')
26 ENDCLASS(InputBox)
27 void InputBox_Clear_Click(entity btn, entity me);
28 #endif
29
30 #ifdef IMPLEMENTATION
31 void configureInputBoxInputBox(entity me, string theText, float theCursorPos, float theFontSize, string gfx)
32 {
33         configureLabelLabel(me, theText, theFontSize, 0.0);
34         me.src = gfx;
35         me.cursorPos = theCursorPos;
36 }
37
38 void setTextInputBox(entity me, string txt)
39 {
40         if(me.text)
41                 strunzone(me.text);
42         setTextLabel(me, strzone(txt));
43 }
44
45 void InputBox_Clear_Click(entity btn, entity me)
46 {
47         me.setText(me, "");
48 }
49
50 float mouseDragInputBox(entity me, vector pos)
51 {
52         float p;
53         me.dragScrollPos = pos;
54         p = me.scrollPos + pos_x - me.keepspaceLeft;
55         me.cursorPos = draw_TextLengthUpToWidth(me.text, p / me.realFontSize_x, 0);
56         me.lastChangeTime = time;
57         return 1;
58 }
59
60 float mousePressInputBox(entity me, vector pos)
61 {
62         me.dragScrollTimer = 0;
63         me.pressed = 1;
64         return mouseDragInputBox(me, pos);
65 }
66
67 float mouseReleaseInputBox(entity me, vector pos)
68 {
69         me.pressed = 0;
70         return mouseDragInputBox(me, pos);
71 }
72
73 void enterTextInputBox(entity me, string ch)
74 {
75         float i;
76         for(i = 0; i < strlen(ch); ++i)
77                 if(strstrofs(me.forbiddenCharacters, substring(ch, i, 1), 0) > -1)
78                         return;
79         me.setText(me, strcat(substring(me.text, 0, me.cursorPos), ch, substring(me.text, me.cursorPos, strlen(me.text) - me.cursorPos)));
80         me.cursorPos += strlen(ch);
81 }
82
83 float keyDownInputBox(entity me, float key, float ascii, float shift)
84 {
85         me.lastChangeTime = time;
86         me.dragScrollTimer = 0;
87         if(ascii >= 32 && ascii != 127)
88         {
89                 me.enterText(me, chr(ascii));
90                 return 1;
91         }
92         switch(key)
93         {
94                 case K_LEFTARROW:
95                         me.cursorPos -= 1;
96                         return 1;
97                 case K_RIGHTARROW:
98                         me.cursorPos += 1;
99                         return 1;
100                 case K_HOME:
101                         me.cursorPos = 0;
102                         return 1;
103                 case K_END:
104                         me.cursorPos = strlen(me.text);
105                         return 1;
106                 case K_BACKSPACE:
107                         if(shift)
108                                 me.setText(me, "");
109                         else
110                                 if(me.cursorPos > 0)
111                                 {
112                                         me.cursorPos -= 1;
113                                         me.setText(me, strcat(substring(me.text, 0, me.cursorPos), substring(me.text, me.cursorPos + 1, strlen(me.text) - me.cursorPos - 1)));
114                                 }
115                         return 1;
116                 case K_DEL:
117                         if(shift)
118                                 me.setText(me, "");
119                         else
120                                 me.setText(me, strcat(substring(me.text, 0, me.cursorPos), substring(me.text, me.cursorPos + 1, strlen(me.text) - me.cursorPos - 1)));
121                         return 1;
122         }
123         return 0;
124 }
125
126 void drawInputBox(entity me)
127 {
128 #define CURSOR "_"
129         float cursorPosInWidths, totalSizeInWidths;
130
131         if(me.pressed)
132                 me.mouseDrag(me, me.dragScrollPos); // simulate mouseDrag event
133
134         if(me.src)
135         {
136                 if(me.focused)
137                         draw_ButtonPicture('0 0 0', strcat(me.src, "_f"), '1 1 0', me.colorF, 1);
138                 else
139                         draw_ButtonPicture('0 0 0', strcat(me.src, "_n"), '1 1 0', me.color, 1);
140         }
141
142         me.cursorPos = bound(0, me.cursorPos, strlen(me.text));
143         cursorPosInWidths = draw_TextWidth(substring(me.text, 0, me.cursorPos), 0) * me.realFontSize_x;
144         totalSizeInWidths = draw_TextWidth(strcat(me.text, CURSOR), 0) * me.realFontSize_x;
145
146         me.dragScrollTimer -= frametime;
147         if(me.dragScrollTimer < 0)
148         {
149                 float save;
150                 save = me.scrollPos;
151                 me.scrollPos = bound(cursorPosInWidths - (0.875 - me.keepspaceLeft - me.keepspaceRight), me.scrollPos, cursorPosInWidths - 0.125);
152                 if(me.scrollPos != save)
153                         me.dragScrollTimer = 0.2;
154         }
155         me.scrollPos = min(me.scrollPos, totalSizeInWidths - (1 - me.keepspaceRight - me.keepspaceLeft));
156         me.scrollPos = max(0, me.scrollPos);
157
158         draw_SetClipRect(eX * me.keepspaceLeft, eX * (1 - me.keepspaceLeft - me.keepspaceRight) + eY);
159         if(me.editColorCodes)
160         {
161                 string ch, ch2;
162                 float i;
163                 vector theColor;
164                 float theAlpha;
165                 vector p;
166                 float brightness;
167                 brightness = cvar("r_textbrightness");
168                 p = me.realOrigin - eX * me.scrollPos;
169                 theColor = '1 1 1';
170                 theAlpha = 1;
171                 for(i = 0; i < strlen(me.text); ++i)
172                 {
173                         ch = substring(me.text, i, 1);
174                         if(ch == "^")
175                         {
176                                 float w;
177                                 ch2 = substring(me.text, i+1, 1);
178                                 w = draw_TextWidth(strcat(ch, ch2), 0) * me.realFontSize_x;
179                                 if(ch2 == "^")
180                                 {
181                                         draw_Fill(p, eX * w + eY * me.realFontSize_y, '0 0 1', 0.5);
182                                         draw_Text(p + eX * 0.25 * w, "^", me.realFontSize, theColor, theAlpha, 0);
183                                 }
184                                 else if(ch2 == "0" || stof(ch2)) // digit?
185                                 {
186                                         switch(stof(ch2))
187                                         {
188                                                 case 0: theColor = '0 0 0'; theAlpha = 1; break;
189                                                 case 1: theColor = '1 0 0'; theAlpha = 1; break;
190                                                 case 2: theColor = '0 1 0'; theAlpha = 1; break;
191                                                 case 3: theColor = '1 1 0'; theAlpha = 1; break;
192                                                 case 4: theColor = '0 0 1'; theAlpha = 1; break;
193                                                 case 5: theColor = '0 1 1'; theAlpha = 1; break;
194                                                 case 6: theColor = '1 0 1'; theAlpha = 1; break;
195                                                 case 7: theColor = '1 1 1'; theAlpha = 1; break;
196                                                 case 8: theColor = '1 1 1'; theAlpha = 0.5; break;
197                                                 case 9: theColor = '0.5 0.5 0.5'; theAlpha = 1; break;
198                                         }
199                                         theColor = theColor * (1 - brightness) + brightness * '1 1 1';
200                                         draw_Fill(p, eX * w + eY * me.realFontSize_y, '1 1 1', 0.5);
201                                         draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0);
202                                         draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0);
203                                 }
204                                 else
205                                 {
206                                         draw_Fill(p, eX * w + eY * me.realFontSize_y, '1 0 0', 0.5);
207                                         draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0);
208                                         draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0);
209                                 }
210                                 p += w * eX;
211                                 ++i;
212                                 continue;
213                         }
214                         draw_Text(p, ch, me.realFontSize, theColor, theAlpha, 0); p += eX * draw_TextWidth(ch, 0) * me.realFontSize_x;
215                 }
216         }
217         else
218                 draw_Text(me.realOrigin - eX * me.scrollPos, me.text, me.realFontSize, '1 1 1', 1, 0);
219                 // skipping drawLabel(me);
220         if(!me.focused || (time - me.lastChangeTime) < floor(time - me.lastChangeTime) + 0.5)
221                 draw_Text(me.realOrigin + eX * (cursorPosInWidths - me.scrollPos), CURSOR, me.realFontSize, '1 1 1', 1, 0);
222
223         draw_ClearClip();
224 }
225 #endif