1 /* bzflag
2 * Copyright (c) 1993-2021 Tim Riker
3 *
4 * This package is free software; you can redistribute it and/or
5 * modify it under the terms of the license found in the file
6 * named COPYING that should have accompanied this file.
7 *
8 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
9 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11 */
12
13 // interface headers
14 #include "HUDuiTypeIn.h"
15
16 // system implementation headers
17 #include <ctype.h>
18
19 // common implementation headers
20 #include "FontManager.h"
21
22 // local implementation headers
23 #include "HUDui.h"
24
25 //
26 // HUDuiTypeIn
27 //
28
HUDuiTypeIn()29 HUDuiTypeIn::HUDuiTypeIn()
30 : HUDuiControl()
31 , maxLength(0)
32 , cursorPos(0)
33 , allowEdit(true)
34 , obfuscate(false)
35 , colorFunc(NULL)
36 {
37 }
38
~HUDuiTypeIn()39 HUDuiTypeIn::~HUDuiTypeIn()
40 {
41 }
42
setObfuscation(bool on)43 void HUDuiTypeIn::setObfuscation(bool on)
44 {
45 obfuscate = on;
46 }
47
getMaxLength() const48 int HUDuiTypeIn::getMaxLength() const
49 {
50 return maxLength;
51 }
52
getString() const53 std::string HUDuiTypeIn::getString() const
54 {
55 return string;
56 }
57
setMaxLength(int _maxLength)58 void HUDuiTypeIn::setMaxLength(int _maxLength)
59 {
60 maxLength = _maxLength;
61 string = string.substr(0, maxLength);
62 if (cursorPos > maxLength)
63 cursorPos = maxLength;
64 onSetFont();
65 }
66
setString(const std::string & _string)67 void HUDuiTypeIn::setString(const std::string& _string)
68 {
69 string = _string;
70 cursorPos = string.length();
71 onSetFont();
72 }
73
74 // allows composing, otherwise not
setEditing(bool _allowEdit)75 void HUDuiTypeIn::setEditing(bool _allowEdit)
76 {
77 allowEdit = _allowEdit;
78 }
79
doKeyPress(const BzfKeyEvent & key)80 bool HUDuiTypeIn::doKeyPress(const BzfKeyEvent& key)
81 {
82 static const char backspace = '\b'; // ^H
83 static const char whitespace = ' ';
84
85 if (!allowEdit) return false; //or return true ??
86 char c = key.ascii;
87 if (c == 0)
88 {
89 switch (key.button)
90 {
91 case BzfKeyEvent::Up:
92 HUDui::setFocus(getPrev());
93 return true;
94
95 case BzfKeyEvent::Down:
96 HUDui::setFocus(getNext());
97 return true;
98
99 case BzfKeyEvent::Left:
100 if (cursorPos > 0)
101 cursorPos--;
102 return true;
103
104 case BzfKeyEvent::Right:
105 if (cursorPos < (int)string.length())
106 cursorPos++;
107 return true;
108
109 case BzfKeyEvent::Home:
110 cursorPos = 0;
111 return true;
112
113 case BzfKeyEvent::End:
114 cursorPos = string.length();
115 return true;
116
117 case BzfKeyEvent::Backspace:
118 c = backspace;
119 break;
120
121 case BzfKeyEvent::Delete:
122 if (cursorPos < (int)string.length())
123 {
124 cursorPos++;
125 c = backspace;
126 }
127 else
128 return true;
129 break;
130
131 default:
132 return false;
133 }
134 }
135
136 if (c == '\t')
137 {
138 HUDui::setFocus(getNext());
139 return true;
140 }
141 if (c >0 && (!isprint(c) && c != backspace))
142 return false;
143
144 if (c == backspace)
145 {
146 if (cursorPos == 0)
147 return true;
148
149 cursorPos--;
150 string = string.substr(0, cursorPos) + string.substr(cursorPos + 1, string.length() - cursorPos + 1);
151 onSetFont();
152 }
153 else if (c > 0)
154 {
155 if (isspace(c))
156 c = whitespace;
157 if ((int)string.length() == maxLength)
158 return true;
159
160 string = string.substr(0, cursorPos) + c + string.substr( cursorPos, string.length() - cursorPos);
161 cursorPos++;
162 onSetFont();
163 }
164 return true;
165 }
166
doKeyRelease(const BzfKeyEvent & key)167 bool HUDuiTypeIn::doKeyRelease(const BzfKeyEvent& key)
168 {
169 if (key.ascii == '\t' || !isprint(key.ascii)) // ignore non-printing and tab
170 return false;
171
172 // slurp up releases
173 return true;
174 }
175
doRender()176 void HUDuiTypeIn::doRender()
177 {
178 if (getFontFace() < 0) return;
179
180 // render string
181 glColor3fv(hasFocus() ? textColor : dimTextColor);
182
183 FontManager &fm = FontManager::instance();
184 std::string renderStr;
185 if (obfuscate)
186 renderStr.append(string.size(), '*');
187 else
188 renderStr = string;
189 if (colorFunc)
190 renderStr = colorFunc(renderStr);
191 fm.drawString(getX(), getY(), 0, getFontFace(), getFontSize(), renderStr);
192
193 // find the position of where to draw the input cursor
194 const std::string noAnsi = stripAnsiCodes(renderStr);
195 float start = fm.getStrLength(getFontFace(), getFontSize(), noAnsi.substr(0, cursorPos));
196
197 if (HUDui::getFocus() == this && allowEdit)
198 fm.drawString(getX() + start, getY(), 0, getFontFace(), getFontSize(), "_");
199 }
200
201 // Local Variables: ***
202 // mode: C++ ***
203 // tab-width: 4 ***
204 // c-basic-offset: 4 ***
205 // indent-tabs-mode: nil ***
206 // End: ***
207 // ex: shiftwidth=4 tabstop=4
208