blob: 21b1f0b86a549676b28bc20d634eafac3d51bade [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 {
91 attr = child->first_attribute("resource");
92 if (attr)
93 mBackground = PageManager::FindResource(attr->value());
94 attr = child->first_attribute("color");
95 if (attr)
96 {
97 std::string color = attr->value();
98 ConvertStrToColor(color, &mBackgroundColor);
99 }
100 }
101 if (mBackground && mBackground->GetResource())
102 {
103 mBackgroundW = gr_get_width(mBackground->GetResource());
104 mBackgroundH = gr_get_height(mBackground->GetResource());
105 }
106
107 // Load the cursor color
108 child = node->first_node("cursor");
109 if (child)
110 {
111 attr = child->first_attribute("resource");
112 if (attr)
113 mCursor = PageManager::FindResource(attr->value());
114 attr = child->first_attribute("color");
115 if (attr)
116 {
117 std::string color = attr->value();
118 ConvertStrToColor(color, &mCursorColor);
119 }
120 attr = child->first_attribute("hasfocus");
121 if (attr)
122 {
123 std::string color = attr->value();
124 SetInputFocus(atoi(color.c_str()));
125 }
126 attr = child->first_attribute("width");
127 if (attr)
128 {
129 std::string cwidth = gui_parse_text(attr->value());
130 CursorWidth = atoi(cwidth.c_str());
131 }
132 }
133 DrawCursor = HasInputFocus;
134
135 // Load the font, and possibly override the color
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200136 child = node->first_node("font");
137 if (child)
138 {
139 attr = child->first_attribute("resource");
140 if (attr) {
141 mFont = PageManager::FindResource(attr->value());
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200142 mFontHeight = gr_getMaxFontHeight(mFont ? mFont->GetResource() : NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400143 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200144 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400145
146 child = node->first_node("text");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200147 if (child) mText = child->value();
Dees_Troy51a0e822012-09-05 15:24:24 -0400148 mLastValue = gui_parse_text(mText);
149
150 child = node->first_node("data");
151 if (child)
152 {
153 attr = child->first_attribute("name");
154 if (attr)
155 mVariable = attr->value();
156 attr = child->first_attribute("default");
157 if (attr)
158 DataManager::SetValue(mVariable, attr->value());
159 attr = child->first_attribute("mask");
160 if (attr) {
161 mMask = attr->value();
162 HasMask = true;
163 }
164 attr = child->first_attribute("maskvariable");
165 if (attr)
166 mMaskVariable = attr->value();
167 else
168 mMaskVariable = mVariable;
169 }
170
171 // Load input restrictions
172 child = node->first_node("restrict");
173 if (child)
174 {
175 attr = child->first_attribute("minlen");
176 if (attr) {
177 std::string attrib = attr->value();
178 MinLen = atoi(attrib.c_str());
179 }
180 attr = child->first_attribute("maxlen");
181 if (attr) {
182 std::string attrib = attr->value();
183 MaxLen = atoi(attrib.c_str());
184 }
185 attr = child->first_attribute("allow");
186 if (attr) {
187 HasAllowed = true;
188 AllowedList = attr->value();
189 }
190 attr = child->first_attribute("disable");
191 if (attr) {
192 HasDisabled = true;
193 DisabledList = attr->value();
194 }
195 }
196
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200197 // Load the placement
Dees_Troy51a0e822012-09-05 15:24:24 -0400198 LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH);
199 SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
200
201 if (mInputText && mFontHeight && mFontHeight < (unsigned)mRenderH) {
202 mFontY = ((mRenderH - mFontHeight) / 2) + mRenderY;
203 mInputText->SetRenderPos(mRenderX, mFontY);
204 } else
205 mFontY = mRenderY;
206
207 if (mInputText)
208 mInputText->SetMaxWidth(mRenderW);
209
210 isLocalChange = false;
211 HandleTextLocation(-3);
Dees_Troy51a0e822012-09-05 15:24:24 -0400212}
213
214GUIInput::~GUIInput()
215{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200216 if (mInputText) delete mInputText;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200217 if (mAction) delete mAction;
Dees_Troy51a0e822012-09-05 15:24:24 -0400218}
219
220int GUIInput::HandleTextLocation(int x)
221{
222 int textWidth;
223 string displayValue, originalValue, insertChar;
224 void* fontResource = NULL;
225
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200226 if (mFont)
227 fontResource = mFont->GetResource();
Dees_Troy51a0e822012-09-05 15:24:24 -0400228
229 DataManager::GetValue(mVariable, originalValue);
230 displayValue = originalValue;
231 if (HasMask) {
232 int index, string_size = displayValue.size();
233 string maskedValue;
234 for (index=0; index<string_size; index++)
235 maskedValue += mMask;
236 displayValue = maskedValue;
237 }
238 textWidth = gr_measureEx(displayValue.c_str(), fontResource);
239 if (textWidth <= mRenderW) {
240 lastX = x;
241 scrollingX = 0;
242 skipChars = 0;
243 mInputText->SkipCharCount(skipChars);
244 mRendered = false;
245 return 0;
246 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200247
248 if (skipChars && skipChars < displayValue.size())
Dees_Troy51a0e822012-09-05 15:24:24 -0400249 displayValue.erase(0, skipChars);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200250
Dees_Troy51a0e822012-09-05 15:24:24 -0400251 textWidth = gr_measureEx(displayValue.c_str(), fontResource);
252 mRendered = false;
253
254 int deltaX, deltaText, newWidth;
255
256 if (x < -1000) {
257 // No change in scrolling
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200258 if (x == -1003)
Dees_Troy51a0e822012-09-05 15:24:24 -0400259 mCursorLocation = -1;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200260
Dees_Troy51a0e822012-09-05 15:24:24 -0400261 if (mCursorLocation == -1) {
262 displayValue = originalValue;
263 skipChars = 0;
264 textWidth = gr_measureEx(displayValue.c_str(), fontResource);
265 while (textWidth > mRenderW) {
266 displayValue.erase(0, 1);
267 skipChars++;
268 textWidth = gr_measureEx(displayValue.c_str(), fontResource);
269 }
270 scrollingX = mRenderW - textWidth;
271 mInputText->SkipCharCount(skipChars);
272 } else if (x == -1001) {
273 // Added a new character
274 int adjust_scrollingX = 0;
275 string cursorLocate;
276
277 cursorLocate = displayValue;
278 cursorLocate.resize(mCursorLocation);
279 textWidth = gr_measureEx(cursorLocate.c_str(), fontResource);
280 while (textWidth > mRenderW) {
281 skipChars++;
282 mCursorLocation--;
283 cursorLocate.erase(0, 1);
284 textWidth = gr_measureEx(cursorLocate.c_str(), fontResource);
285 adjust_scrollingX = -1;
286 }
287 if (adjust_scrollingX) {
288 scrollingX = mRenderW - textWidth;
289 if (scrollingX < 0)
290 scrollingX = 0;
291 }
292 mInputText->SkipCharCount(skipChars);
293 } else if (x == -1002) {
294 // Deleted a character
295 while (-1) {
296 if (skipChars == 0) {
297 scrollingX = 0;
298 mInputText->SkipCharCount(skipChars);
299 return 0;
300 }
301 insertChar = originalValue.substr(skipChars - 1, 1);
302 displayValue.insert(0, insertChar);
303 newWidth = gr_measureEx(displayValue.c_str(), fontResource);
304 deltaText = newWidth - textWidth;
305 if (newWidth > mRenderW) {
306 scrollingX = mRenderW - textWidth;
307 if (scrollingX < 0)
308 scrollingX = 0;
309 mInputText->SkipCharCount(skipChars);
310 return 0;
311 } else {
312 textWidth = newWidth;
313 skipChars--;
314 mCursorLocation++;
315 }
316 }
317 } else
Dees_Troy2673cec2013-04-02 20:22:16 +0000318 LOGINFO("GUIInput::HandleTextLocation -> We really shouldn't ever get here...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400319 } else if (x > lastX) {
320 // Dragging to right, scrolling left
321 while (-1) {
322 deltaX = x - lastX + scrollingX;
323 if (skipChars == 0 || deltaX == 0) {
324 scrollingX = 0;
325 lastX = x;
326 mInputText->SkipCharCount(skipChars);
327 return 0;
328 }
329 insertChar = originalValue.substr(skipChars - 1, 1);
330 displayValue.insert(0, insertChar);
331 newWidth = gr_measureEx(displayValue.c_str(), fontResource);
332 deltaText = newWidth - textWidth;
333 if (deltaText < deltaX) {
334 lastX += deltaText;
335 textWidth = newWidth;
336 skipChars--;
337 } else {
338 scrollingX = deltaX;
339 lastX = x;
340 mInputText->SkipCharCount(skipChars);
341 return 0;
342 }
343 }
344 } else if (x < lastX) {
345 // Dragging to left, scrolling right
346 if (textWidth <= mRenderW) {
347 lastX = x;
348 scrollingX = mRenderW - textWidth;
349 return 0;
350 }
351 if (scrollingX) {
352 deltaX = lastX - x;
353 if (scrollingX > deltaX) {
354 scrollingX -= deltaX;
355 lastX = x;
356 return 0;
357 } else {
358 lastX -= deltaX;
359 scrollingX = 0;
360 }
361 }
362 while (-1) {
363 deltaX = lastX - x;
364 displayValue.erase(0, 1);
365 skipChars++;
366 newWidth = gr_measureEx(displayValue.c_str(), fontResource);
367 deltaText = textWidth - newWidth;
368 if (newWidth <= mRenderW) {
369 scrollingX = mRenderW - newWidth;
370 lastX = x;
371 mInputText->SkipCharCount(skipChars);
372 return 0;
373 }
374 if (deltaText < deltaX) {
375 lastX -= deltaText;
376 textWidth = newWidth;
377 } else {
378 scrollingX = deltaText - deltaX;
379 lastX = x;
380 mInputText->SkipCharCount(skipChars);
381 return 0;
382 }
383 }
384 }
385 return 0;
386}
387
388int GUIInput::Render(void)
389{
390 if (!isConditionTrue())
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200391 {
392 mRendered = false;
393 return 0;
394 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400395
396 void* fontResource = NULL;
397 if (mFont) fontResource = mFont->GetResource();
398
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200399 // First step, fill background
Dees_Troy51a0e822012-09-05 15:24:24 -0400400 gr_color(mBackgroundColor.red, mBackgroundColor.green, mBackgroundColor.blue, 255);
401 gr_fill(mRenderX, mRenderY, mRenderW, mRenderH);
402
403 // Next, render the background resource (if it exists)
404 if (mBackground && mBackground->GetResource())
405 {
406 mBackgroundX = mRenderX + ((mRenderW - mBackgroundW) / 2);
407 mBackgroundY = mRenderY + ((mRenderH - mBackgroundH) / 2);
408 gr_blit(mBackground->GetResource(), 0, 0, mBackgroundW, mBackgroundH, mBackgroundX, mBackgroundY);
409 }
410
411 int ret = 0;
412
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200413 // Render the text
Dees_Troy51a0e822012-09-05 15:24:24 -0400414 mInputText->SetRenderPos(mRenderX + scrollingX, mFontY);
415 mInputText->SetMaxWidth(mRenderW - scrollingX);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200416 if (mInputText) ret = mInputText->Render();
417 if (ret < 0) return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400418
419 if (HasInputFocus && DrawCursor) {
420 // Render the cursor
421 string displayValue;
422 int cursorX;
423 DataManager::GetValue(mVariable, displayValue);
424 if (HasMask) {
425 int index, string_size = displayValue.size();
426 string maskedValue;
427 for (index=0; index<string_size; index++)
428 maskedValue += mMask;
429 displayValue = maskedValue;
430 }
431 if (displayValue.size() == 0) {
432 skipChars = 0;
433 mCursorLocation = -1;
434 cursorX = mRenderX;
435 } else {
436 if (skipChars && skipChars < displayValue.size()) {
437 displayValue.erase(0, skipChars);
438 }
439 if (mCursorLocation == 0) {
440 // Cursor is at the beginning
441 cursorX = mRenderX;
442 } else if (mCursorLocation > 0) {
443 // Cursor is in the middle
444 if (displayValue.size() > (unsigned)mCursorLocation) {
445 string cursorDisplay;
446
447 cursorDisplay = displayValue;
448 cursorDisplay.resize(mCursorLocation);
449 cursorX = gr_measureEx(cursorDisplay.c_str(), fontResource) + mRenderX;
450 } else {
451 // Cursor location is after the end of the text - reset to -1
452 mCursorLocation = -1;
453 cursorX = gr_measureEx(displayValue.c_str(), fontResource) + mRenderX;
454 }
455 } else {
456 // Cursor is at the end (-1)
457 cursorX = gr_measureEx(displayValue.c_str(), fontResource) + mRenderX;
458 }
459 }
460 cursorX += scrollingX;
461 // Make sure that the cursor doesn't go past the boundaries of the box
462 if (cursorX + (int)CursorWidth > mRenderX + mRenderW)
463 cursorX = mRenderX + mRenderW - CursorWidth;
464
465 // Set the color for the cursor
466 gr_color(mCursorColor.red, mCursorColor.green, mCursorColor.blue, 255);
467 gr_fill(cursorX, mFontY, CursorWidth, mFontHeight);
468 }
469
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200470 mRendered = true;
471 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400472}
473
474int GUIInput::Update(void)
475{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200476 if (!isConditionTrue()) return (mRendered ? 2 : 0);
477 if (!mRendered) return 2;
Dees_Troy51a0e822012-09-05 15:24:24 -0400478
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200479 int ret = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400480
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200481 if (mInputText) ret = mInputText->Update();
482 if (ret < 0) return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400483
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200484 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400485}
486
487int GUIInput::GetSelection(int x, int y)
488{
489 if (x < mRenderX || x - mRenderX > mRenderW || y < mRenderY || y - mRenderY > mRenderH) return -1;
490 return (x - mRenderX);
491}
492
493int GUIInput::NotifyTouch(TOUCH_STATE state, int x, int y)
494{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200495 static int startSelection = -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400496 int textWidth;
497 string displayValue, originalValue;
498 void* fontResource = NULL;
499
500 if (mFont) fontResource = mFont->GetResource();
501
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200502 if (!isConditionTrue())
503 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400504
505 if (!HasInputFocus) {
506 if (state != TOUCH_RELEASE)
507 return 0; // Only change focus if touch releases within the input box
508 if (GetSelection(x, y) >= 0) {
509 // When changing focus, we don't scroll or change the cursor location
510 PageManager::SetKeyBoardFocus(0);
511 PageManager::NotifyKeyboard(0);
512 SetInputFocus(1);
513 DrawCursor = true;
514 mRendered = false;
515 }
516 } else {
517 switch (state) {
518 case TOUCH_HOLD:
519 case TOUCH_REPEAT:
520 break;
521 case TOUCH_START:
522 startSelection = GetSelection(x,y);
523 lastX = x;
524 DrawCursor = false;
525 mRendered = false;
526 break;
527
528 case TOUCH_DRAG:
529 // Check if we dragged out of the selection window
530 if (GetSelection(x, y) == -1) {
531 lastX = 0;
532 break;
533 }
534
535 DrawCursor = false;
536
537 // Provide some debounce on initial touches
538 if (startSelection != -1 && abs(x - lastX) < 6) {
539 break;
540 }
541
542 startSelection = -1;
543 if (lastX != x)
544 HandleTextLocation(x);
545 break;
546
547 case TOUCH_RELEASE:
548 // We've moved the cursor location
549 int relativeX = x - mRenderX;
550
551 mRendered = false;
552 DrawCursor = true;
553 DataManager::GetValue(mVariable, displayValue);
554 if (HasMask) {
555 int index, string_size = displayValue.size();
556 string maskedValue;
557 for (index=0; index<string_size; index++)
558 maskedValue += mMask;
559 displayValue = maskedValue;
560 }
561 if (displayValue.size() == 0) {
562 skipChars = 0;
563 mCursorLocation = -1;
564 return 0;
565 } else if (skipChars && skipChars < displayValue.size()) {
566 displayValue.erase(0, skipChars);
567 }
568
569 string cursorString;
570 int cursorX = 0;
571 unsigned index = 0;
572
573 for(index=0; index<displayValue.size(); index++)
574 {
575 cursorString = displayValue.substr(0, index);
576 cursorX = gr_measureEx(cursorString.c_str(), fontResource) + mRenderX;
577 if (cursorX > x) {
578 if (index > 0)
579 mCursorLocation = index - 1;
580 else
581 mCursorLocation = index;
582 return 0;
583 }
584 }
585 mCursorLocation = -1;
586 break;
587 }
588 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200589 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400590}
591
Vojtech Bocek07220562014-02-08 02:05:33 +0100592int GUIInput::NotifyVarChange(const std::string& varName, const std::string& value)
Dees_Troy51a0e822012-09-05 15:24:24 -0400593{
Vojtech Bocek07220562014-02-08 02:05:33 +0100594 GUIObject::NotifyVarChange(varName, value);
595
Dees_Troy51a0e822012-09-05 15:24:24 -0400596 if (varName == mVariable && !isLocalChange) {
597 HandleTextLocation(-1003);
598 return 0;
599 }
600 return 0;
601}
602
603int GUIInput::NotifyKeyboard(int key)
604{
605 string variableValue;
606
607 if (HasInputFocus) {
608 if (key == KEYBOARD_BACKSPACE) {
609 //Backspace
610 DataManager::GetValue(mVariable, variableValue);
611 if (variableValue.size() > 0 && (mCursorLocation + skipChars != 0 || mCursorLocation == -1)) {
612 if (mCursorLocation == -1) {
613 variableValue.resize(variableValue.size() - 1);
614 } else {
615 variableValue.erase(mCursorLocation + skipChars - 1, 1);
616 if (mCursorLocation > 0)
617 mCursorLocation--;
618 else if (skipChars > 0)
619 skipChars--;
620 }
621 isLocalChange = true;
622 DataManager::SetValue(mVariable, variableValue);
623 isLocalChange = false;
624
625 if (HasMask) {
626 int index, string_size = variableValue.size();
627 string maskedValue;
628 for (index=0; index<string_size; index++)
629 maskedValue += mMask;
630 DataManager::SetValue(mMaskVariable, maskedValue);
631 }
632 HandleTextLocation(-1002);
633 }
634 } else if (key == KEYBOARD_SWIPE_LEFT) {
635 // Delete all
636 isLocalChange = true;
637 if (mCursorLocation == -1) {
638 DataManager::SetValue (mVariable, "");
639 if (HasMask)
640 DataManager::SetValue(mMaskVariable, "");
641 mCursorLocation = -1;
642 } else {
643 DataManager::GetValue(mVariable, variableValue);
644 variableValue.erase(0, mCursorLocation + skipChars);
645 DataManager::SetValue(mVariable, variableValue);
646 if (HasMask) {
647 DataManager::GetValue(mMaskVariable, variableValue);
648 variableValue.erase(0, mCursorLocation + skipChars);
649 DataManager::SetValue(mMaskVariable, variableValue);
650 }
651 mCursorLocation = 0;
652 }
653 skipChars = 0;
654 scrollingX = 0;
655 mInputText->SkipCharCount(skipChars);
656 isLocalChange = false;
657 mRendered = false;
658 return 0;
659 } else if (key == KEYBOARD_ARROW_LEFT) {
660 if (mCursorLocation == 0 && skipChars == 0)
661 return 0; // we're already at the beginning
662 if (mCursorLocation == -1) {
663 DataManager::GetValue(mVariable, variableValue);
664 if (variableValue.size() == 0)
665 return 0;
666 mCursorLocation = variableValue.size() - skipChars - 1;
667 } else if (mCursorLocation == 0) {
668 skipChars--;
669 HandleTextLocation(-1002);
670 } else {
671 mCursorLocation--;
672 HandleTextLocation(-1002);
673 }
674 mRendered = false;
675 return 0;
676 } else if (key == KEYBOARD_ARROW_RIGHT) {
677 if (mCursorLocation == -1)
678 return 0; // we're already at the end
679 mCursorLocation++;
680 DataManager::GetValue(mVariable, variableValue);
681 if (variableValue.size() <= mCursorLocation + skipChars)
682 mCursorLocation = -1;
683 HandleTextLocation(-1001);
684 mRendered = false;
685 return 0;
686 } else if (key == KEYBOARD_HOME || key == KEYBOARD_ARROW_UP) {
687 DataManager::GetValue(mVariable, variableValue);
688 if (variableValue.size() == 0)
689 return 0;
690 mCursorLocation = 0;
691 skipChars = 0;
692 mRendered = false;
693 HandleTextLocation(-1002);
694 return 0;
695 } else if (key == KEYBOARD_END || key == KEYBOARD_ARROW_DOWN) {
696 mCursorLocation = -1;
697 mRendered = false;
698 HandleTextLocation(-1003);
699 return 0;
700 } else if (key < KEYBOARD_SPECIAL_KEYS && key > 0) {
701 // Regular key
702 if (HasAllowed && AllowedList.find((char)key) == string::npos) {
703 return 0;
704 }
705 if (HasDisabled && DisabledList.find((char)key) != string::npos) {
706 return 0;
707 }
708 DataManager::GetValue(mVariable, variableValue);
709 if (MaxLen != 0 && variableValue.size() >= MaxLen) {
710 return 0;
711 }
712 if (mCursorLocation == -1) {
713 variableValue += key;
714 } else {
that5fa54ce2015-02-01 16:15:29 +0100715 variableValue.insert(mCursorLocation + skipChars, 1, key);
Dees_Troy51a0e822012-09-05 15:24:24 -0400716 mCursorLocation++;
717 }
718 isLocalChange = true;
719 DataManager::SetValue(mVariable, variableValue);
720 HandleTextLocation(-1001);
721 isLocalChange = false;
722
723 if (HasMask) {
724 int index, string_size = variableValue.size();
725 string maskedValue;
726 for (index=0; index<string_size; index++)
727 maskedValue += mMask;
728 DataManager::SetValue(mMaskVariable, maskedValue);
729 }
730 } else if (key == KEYBOARD_ACTION) {
731 // Action
732 DataManager::GetValue(mVariable, variableValue);
733 if (mAction) {
734 unsigned inputLen = variableValue.length();
735 if (inputLen < MinLen)
736 return 0;
737 else if (MaxLen != 0 && inputLen > MaxLen)
738 return 0;
739 else
740 return (mAction ? mAction->NotifyTouch(TOUCH_RELEASE, mRenderX, mRenderY) : 1);
741 }
742 }
743 return 0;
744 } else {
745 if (key == 0) {
746 // Somewhat ugly hack-ish way to tell the box to redraw after losing focus to remove the cursor
747 mRendered = false;
748 return 1;
749 }
750 }
751 return 1;
752}