PEBL 2.2
Psychology Experiment Building Language - Cross-platform psychological experiment development system
PTextBox.cpp
Go to the documentation of this file.
1//* -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*- */
3// Name: src/objects/PTextBox.cpp
4// Purpose: Contains generic specification for a read-only text box.
5// Author: Shane T. Mueller, Ph.D.
6// Copyright: (c) 2003-2026 Shane T. Mueller <smueller@obereed.net>
7// License: GPL 2
8//
9//
10//
11// This file is part of the PEBL project.
12//
13// PEBL is free software; you can redistribute it and/or modify
14// it under the terms of the GNU General Public License as published by
15// the Free Software Foundation; either version 2 of the License, or
16// (at your option) any later version.
17//
18// PEBL is distributed in the hope that it will be useful,
19// but WITHOUT ANY WARRANTY; without even the implied warranty of
20// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21// GNU General Public License for more details.
22//
23// You should have received a copy of the GNU General Public License
24// along with PEBL; if not, write to the Free Software
25// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
28#include "PTextBox.h"
29#include "PFont.h"
30#include "../utility/rc_ptrs.h"
31#include "../utility/PEBLUtility.h"
32#include "../devices/PKeyboard.h"
33#include "../libs/PEBLEnvironment.h"
34#include "../../libs/utfcpp/source/utf8.h"
35
36
37//#include "SDL/SDL.h" //For Uint16 only
38#include <iostream>
39
40using std::cout;
41using std::endl;
42
44 PTextObject(""),
45 mEditable(false),
46 mCursorPos(0),
47 mCursorChanged(true),
48 mLineWrap(true),
49 mJustify(1)
50{
51 InitializeProperty("TEXT",Variant(""));
52 InitializeProperty("WIDTH",Variant(0));
53 InitializeProperty("HEIGHT",Variant(0));
54 InitializeProperty("EDITABLE",Variant(false));
55 InitializeProperty("CURSORPOS",Variant(0));
56 InitializeProperty("NAME",Variant("<TEXTBOX>"));
57 InitializeProperty("LINEWRAP",Variant(1));
58 InitializeProperty("LINEHEIGHT",Variant(0));
59 InitializeProperty("NUMTEXTLINES",Variant(0));
60 InitializeProperty("TEXTCOMPLETE",Variant(0));
61 InitializeProperty("JUSTIFY",Variant("LEFT"));
62 InitializeProperty("ISADAPTIVE",Variant(false));
63 InitializeProperty("ADAPTIVEMODE",Variant("scalefont"));
64 InitializeProperty("REQUESTEDFONTSIZE",Variant(0));
65 InitializeProperty("FORMATTED",Variant(0));
66}
67
68
69
70PTextBox::PTextBox(std::string text, int width, int height):
71 PTextObject(text),
72 mEditable(false),
73 mCursorPos(0),
74 mCursorChanged(true),
75 mLineWrap(true),
76 mJustify(1)
77{
78 InitializeProperty("TEXT",Variant(text));
79 InitializeProperty("WIDTH",Variant(width));
80 InitializeProperty("HEIGHT",Variant(height));
81 InitializeProperty("EDITABLE",Variant(false));
82 InitializeProperty("CURSORPOS",Variant(0));
83 InitializeProperty("NAME",Variant("<TEXTBOX>"));
84 InitializeProperty("LINEWRAP",Variant(1));
85 InitializeProperty("LINEHEIGHT",Variant(0));
86 InitializeProperty("NUMTEXTLINES",Variant(0));
87 InitializeProperty("TEXTCOMPLETE",Variant(0));
88 InitializeProperty("JUSTIFY",Variant("LEFT"));
89 InitializeProperty("ISADAPTIVE",Variant(false));
90 InitializeProperty("ADAPTIVEMODE",Variant("scalefont"));
91 InitializeProperty("REQUESTEDFONTSIZE",Variant(0));
92 InitializeProperty("FORMATTED",Variant(0));
93}
94
95
97 PTextObject(text.GetText()),
98 mEditable(false),
99 mCursorPos(0),
100 mCursorChanged(true),
101 mLineWrap(true),
102 mJustify(1)
103{
104 mChanged = true;
105 InitializeProperty("NAME",Variant("<TEXTBOX>"));
106 InitializeProperty("LINEWRAP",Variant(1));
107 InitializeProperty("LINEHEIGHT",Variant(0));
108 InitializeProperty("NUMTEXTLINES",Variant(0));
109 InitializeProperty("TEXTCOMPLETE",Variant(0));
110 InitializeProperty("JUSTIFY",Variant("LEFT"));
111 InitializeProperty("ISADAPTIVE",Variant(false));
112 InitializeProperty("ADAPTIVEMODE",Variant("scalefont"));
113 InitializeProperty("REQUESTEDFONTSIZE",Variant(0));
114 InitializeProperty("FORMATTED",Variant(0));
115}
116
120
121
122
123
124bool PTextBox::SetProperty(std::string name, Variant v)
125{
126
127 if(PTextObject::SetProperty(name,v))
128 {
129 // If we set it at higher level, don't worry.
130 }
131 else if(name =="WIDTH") SetWidth(v);
132 else if(name == "HEIGHT") SetHeight(v);
133 else if(name == "TEXT"){
134 SetText(v.GetString());
135 mCursorChanged=true;
136 mChanged=true;}
137 else if(name == "EDITABLE")SetEditable(v);
138 else if(name == "CURSORPOS") SetCursorPosition(v);
139 else if(name == "LINEWRAP") SetLineWrap(v);
140 else if(name == "JUSTIFY") SetJustify(v);
141 else if(name == "ISADAPTIVE" || name == "ADAPTIVEMODE" || name == "REQUESTEDFONTSIZE" || name == "FORMATTED") {
142 // These properties are stored only in the property system
143 // Adaptive scaling is handled in PEBL code (UI.pbl)
144 // Formatted text rendering is handled in PlatformTextBox
145 // Store the property value and mark as changed
147 mChanged = true;
148 }
149 else return false;
150 return true;
151}
152
153
154Variant PTextBox::GetProperty(std::string name)const
155{
156 return PTextObject::GetProperty(name);
157}
158
159
161{
162
163 if(name == "JUSTIFY")
164 {
165 if(v=="LEFT" | v == "RIGHT" | v == "CENTER")
166 {
167 return OVE_VALID;
168 }else
169 {
171 }
172 }
173 return ValidateProperty(name);
174}
175
177{
178 if(name == "CURSORPOS"| name=="LINEWRAP"| name == "JUSTIFY" | name == "NUMTEXTLINES" | name == "TEXTCOMPLETE" | name == "ISADAPTIVE" | name == "ADAPTIVEMODE" | name == "REQUESTEDFONTSIZE" | name == "FORMATTED")
179 return OVE_VALID;
180 else
182}
183
184
185
186
187//Inserts text at cursor
188//this is sort of broken when char=10 (newline) is inserted.
189void PTextBox::InsertText(const std::string text)
190{
191
192
193 if(mCursorPos>mText.length())
194 mCursorPos=mText.length();
195
196 mText.insert(mCursorPos, text);
197 mCursorPos += text.length();
198
199 mChanged= true;
200 mCursorChanged = true;
201 SetProperty("TEXT",mText);
202
203}
204
205//Deletes text at cursor. negative numbers indicate
206//before the cursor. Length should be the number of characters;
207//not the number of bytes, so we need to delete entire unicode characters
208//all at once.
209
210void PTextBox::DeleteText(int length)
211{
212
213 int count = 0;
214 int bytecount = 1;
215
216 if(length > 0)
217 {
218
219 std::string::iterator start = mText.begin();
220 std::string::iterator end = start+mCursorPos+1;
221
222 while(count < length)
223 {
224
225 while(!utf8::is_valid(start,end) && end < mText.end())
226 {
227
228 end++;
229 bytecount++;
230 }
231 count++;
232 bytecount++;
233 }
234
235 //We need to watch deleting at the end. If we try to bite off too much at
236 //the end, just don't do it.
237 if(bytecount+mCursorPos<mText.length())
238 {
239 mText.erase(mCursorPos, bytecount-1);
240 mChanged= true;
241 }
242 }
243 else if (length < 0)
244 {
245
246 //Delete before the cursor.
247 std::string::iterator start = mText.begin();
248 std::string::iterator end = start+mCursorPos-1;
249
250
251 //Delete before the cursor.
252 while(count < (-length))
253 {
254
255 //crash happens here when deleting from the beginning
256
257
258
259 while(!utf8::is_valid(start,end) && start < end)
260 {
261
262 bytecount++;
263 end--; //delete backward to the end of the remaining
264
265 }
266 count++;
267 bytecount++;
268 }
269
270
271 bytecount--; //back off one byte because it got double-incremented
272
273
274 if((int)mCursorPos - bytecount < 0)
275 {
276
277 mText.erase(0,mCursorPos);
278 mChanged= true;
279 mCursorPos = 0;
280
281 }
282 else
283 {
284
285 mText.erase(mCursorPos-bytecount, bytecount);
286 mChanged= true;
287 mCursorPos -= bytecount;
288
289 }
290 }
291
292 SetProperty("TEXT",mText);
293}
294
295long unsigned int PTextBox::IncrementCursor()
296{
297
298
299 //this just checks for end-of-line stuff.
300 if(0)
301 {
302 mCursorPos ++;
303 }
304 else
305 {
306
307
308 if(mCursorPos > (int)(mText.length()))
309 mCursorPos = mText.length();
310
311
312
313 bool cont = true;
314 std::string::iterator start = mText.begin()+mCursorPos;
315 std::string::iterator end = start+1;
316 mCursorPos++;
317
318 while(!utf8::is_valid(start,end))
319 {
320
321 mCursorPos += 1;
322 end++;
323 }
324
325 }
326
327
328 mCursorChanged = true;
329
330
331 return mCursorPos;
332}
333
334long unsigned int PTextBox::DecrementCursor()
335{
336
337
338 if(mCursorPos>=1)
339 {
340
341
342 bool cont = true;
343 std::string::iterator start = mText.begin()+mCursorPos;
344 std::string::iterator end = start;
345 mCursorPos--;
346 start--;
347 while(!utf8::is_valid(start,end))
348 {
349 mCursorPos -= 1;
350 start--;
351 }
352
353 }
354
355
356// if(AtPrintableCharacter(mCursorPos -1))
357// mCursorPos --;
358// else
359// mCursorPos -= 1;
360
361 mCursorChanged = true;
362 return mCursorPos;
363}
364
365//These shadow higher accessors in widget, because
366//they need to set the textchanged flag
368{
369 mHeight = h;
370 mChanged = true;
371}
372
374{
375 mWidth = w;
376 mChanged = true;
377}
378
379
380void PTextBox::SetLineWrap(bool state)
381{
382 mLineWrap = state;
383}
384
385
387{
388
389 mJustify =j;
390 mChanged = true;
391}
392
393
394void PTextBox::HandleKeyPress(int keycode, int modkeys, Uint16 unicode)
395{
396
397 //First, handle special keys
398 switch(keycode)
399 {
400#if 0
401 if(0)
402 {
404 }
405#endif
406 break;
407 }
408 mCursorChanged=true;
409}
410
411
412//This will handle entry of processed text; not just
413//keystrokes, to enable 'modrin' keyboarding.
414void PTextBox::HandleTextInput(std::string text)
415{
416
417
418 InsertText(text);
419 //we may need to adjust cursor position.
420 mCursorChanged=true;
421}
422
423
424bool PTextBox::AtPrintableCharacter(unsigned long int x)
425{
426 unsigned long int pos=x;
427
428 if(x> mText.length())
429 pos = mText.length();
430
431 if (mText[pos] == 10
432 || mText[pos] == 13
433 || mText[pos] == 18
434 )
435 return false;
436 else
437 return true;
438}
439
440
441std::string PTextBox::ObjectName()const
442{
443 return "TextBox";
444}
ObjectValidationError
Definition PEBLObject.h:37
@ OVE_INVALID_PROPERTY_VALUE
Definition PEBLObject.h:42
@ OVE_VALID
Definition PEBLObject.h:39
PEBL_Keycode
Definition PKeyboard.h:78
virtual bool InitializeProperty(std::string name, Variant v)
virtual bool SetProperty(std::string name, Variant v)
This class is the basic generic text box.
Definition PTextBox.h:40
virtual void HandleTextInput(std::string text)
Definition PTextBox.cpp:414
virtual long unsigned int IncrementCursor()
Definition PTextBox.cpp:295
virtual void InsertText(const std::string character)
Definition PTextBox.cpp:189
virtual ~PTextBox()
Definition PTextBox.cpp:117
virtual std::string ObjectName() const
Definition PTextBox.cpp:441
virtual void HandleKeyPress(int keycode, int modkeys, Uint16 unicode)
Definition PTextBox.cpp:394
virtual void SetJustify(Variant j)
Definition PTextBox.cpp:386
virtual void SetWidth(int w)
Definition PTextBox.cpp:373
virtual long unsigned int DecrementCursor()
Definition PTextBox.cpp:334
Variant mJustify
Definition PTextBox.h:94
virtual bool AtPrintableCharacter(unsigned long int x)
Definition PTextBox.cpp:424
virtual ObjectValidationError ValidateProperty(std::string, Variant v) const
Definition PTextBox.cpp:160
virtual bool SetProperty(std::string, Variant v)
Definition PTextBox.cpp:124
unsigned long int mCursorPos
Definition PTextBox.h:91
virtual void SetCursorPosition(unsigned long int pos)
Definition PTextBox.h:64
virtual void SetLineWrap(bool state)
Definition PTextBox.cpp:380
virtual void SetEditable(bool val)
Definition PTextBox.h:61
virtual void SetHeight(int h)
Definition PTextBox.cpp:367
bool mLineWrap
Definition PTextBox.h:93
virtual Variant GetProperty(std::string) const
Definition PTextBox.cpp:154
bool mCursorChanged
Definition PTextBox.h:92
virtual void DeleteText(int length)
Definition PTextBox.cpp:210
This class simply represent an abstract text-based object.
Definition PTextObject.h:41
virtual ObjectValidationError ValidateProperty(std::string, Variant v) const
virtual bool SetProperty(std::string, Variant v)
std::string mText
Definition PTextObject.h:70
virtual Variant GetProperty(std::string) const
virtual void SetText(const std::string &text)
pInt mWidth
Definition PWidget.h:136
pInt mHeight
Definition PWidget.h:136
std::string GetString() const
Definition Variant.cpp:1056
std::string TranslateKeycode(const PEBL_Keycode key, int modkeys)
int count
Definition test.cpp:12