]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/menu/item/inputbox.c
r5315 | div0 | 2008-12-26 16:47:30 +0100 (Fri, 26 Dec 2008) | 2 lines
[divverent/nexuiz.git] / data / qcsrc / menu / 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         METHOD(InputBox, showNotify, void(entity))
12
13         ATTRIB(InputBox, src, string, string_null)
14
15         ATTRIB(InputBox, cursorPos, float, 0) // characters
16         ATTRIB(InputBox, scrollPos, float, 0) // widths
17
18         ATTRIB(InputBox, focusable, float, 1)
19         ATTRIB(InputBox, disabled, float, 0)
20         ATTRIB(InputBox, lastChangeTime, float, 0)
21         ATTRIB(InputBox, dragScrollTimer, float, 0)
22         ATTRIB(InputBox, dragScrollPos, vector, '0 0 0')
23         ATTRIB(InputBox, pressed, float, 0)
24         ATTRIB(InputBox, editColorCodes, float, 1)
25         ATTRIB(InputBox, forbiddenCharacters, string, "")
26         ATTRIB(InputBox, color, vector, '1 1 1')
27         ATTRIB(InputBox, colorF, vector, '1 1 1')
28 ENDCLASS(InputBox)
29 void InputBox_Clear_Click(entity btn, entity me);
30 #endif
31
32 #ifdef IMPLEMENTATION
33 void configureInputBoxInputBox(entity me, string theText, float theCursorPos, float theFontSize, string gfx)
34 {
35         configureLabelLabel(me, theText, theFontSize, 0.0);
36         me.src = gfx;
37         me.cursorPos = theCursorPos;
38 }
39
40 void setTextInputBox(entity me, string txt)
41 {
42         if(me.text)
43                 strunzone(me.text);
44         setTextLabel(me, strzone(txt));
45 }
46
47 void InputBox_Clear_Click(entity btn, entity me)
48 {
49         me.setText(me, "");
50 }
51
52 float mouseDragInputBox(entity me, vector pos)
53 {
54         float p;
55         me.dragScrollPos = pos;
56         p = me.scrollPos + pos_x - me.keepspaceLeft;
57         me.cursorPos = draw_TextLengthUpToWidth(me.text, p / me.realFontSize_x, 0);
58         me.lastChangeTime = time;
59         return 1;
60 }
61
62 float mousePressInputBox(entity me, vector pos)
63 {
64         me.dragScrollTimer = time;
65         me.pressed = 1;
66         return mouseDragInputBox(me, pos);
67 }
68
69 float mouseReleaseInputBox(entity me, vector pos)
70 {
71         me.pressed = 0;
72         return mouseDragInputBox(me, pos);
73 }
74
75 void enterTextInputBox(entity me, string ch)
76 {
77         float i;
78         for(i = 0; i < strlen(ch); ++i)
79                 if(strstrofs(me.forbiddenCharacters, substring(ch, i, 1), 0) > -1)
80                         return;
81         me.setText(me, strcat(substring(me.text, 0, me.cursorPos), ch, substring(me.text, me.cursorPos, strlen(me.text) - me.cursorPos)));
82         me.cursorPos += strlen(ch);
83 }
84
85 float keyDownInputBox(entity me, float key, float ascii, float shift)
86 {
87         me.lastChangeTime = time;
88         me.dragScrollTimer = time;
89         if(ascii >= 32 && ascii != 127)
90         {
91                 me.enterText(me, chr(ascii));
92                 return 1;
93         }
94         switch(key)
95         {
96                 case K_LEFTARROW:
97                         me.cursorPos -= 1;
98                         return 1;
99                 case K_RIGHTARROW:
100                         me.cursorPos += 1;
101                         return 1;
102                 case K_HOME:
103                         me.cursorPos = 0;
104                         return 1;
105                 case K_END:
106                         me.cursorPos = strlen(me.text);
107                         return 1;
108                 case K_BACKSPACE:
109                         if(me.cursorPos > 0)
110                         {
111                                 me.cursorPos -= 1;
112                                 me.setText(me, strcat(substring(me.text, 0, me.cursorPos), substring(me.text, me.cursorPos + 1, strlen(me.text) - me.cursorPos - 1)));
113                         }
114                         return 1;
115                 case K_DEL:
116                         if(shift & S_CTRL)
117                                 me.setText(me, "");
118                         else
119                                 me.setText(me, strcat(substring(me.text, 0, me.cursorPos), substring(me.text, me.cursorPos + 1, strlen(me.text) - me.cursorPos - 1)));
120                         return 1;
121         }
122         return 0;
123 }
124
125 void drawInputBox(entity me)
126 {
127 #define CURSOR "_"
128         float cursorPosInWidths, totalSizeInWidths;
129
130         if(me.pressed)
131                 me.mouseDrag(me, me.dragScrollPos); // simulate mouseDrag event
132
133         me.focusable = !me.disabled;
134         if(me.disabled)
135                 draw_alpha *= me.disabledAlpha;
136
137         if(me.src)
138         {
139                 if(me.focused && !me.disabled)
140                         draw_ButtonPicture('0 0 0', strcat(me.src, "_f"), '1 1 0', me.colorF, 1);
141                 else
142                         draw_ButtonPicture('0 0 0', strcat(me.src, "_n"), '1 1 0', me.color, 1);
143         }
144
145         me.cursorPos = bound(0, me.cursorPos, strlen(me.text));
146         cursorPosInWidths = draw_TextWidth(substring(me.text, 0, me.cursorPos), 0) * me.realFontSize_x;
147         totalSizeInWidths = draw_TextWidth(strcat(me.text, CURSOR), 0) * me.realFontSize_x;
148
149         if(me.dragScrollTimer < time)
150         {
151                 float save;
152                 save = me.scrollPos;
153                 me.scrollPos = bound(cursorPosInWidths - (0.875 - me.keepspaceLeft - me.keepspaceRight), me.scrollPos, cursorPosInWidths - 0.125);
154                 if(me.scrollPos != save)
155                         me.dragScrollTimer = time + 0.2;
156         }
157         me.scrollPos = min(me.scrollPos, totalSizeInWidths - (1 - me.keepspaceRight - me.keepspaceLeft));
158         me.scrollPos = max(0, me.scrollPos);
159
160         draw_SetClipRect(eX * me.keepspaceLeft, eX * (1 - me.keepspaceLeft - me.keepspaceRight) + eY);
161         if(me.editColorCodes)
162         {
163                 string ch, ch2;
164                 float i;
165                 vector theColor;
166                 float theAlpha;    //float theVariableAlpha;
167                 vector p;
168                 float brightness, contrast;
169                 vector theTempColor;
170                 float component;
171                 
172                 brightness = cvar("r_textbrightness");
173                 contrast = cvar("r_textcontrast");
174                 p = me.realOrigin - eX * me.scrollPos;
175                 theColor = '1 1 1';
176                 theAlpha = 1;    //theVariableAlpha = 1; // changes when ^ax found
177                 
178                 theColor = theColor * contrast + '1 1 1' * brightness;
179                 for(i = 0; i < strlen(me.text); ++i)
180                 {
181                         ch = substring(me.text, i, 1);
182                         if(ch == "^")
183                         {
184                                 float w;
185                                 ch2 = substring(me.text, i+1, 1);
186                                 w = draw_TextWidth(strcat(ch, ch2), 0) * me.realFontSize_x;
187                                 if(ch2 == "^")
188                                 {
189                                         draw_Fill(p, eX * w + eY * me.realFontSize_y, '1 1 1', 0.5);
190                                         draw_Text(p + eX * 0.25 * w, "^", me.realFontSize, theColor, theAlpha, 0);
191                                 }
192                                 else if(ch2 == "0" || stof(ch2)) // digit?
193                                 {
194                                         switch(stof(ch2))
195                                         {
196                                                 case 0: theColor = '0 0 0'; theAlpha = 1; break;
197                                                 case 1: theColor = '1 0 0'; theAlpha = 1; break;
198                                                 case 2: theColor = '0 1 0'; theAlpha = 1; break;
199                                                 case 3: theColor = '1 1 0'; theAlpha = 1; break;
200                                                 case 4: theColor = '0 0 1'; theAlpha = 1; break;
201                                                 case 5: theColor = '0 1 1'; theAlpha = 1; break;
202                                                 case 6: theColor = '1 0 1'; theAlpha = 1; break;
203                                                 case 7: theColor = '1 1 1'; theAlpha = 1; break;
204                                                 case 8: theColor = '1 1 1'; theAlpha = 0.5; break;
205                                                 case 9: theColor = '0.5 0.5 0.5'; theAlpha = 1; break;
206                                         }
207                                         theColor = theColor * contrast + '1 1 1' * brightness;
208                                         draw_Fill(p, eX * w + eY * me.realFontSize_y, '1 1 1', 0.5);
209                                         draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0);
210                                 }
211                                 else if(ch2 == "x") // ^x found
212                                 {
213                                         theColor = '1 1 1';
214                                         theTempColor = '0 0 0';
215                                         
216                                         component = HEXDIGIT_TO_DEC(substring(me.text, i+2, 1));
217                                         if (component >= 0) // ^xr found
218                                         {
219                                                 theTempColor_x = component/15;
220                                                 
221                                                 component = HEXDIGIT_TO_DEC(substring(me.text, i+3, 1));
222                                                 if (component >= 0) // ^xrg found
223                                                 {
224                                                         theTempColor_y = component/15;
225                                                         
226                                                         component = HEXDIGIT_TO_DEC(substring(me.text, i+4, 1));
227                                                         if (component >= 0) // ^xrgb found
228                                                         {
229                                                                 theTempColor_z = component/15;
230                                                                 theColor = theTempColor * contrast + '1 1 1' * brightness;
231                                                                 w = draw_TextWidth(substring(me.text, i, 5), 0) * me.realFontSize_x;
232                                                                 
233                                                                 draw_Fill(p, eX * w + eY * me.realFontSize_y, '1 1 1', 0.5);
234                                                                 draw_Text(p, substring(me.text, i, 5), me.realFontSize, theColor, 1, 0);    // theVariableAlpha instead of 1 using alpha tags ^ax
235                                                                 i += 3;
236                                                         }
237                                                         else
238                                                         {
239                                                                 // blue missing
240                                                                 w = draw_TextWidth(substring(me.text, i, 4), 0) * me.realFontSize_x;
241                                                                 draw_Fill(p, eX * w + eY * me.realFontSize_y, eZ, 0.5);
242                                                                 draw_Text(p, substring(me.text, i, 4), me.realFontSize, '1 1 1', theAlpha, 0);
243                                                                 i += 2;
244                                                         }
245                                                 }
246                                                 else
247                                                 {
248                                                         // green missing
249                                                         w = draw_TextWidth(substring(me.text, i, 3), 0) * me.realFontSize_x;
250                                                         draw_Fill(p, eX * w + eY * me.realFontSize_y, eY, 0.5);
251                                                         draw_Text(p, substring(me.text, i, 3), me.realFontSize, '1 1 1', theAlpha, 0);
252                                                         i += 1;
253                                                 }
254                                         }
255                                         else
256                                         {
257                                                 // red missing
258                                                 //w = draw_TextWidth(substring(me.text, i, 2), 0) * me.realFontSize_x;
259                                                 draw_Fill(p, eX * w + eY * me.realFontSize_y, eX, 0.5);
260                                                 draw_Text(p, substring(me.text, i, 2), me.realFontSize, '1 1 1', theAlpha, 0);
261                                         }
262                                 }
263                                 /*else if(ch2 == "a") // ^a found
264                                 {
265                                         draw_Fill(p, eX * w + eY * me.realFontSize_y, '1 1 1', 0.5);
266                                         draw_Text(p, substring(me.text, i, 2), me.realFontSize, theColor, 0.8, 0);
267                                         
268                                         component = str2chr(me.text, i+2);
269                                         if (component >= '0' && component <= '9')
270                                                 component = component - '0';
271                                         else if (component >= 'a' && component <= 'f')
272                                                 component = component - 87;
273                                         else if (component >= 'A' && component <= 'F')
274                                                 component = component - 55;
275                                         else
276                                                 component = -1;
277                                         
278                                         if (component >= 0) // ^ah found
279                                         {
280                                                 // FIX ME: overflow here
281                                                 if (component == 20 && theVariableAlpha <= 0.97)
282                                                         theVariableAlpha = theVariableAlpha + 0.0625;
283                                                 else if (component == 30 && theVariableAlpha >= 0.03)
284                                                         theVariableAlpha = theVariableAlpha - 0.0625;
285                                                 else
286                                                         theVariableAlpha = component*0.0625;
287                                                 
288                                                 draw_Fill(p, eX * draw_TextWidth(substring(me.text, i, 3), 0) * me.realFontSize_x + eY * me.realFontSize_y, '0.8 0.8 0.8', 0.5);
289                                                 draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, 0.8, 0);
290                                         }
291                                 }*/
292                                 else
293                                 {
294                                         draw_Fill(p, eX * w + eY * me.realFontSize_y, '1 1 1', 0.5);
295                                         draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0);
296                                 }
297                                 p += w * eX;
298                                 ++i;
299                                 continue;
300                         }
301                         draw_Text(p, ch, me.realFontSize, theColor, theAlpha, 0); // TODO theVariableAlpha
302                         p += eX * draw_TextWidth(ch, 0) * me.realFontSize_x;
303                 }
304         }
305         else
306                 draw_Text(me.realOrigin - eX * me.scrollPos, me.text, me.realFontSize, '1 1 1', 1, 0);
307                 // skipping drawLabel(me);
308         if(!me.focused || (time - me.lastChangeTime) < floor(time - me.lastChangeTime) + 0.5)
309                 draw_Text(me.realOrigin + eX * (cursorPosInWidths - me.scrollPos), CURSOR, me.realFontSize, '1 1 1', 1, 0);
310
311         draw_ClearClip();
312 }
313
314 void showNotifyInputBox(entity me)
315 {
316         me.focusable = !me.disabled;
317 }
318 #endif