blob: 299034a2c73ab995f86f3d164d2404a63c07ee45 [file] [log] [blame]
Dees Troy3be70a82013-10-22 14:25:12 +00001/*
2 Copyright 2012 bigbiff/Dees_Troy TeamWin
3 This file is part of TWRP/TeamWin Recovery Project.
4
5 TWRP is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 TWRP is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with TWRP. If not, see <http://www.gnu.org/licenses/>.
17*/
18
Dees_Troy51a0e822012-09-05 15:24:24 -040019// input.cpp - GUIInput object
20
21#include <linux/input.h>
22#include <pthread.h>
23#include <stdarg.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <fcntl.h>
28#include <sys/reboot.h>
29#include <sys/stat.h>
30#include <sys/time.h>
31#include <sys/mman.h>
32#include <sys/types.h>
33#include <sys/ioctl.h>
34#include <time.h>
35#include <unistd.h>
36#include <stdlib.h>
37
38#include <string>
39
40extern "C" {
Dees_Troy2673cec2013-04-02 20:22:16 +000041#include "../twcommon.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040042#include "../minuitwrp/minui.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040043}
44
45#include "rapidxml.hpp"
46#include "objects.hpp"
47#include "../data.hpp"
48
49GUIInput::GUIInput(xml_node<>* node)
Vojtech Bocekede51c52014-02-07 23:58:09 +010050 : GUIObject(node)
Dees_Troy51a0e822012-09-05 15:24:24 -040051{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020052 xml_attribute<>* attr;
53 xml_node<>* child;
Dees_Troy51a0e822012-09-05 15:24:24 -040054
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020055 mInputText = NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -040056 mAction = NULL;
57 mBackground = NULL;
58 mCursor = NULL;
59 mFont = NULL;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020060 mRendered = false;
Dees_Troy51a0e822012-09-05 15:24:24 -040061 HasMask = false;
62 DrawCursor = false;
63 isLocalChange = true;
64 HasAllowed = false;
65 HasDisabled = false;
66 skipChars = scrollingX = mFontHeight = mFontY = lastX = 0;
67 mBackgroundX = mBackgroundY = mBackgroundW = mBackgroundH = MinLen = MaxLen = 0;
68 mCursorLocation = -1; // -1 is always the end of the string
69 CursorWidth = 3;
70 ConvertStrToColor("black", &mBackgroundColor);
71 ConvertStrToColor("white", &mCursorColor);
72
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020073 if (!node)
74 return;
Dees_Troy51a0e822012-09-05 15:24:24 -040075
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020076 // Load text directly from the node
77 mInputText = new GUIText(node);
Dees_Troy51a0e822012-09-05 15:24:24 -040078 // Load action directly from the node
79 mAction = new GUIAction(node);
80
81 if (mInputText->Render() < 0)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020082 {
83 delete mInputText;
84 mInputText = NULL;
85 }
Dees_Troy51a0e822012-09-05 15:24:24 -040086
87 // Load the background
88 child = node->first_node("background");
89 if (child)
90 {
thatf6ed8fc2015-02-14 20:23:16 +010091 mBackground = LoadAttrImage(child, "resource");
92 mBackgroundColor = LoadAttrColor(child, "color", mBackgroundColor);
Dees_Troy51a0e822012-09-05 15:24:24 -040093 }
94 if (mBackground && mBackground->GetResource())
95 {
thatf6ed8fc2015-02-14 20:23:16 +010096 mBackgroundW = mBackground->GetWidth();
97 mBackgroundH = mBackground->GetHeight();
Dees_Troy51a0e822012-09-05 15:24:24 -040098 }
99
100 // Load the cursor color
101 child = node->first_node("cursor");
102 if (child)
103 {
thatf6ed8fc2015-02-14 20:23:16 +0100104 mCursor = LoadAttrImage(child, "resource");
105 mCursorColor = LoadAttrColor(child, "color", mCursorColor);
Dees_Troy51a0e822012-09-05 15:24:24 -0400106 attr = child->first_attribute("hasfocus");
107 if (attr)
108 {
109 std::string color = attr->value();
110 SetInputFocus(atoi(color.c_str()));
111 }
112 attr = child->first_attribute("width");
113 if (attr)
114 {
115 std::string cwidth = gui_parse_text(attr->value());
Ethan Yonker63e414f2015-02-06 15:44:39 -0600116 CursorWidth = scale_theme_x(atoi(cwidth.c_str()));
Dees_Troy51a0e822012-09-05 15:24:24 -0400117 }
118 }
119 DrawCursor = HasInputFocus;
120
thatf6ed8fc2015-02-14 20:23:16 +0100121 // Load the font
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200122 child = node->first_node("font");
123 if (child)
124 {
thatf6ed8fc2015-02-14 20:23:16 +0100125 mFont = LoadAttrFont(child, "resource");
126 mFontHeight = mFont->GetHeight();
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200127 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400128
129 child = node->first_node("text");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200130 if (child) mText = child->value();
Dees_Troy51a0e822012-09-05 15:24:24 -0400131 mLastValue = gui_parse_text(mText);
132
133 child = node->first_node("data");
134 if (child)
135 {
136 attr = child->first_attribute("name");
137 if (attr)
138 mVariable = attr->value();
139 attr = child->first_attribute("default");
140 if (attr)
141 DataManager::SetValue(mVariable, attr->value());
142 attr = child->first_attribute("mask");
143 if (attr) {
144 mMask = attr->value();
145 HasMask = true;
146 }
147 attr = child->first_attribute("maskvariable");
148 if (attr)
149 mMaskVariable = attr->value();
150 else
151 mMaskVariable = mVariable;
152 }
153
154 // Load input restrictions
155 child = node->first_node("restrict");
156 if (child)
157 {
158 attr = child->first_attribute("minlen");
159 if (attr) {
160 std::string attrib = attr->value();
161 MinLen = atoi(attrib.c_str());
162 }
163 attr = child->first_attribute("maxlen");
164 if (attr) {
165 std::string attrib = attr->value();
166 MaxLen = atoi(attrib.c_str());
167 }
168 attr = child->first_attribute("allow");
169 if (attr) {
170 HasAllowed = true;
171 AllowedList = attr->value();
172 }
173 attr = child->first_attribute("disable");
174 if (attr) {
175 HasDisabled = true;
176 DisabledList = attr->value();
177 }
178 }
179
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200180 // Load the placement
Dees_Troy51a0e822012-09-05 15:24:24 -0400181 LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH);
182 SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
183
184 if (mInputText && mFontHeight && mFontHeight < (unsigned)mRenderH) {
185 mFontY = ((mRenderH - mFontHeight) / 2) + mRenderY;
186 mInputText->SetRenderPos(mRenderX, mFontY);
187 } else
188 mFontY = mRenderY;
189
190 if (mInputText)
191 mInputText->SetMaxWidth(mRenderW);
192
193 isLocalChange = false;
194 HandleTextLocation(-3);
Dees_Troy51a0e822012-09-05 15:24:24 -0400195}
196
197GUIInput::~GUIInput()
198{
thatf6ed8fc2015-02-14 20:23:16 +0100199 delete mInputText;
200 delete mAction;
Dees_Troy51a0e822012-09-05 15:24:24 -0400201}
202
203int GUIInput::HandleTextLocation(int x)
204{
205 int textWidth;
206 string displayValue, originalValue, insertChar;
207 void* fontResource = NULL;
208
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200209 if (mFont)
210 fontResource = mFont->GetResource();
Dees_Troy51a0e822012-09-05 15:24:24 -0400211
212 DataManager::GetValue(mVariable, originalValue);
213 displayValue = originalValue;
214 if (HasMask) {
215 int index, string_size = displayValue.size();
216 string maskedValue;
217 for (index=0; index<string_size; index++)
218 maskedValue += mMask;
219 displayValue = maskedValue;
220 }
221 textWidth = gr_measureEx(displayValue.c_str(), fontResource);
222 if (textWidth <= mRenderW) {
223 lastX = x;
224 scrollingX = 0;
225 skipChars = 0;
226 mInputText->SkipCharCount(skipChars);
227 mRendered = false;
228 return 0;
229 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200230
231 if (skipChars && skipChars < displayValue.size())
Dees_Troy51a0e822012-09-05 15:24:24 -0400232 displayValue.erase(0, skipChars);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200233
Dees_Troy51a0e822012-09-05 15:24:24 -0400234 textWidth = gr_measureEx(displayValue.c_str(), fontResource);
235 mRendered = false;
236
237 int deltaX, deltaText, newWidth;
238
239 if (x < -1000) {
240 // No change in scrolling
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200241 if (x == -1003)
Dees_Troy51a0e822012-09-05 15:24:24 -0400242 mCursorLocation = -1;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200243
Dees_Troy51a0e822012-09-05 15:24:24 -0400244 if (mCursorLocation == -1) {
245 displayValue = originalValue;
246 skipChars = 0;
247 textWidth = gr_measureEx(displayValue.c_str(), fontResource);
248 while (textWidth > mRenderW) {
249 displayValue.erase(0, 1);
250 skipChars++;
251 textWidth = gr_measureEx(displayValue.c_str(), fontResource);
252 }
253 scrollingX = mRenderW - textWidth;
254 mInputText->SkipCharCount(skipChars);
255 } else if (x == -1001) {
256 // Added a new character
257 int adjust_scrollingX = 0;
258 string cursorLocate;
259
260 cursorLocate = displayValue;
261 cursorLocate.resize(mCursorLocation);
262 textWidth = gr_measureEx(cursorLocate.c_str(), fontResource);
263 while (textWidth > mRenderW) {
264 skipChars++;
265 mCursorLocation--;
266 cursorLocate.erase(0, 1);
267 textWidth = gr_measureEx(cursorLocate.c_str(), fontResource);
268 adjust_scrollingX = -1;
269 }
270 if (adjust_scrollingX) {
271 scrollingX = mRenderW - textWidth;
272 if (scrollingX < 0)
273 scrollingX = 0;
274 }
275 mInputText->SkipCharCount(skipChars);
276 } else if (x == -1002) {
277 // Deleted a character
278 while (-1) {
279 if (skipChars == 0) {
280 scrollingX = 0;
281 mInputText->SkipCharCount(skipChars);
282 return 0;
283 }
284 insertChar = originalValue.substr(skipChars - 1, 1);
285 displayValue.insert(0, insertChar);
286 newWidth = gr_measureEx(displayValue.c_str(), fontResource);
287 deltaText = newWidth - textWidth;
288 if (newWidth > mRenderW) {
289 scrollingX = mRenderW - textWidth;
290 if (scrollingX < 0)
291 scrollingX = 0;
292 mInputText->SkipCharCount(skipChars);
293 return 0;
294 } else {
295 textWidth = newWidth;
296 skipChars--;
297 mCursorLocation++;
298 }
299 }
300 } else
Dees_Troy2673cec2013-04-02 20:22:16 +0000301 LOGINFO("GUIInput::HandleTextLocation -> We really shouldn't ever get here...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400302 } else if (x > lastX) {
303 // Dragging to right, scrolling left
304 while (-1) {
305 deltaX = x - lastX + scrollingX;
306 if (skipChars == 0 || deltaX == 0) {
307 scrollingX = 0;
308 lastX = x;
309 mInputText->SkipCharCount(skipChars);
310 return 0;
311 }
312 insertChar = originalValue.substr(skipChars - 1, 1);
313 displayValue.insert(0, insertChar);
314 newWidth = gr_measureEx(displayValue.c_str(), fontResource);
315 deltaText = newWidth - textWidth;
316 if (deltaText < deltaX) {
317 lastX += deltaText;
318 textWidth = newWidth;
319 skipChars--;
320 } else {
321 scrollingX = deltaX;
322 lastX = x;
323 mInputText->SkipCharCount(skipChars);
324 return 0;
325 }
326 }
327 } else if (x < lastX) {
328 // Dragging to left, scrolling right
329 if (textWidth <= mRenderW) {
330 lastX = x;
331 scrollingX = mRenderW - textWidth;
332 return 0;
333 }
334 if (scrollingX) {
335 deltaX = lastX - x;
336 if (scrollingX > deltaX) {
337 scrollingX -= deltaX;
338 lastX = x;
339 return 0;
340 } else {
341 lastX -= deltaX;
342 scrollingX = 0;
343 }
344 }
345 while (-1) {
346 deltaX = lastX - x;
347 displayValue.erase(0, 1);
348 skipChars++;
349 newWidth = gr_measureEx(displayValue.c_str(), fontResource);
350 deltaText = textWidth - newWidth;
351 if (newWidth <= mRenderW) {
352 scrollingX = mRenderW - newWidth;
353 lastX = x;
354 mInputText->SkipCharCount(skipChars);
355 return 0;
356 }
357 if (deltaText < deltaX) {
358 lastX -= deltaText;
359 textWidth = newWidth;
360 } else {
361 scrollingX = deltaText - deltaX;
362 lastX = x;
363 mInputText->SkipCharCount(skipChars);
364 return 0;
365 }
366 }
367 }
368 return 0;
369}
370
371int GUIInput::Render(void)
372{
373 if (!isConditionTrue())
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200374 {
375 mRendered = false;
376 return 0;
377 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400378
379 void* fontResource = NULL;
380 if (mFont) fontResource = mFont->GetResource();
381
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200382 // First step, fill background
Dees_Troy51a0e822012-09-05 15:24:24 -0400383 gr_color(mBackgroundColor.red, mBackgroundColor.green, mBackgroundColor.blue, 255);
384 gr_fill(mRenderX, mRenderY, mRenderW, mRenderH);
385
386 // Next, render the background resource (if it exists)
387 if (mBackground && mBackground->GetResource())
388 {
389 mBackgroundX = mRenderX + ((mRenderW - mBackgroundW) / 2);
390 mBackgroundY = mRenderY + ((mRenderH - mBackgroundH) / 2);
391 gr_blit(mBackground->GetResource(), 0, 0, mBackgroundW, mBackgroundH, mBackgroundX, mBackgroundY);
392 }
393
394 int ret = 0;
395
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200396 // Render the text
Dees_Troy51a0e822012-09-05 15:24:24 -0400397 mInputText->SetRenderPos(mRenderX + scrollingX, mFontY);
398 mInputText->SetMaxWidth(mRenderW - scrollingX);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200399 if (mInputText) ret = mInputText->Render();
400 if (ret < 0) return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400401
402 if (HasInputFocus && DrawCursor) {
403 // Render the cursor
404 string displayValue;
405 int cursorX;
406 DataManager::GetValue(mVariable, displayValue);
407 if (HasMask) {
408 int index, string_size = displayValue.size();
409 string maskedValue;
410 for (index=0; index<string_size; index++)
411 maskedValue += mMask;
412 displayValue = maskedValue;
413 }
414 if (displayValue.size() == 0) {
415 skipChars = 0;
416 mCursorLocation = -1;
417 cursorX = mRenderX;
418 } else {
419 if (skipChars && skipChars < displayValue.size()) {
420 displayValue.erase(0, skipChars);
421 }
422 if (mCursorLocation == 0) {
423 // Cursor is at the beginning
424 cursorX = mRenderX;
425 } else if (mCursorLocation > 0) {
426 // Cursor is in the middle
427 if (displayValue.size() > (unsigned)mCursorLocation) {
428 string cursorDisplay;
429
430 cursorDisplay = displayValue;
431 cursorDisplay.resize(mCursorLocation);
432 cursorX = gr_measureEx(cursorDisplay.c_str(), fontResource) + mRenderX;
433 } else {
434 // Cursor location is after the end of the text - reset to -1
435 mCursorLocation = -1;
436 cursorX = gr_measureEx(displayValue.c_str(), fontResource) + mRenderX;
437 }
438 } else {
439 // Cursor is at the end (-1)
440 cursorX = gr_measureEx(displayValue.c_str(), fontResource) + mRenderX;
441 }
442 }
443 cursorX += scrollingX;
444 // Make sure that the cursor doesn't go past the boundaries of the box
445 if (cursorX + (int)CursorWidth > mRenderX + mRenderW)
446 cursorX = mRenderX + mRenderW - CursorWidth;
447
448 // Set the color for the cursor
449 gr_color(mCursorColor.red, mCursorColor.green, mCursorColor.blue, 255);
450 gr_fill(cursorX, mFontY, CursorWidth, mFontHeight);
451 }
452
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200453 mRendered = true;
454 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400455}
456
457int GUIInput::Update(void)
458{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200459 if (!isConditionTrue()) return (mRendered ? 2 : 0);
460 if (!mRendered) return 2;
Dees_Troy51a0e822012-09-05 15:24:24 -0400461
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200462 int ret = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400463
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200464 if (mInputText) ret = mInputText->Update();
465 if (ret < 0) return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400466
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200467 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400468}
469
470int GUIInput::GetSelection(int x, int y)
471{
472 if (x < mRenderX || x - mRenderX > mRenderW || y < mRenderY || y - mRenderY > mRenderH) return -1;
473 return (x - mRenderX);
474}
475
476int GUIInput::NotifyTouch(TOUCH_STATE state, int x, int y)
477{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200478 static int startSelection = -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400479 int textWidth;
480 string displayValue, originalValue;
481 void* fontResource = NULL;
482
483 if (mFont) fontResource = mFont->GetResource();
484
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200485 if (!isConditionTrue())
486 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400487
488 if (!HasInputFocus) {
489 if (state != TOUCH_RELEASE)
490 return 0; // Only change focus if touch releases within the input box
491 if (GetSelection(x, y) >= 0) {
492 // When changing focus, we don't scroll or change the cursor location
493 PageManager::SetKeyBoardFocus(0);
494 PageManager::NotifyKeyboard(0);
495 SetInputFocus(1);
496 DrawCursor = true;
497 mRendered = false;
498 }
499 } else {
500 switch (state) {
501 case TOUCH_HOLD:
502 case TOUCH_REPEAT:
503 break;
504 case TOUCH_START:
505 startSelection = GetSelection(x,y);
506 lastX = x;
507 DrawCursor = false;
508 mRendered = false;
509 break;
510
511 case TOUCH_DRAG:
512 // Check if we dragged out of the selection window
513 if (GetSelection(x, y) == -1) {
514 lastX = 0;
515 break;
516 }
517
518 DrawCursor = false;
519
520 // Provide some debounce on initial touches
521 if (startSelection != -1 && abs(x - lastX) < 6) {
522 break;
523 }
524
525 startSelection = -1;
526 if (lastX != x)
527 HandleTextLocation(x);
528 break;
529
530 case TOUCH_RELEASE:
531 // We've moved the cursor location
532 int relativeX = x - mRenderX;
533
534 mRendered = false;
535 DrawCursor = true;
536 DataManager::GetValue(mVariable, displayValue);
537 if (HasMask) {
538 int index, string_size = displayValue.size();
539 string maskedValue;
540 for (index=0; index<string_size; index++)
541 maskedValue += mMask;
542 displayValue = maskedValue;
543 }
544 if (displayValue.size() == 0) {
545 skipChars = 0;
546 mCursorLocation = -1;
547 return 0;
548 } else if (skipChars && skipChars < displayValue.size()) {
549 displayValue.erase(0, skipChars);
550 }
551
552 string cursorString;
553 int cursorX = 0;
554 unsigned index = 0;
555
556 for(index=0; index<displayValue.size(); index++)
557 {
558 cursorString = displayValue.substr(0, index);
559 cursorX = gr_measureEx(cursorString.c_str(), fontResource) + mRenderX;
560 if (cursorX > x) {
561 if (index > 0)
562 mCursorLocation = index - 1;
563 else
564 mCursorLocation = index;
565 return 0;
566 }
567 }
568 mCursorLocation = -1;
569 break;
570 }
571 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200572 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400573}
574
Vojtech Bocek07220562014-02-08 02:05:33 +0100575int GUIInput::NotifyVarChange(const std::string& varName, const std::string& value)
Dees_Troy51a0e822012-09-05 15:24:24 -0400576{
Vojtech Bocek07220562014-02-08 02:05:33 +0100577 GUIObject::NotifyVarChange(varName, value);
578
Dees_Troy51a0e822012-09-05 15:24:24 -0400579 if (varName == mVariable && !isLocalChange) {
580 HandleTextLocation(-1003);
581 return 0;
582 }
583 return 0;
584}
585
586int GUIInput::NotifyKeyboard(int key)
587{
588 string variableValue;
589
590 if (HasInputFocus) {
591 if (key == KEYBOARD_BACKSPACE) {
592 //Backspace
593 DataManager::GetValue(mVariable, variableValue);
594 if (variableValue.size() > 0 && (mCursorLocation + skipChars != 0 || mCursorLocation == -1)) {
595 if (mCursorLocation == -1) {
596 variableValue.resize(variableValue.size() - 1);
597 } else {
598 variableValue.erase(mCursorLocation + skipChars - 1, 1);
599 if (mCursorLocation > 0)
600 mCursorLocation--;
601 else if (skipChars > 0)
602 skipChars--;
603 }
604 isLocalChange = true;
605 DataManager::SetValue(mVariable, variableValue);
606 isLocalChange = false;
607
608 if (HasMask) {
609 int index, string_size = variableValue.size();
610 string maskedValue;
611 for (index=0; index<string_size; index++)
612 maskedValue += mMask;
613 DataManager::SetValue(mMaskVariable, maskedValue);
614 }
615 HandleTextLocation(-1002);
616 }
617 } else if (key == KEYBOARD_SWIPE_LEFT) {
618 // Delete all
619 isLocalChange = true;
620 if (mCursorLocation == -1) {
621 DataManager::SetValue (mVariable, "");
622 if (HasMask)
623 DataManager::SetValue(mMaskVariable, "");
624 mCursorLocation = -1;
625 } else {
626 DataManager::GetValue(mVariable, variableValue);
627 variableValue.erase(0, mCursorLocation + skipChars);
628 DataManager::SetValue(mVariable, variableValue);
629 if (HasMask) {
630 DataManager::GetValue(mMaskVariable, variableValue);
631 variableValue.erase(0, mCursorLocation + skipChars);
632 DataManager::SetValue(mMaskVariable, variableValue);
633 }
634 mCursorLocation = 0;
635 }
636 skipChars = 0;
637 scrollingX = 0;
638 mInputText->SkipCharCount(skipChars);
639 isLocalChange = false;
640 mRendered = false;
641 return 0;
642 } else if (key == KEYBOARD_ARROW_LEFT) {
643 if (mCursorLocation == 0 && skipChars == 0)
644 return 0; // we're already at the beginning
645 if (mCursorLocation == -1) {
646 DataManager::GetValue(mVariable, variableValue);
647 if (variableValue.size() == 0)
648 return 0;
649 mCursorLocation = variableValue.size() - skipChars - 1;
650 } else if (mCursorLocation == 0) {
651 skipChars--;
652 HandleTextLocation(-1002);
653 } else {
654 mCursorLocation--;
655 HandleTextLocation(-1002);
656 }
657 mRendered = false;
658 return 0;
659 } else if (key == KEYBOARD_ARROW_RIGHT) {
660 if (mCursorLocation == -1)
661 return 0; // we're already at the end
662 mCursorLocation++;
663 DataManager::GetValue(mVariable, variableValue);
664 if (variableValue.size() <= mCursorLocation + skipChars)
665 mCursorLocation = -1;
666 HandleTextLocation(-1001);
667 mRendered = false;
668 return 0;
669 } else if (key == KEYBOARD_HOME || key == KEYBOARD_ARROW_UP) {
670 DataManager::GetValue(mVariable, variableValue);
671 if (variableValue.size() == 0)
672 return 0;
673 mCursorLocation = 0;
674 skipChars = 0;
675 mRendered = false;
676 HandleTextLocation(-1002);
677 return 0;
678 } else if (key == KEYBOARD_END || key == KEYBOARD_ARROW_DOWN) {
679 mCursorLocation = -1;
680 mRendered = false;
681 HandleTextLocation(-1003);
682 return 0;
683 } else if (key < KEYBOARD_SPECIAL_KEYS && key > 0) {
684 // Regular key
685 if (HasAllowed && AllowedList.find((char)key) == string::npos) {
686 return 0;
687 }
688 if (HasDisabled && DisabledList.find((char)key) != string::npos) {
689 return 0;
690 }
691 DataManager::GetValue(mVariable, variableValue);
692 if (MaxLen != 0 && variableValue.size() >= MaxLen) {
693 return 0;
694 }
695 if (mCursorLocation == -1) {
696 variableValue += key;
697 } else {
that5fa54ce2015-02-01 16:15:29 +0100698 variableValue.insert(mCursorLocation + skipChars, 1, key);
Dees_Troy51a0e822012-09-05 15:24:24 -0400699 mCursorLocation++;
700 }
701 isLocalChange = true;
702 DataManager::SetValue(mVariable, variableValue);
703 HandleTextLocation(-1001);
704 isLocalChange = false;
705
706 if (HasMask) {
707 int index, string_size = variableValue.size();
708 string maskedValue;
709 for (index=0; index<string_size; index++)
710 maskedValue += mMask;
711 DataManager::SetValue(mMaskVariable, maskedValue);
712 }
713 } else if (key == KEYBOARD_ACTION) {
714 // Action
715 DataManager::GetValue(mVariable, variableValue);
716 if (mAction) {
717 unsigned inputLen = variableValue.length();
718 if (inputLen < MinLen)
719 return 0;
720 else if (MaxLen != 0 && inputLen > MaxLen)
721 return 0;
722 else
723 return (mAction ? mAction->NotifyTouch(TOUCH_RELEASE, mRenderX, mRenderY) : 1);
724 }
725 }
726 return 0;
727 } else {
728 if (key == 0) {
729 // Somewhat ugly hack-ish way to tell the box to redraw after losing focus to remove the cursor
730 mRendered = false;
731 return 1;
732 }
733 }
734 return 1;
735}