blob: ca27ea8121e23fe2abaa28cdc8d175807eb9c2d7 [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
Ethan Yonker21ff02a2015-02-18 14:35:00 -060088 child = FindNode(node, "background");
Dees_Troy51a0e822012-09-05 15:24:24 -040089 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
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600101 child = FindNode(node, "cursor");
Dees_Troy51a0e822012-09-05 15:24:24 -0400102 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 {
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600109 std::string focus = attr->value();
110 SetInputFocus(atoi(focus.c_str()));
Dees_Troy51a0e822012-09-05 15:24:24 -0400111 }
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600112 CursorWidth = LoadAttrIntScaleX(child, "width", CursorWidth);
Dees_Troy51a0e822012-09-05 15:24:24 -0400113 }
114 DrawCursor = HasInputFocus;
115
thatf6ed8fc2015-02-14 20:23:16 +0100116 // Load the font
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600117 child = FindNode(node, "font");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200118 if (child)
119 {
thatf6ed8fc2015-02-14 20:23:16 +0100120 mFont = LoadAttrFont(child, "resource");
121 mFontHeight = mFont->GetHeight();
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200122 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400123
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600124 child = FindNode(node, "text");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200125 if (child) mText = child->value();
Dees_Troy51a0e822012-09-05 15:24:24 -0400126 mLastValue = gui_parse_text(mText);
127
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600128 child = FindNode(node, "data");
Dees_Troy51a0e822012-09-05 15:24:24 -0400129 if (child)
130 {
131 attr = child->first_attribute("name");
132 if (attr)
133 mVariable = attr->value();
134 attr = child->first_attribute("default");
135 if (attr)
136 DataManager::SetValue(mVariable, attr->value());
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600137 mMask = LoadAttrString(child, "mask");
138 HasMask = !mMask.empty();
Dees_Troy51a0e822012-09-05 15:24:24 -0400139 attr = child->first_attribute("maskvariable");
140 if (attr)
141 mMaskVariable = attr->value();
142 else
143 mMaskVariable = mVariable;
144 }
145
146 // Load input restrictions
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600147 child = FindNode(node, "restrict");
Dees_Troy51a0e822012-09-05 15:24:24 -0400148 if (child)
149 {
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600150 MinLen = LoadAttrInt(child, "minlen", MinLen);
151 MaxLen = LoadAttrInt(child, "maxlen", MaxLen);
152 AllowedList = LoadAttrString(child, "allow");
153 HasAllowed = !AllowedList.empty();
154 DisabledList = LoadAttrString(child, "disable");
155 HasDisabled = !DisabledList.empty();
Dees_Troy51a0e822012-09-05 15:24:24 -0400156 }
157
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200158 // Load the placement
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600159 LoadPlacement(FindNode(node, "placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH);
Dees_Troy51a0e822012-09-05 15:24:24 -0400160 SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
161
162 if (mInputText && mFontHeight && mFontHeight < (unsigned)mRenderH) {
163 mFontY = ((mRenderH - mFontHeight) / 2) + mRenderY;
164 mInputText->SetRenderPos(mRenderX, mFontY);
165 } else
166 mFontY = mRenderY;
167
168 if (mInputText)
169 mInputText->SetMaxWidth(mRenderW);
170
171 isLocalChange = false;
172 HandleTextLocation(-3);
Dees_Troy51a0e822012-09-05 15:24:24 -0400173}
174
175GUIInput::~GUIInput()
176{
thatf6ed8fc2015-02-14 20:23:16 +0100177 delete mInputText;
178 delete mAction;
Dees_Troy51a0e822012-09-05 15:24:24 -0400179}
180
181int GUIInput::HandleTextLocation(int x)
182{
183 int textWidth;
184 string displayValue, originalValue, insertChar;
185 void* fontResource = NULL;
186
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200187 if (mFont)
188 fontResource = mFont->GetResource();
Dees_Troy51a0e822012-09-05 15:24:24 -0400189
190 DataManager::GetValue(mVariable, originalValue);
191 displayValue = originalValue;
192 if (HasMask) {
193 int index, string_size = displayValue.size();
194 string maskedValue;
195 for (index=0; index<string_size; index++)
196 maskedValue += mMask;
197 displayValue = maskedValue;
198 }
199 textWidth = gr_measureEx(displayValue.c_str(), fontResource);
200 if (textWidth <= mRenderW) {
201 lastX = x;
202 scrollingX = 0;
203 skipChars = 0;
204 mInputText->SkipCharCount(skipChars);
205 mRendered = false;
206 return 0;
207 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200208
209 if (skipChars && skipChars < displayValue.size())
Dees_Troy51a0e822012-09-05 15:24:24 -0400210 displayValue.erase(0, skipChars);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200211
Dees_Troy51a0e822012-09-05 15:24:24 -0400212 textWidth = gr_measureEx(displayValue.c_str(), fontResource);
213 mRendered = false;
214
215 int deltaX, deltaText, newWidth;
216
217 if (x < -1000) {
218 // No change in scrolling
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200219 if (x == -1003)
Dees_Troy51a0e822012-09-05 15:24:24 -0400220 mCursorLocation = -1;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200221
Dees_Troy51a0e822012-09-05 15:24:24 -0400222 if (mCursorLocation == -1) {
223 displayValue = originalValue;
224 skipChars = 0;
225 textWidth = gr_measureEx(displayValue.c_str(), fontResource);
226 while (textWidth > mRenderW) {
227 displayValue.erase(0, 1);
228 skipChars++;
229 textWidth = gr_measureEx(displayValue.c_str(), fontResource);
230 }
231 scrollingX = mRenderW - textWidth;
232 mInputText->SkipCharCount(skipChars);
233 } else if (x == -1001) {
234 // Added a new character
235 int adjust_scrollingX = 0;
236 string cursorLocate;
237
238 cursorLocate = displayValue;
239 cursorLocate.resize(mCursorLocation);
240 textWidth = gr_measureEx(cursorLocate.c_str(), fontResource);
241 while (textWidth > mRenderW) {
242 skipChars++;
243 mCursorLocation--;
244 cursorLocate.erase(0, 1);
245 textWidth = gr_measureEx(cursorLocate.c_str(), fontResource);
246 adjust_scrollingX = -1;
247 }
248 if (adjust_scrollingX) {
249 scrollingX = mRenderW - textWidth;
250 if (scrollingX < 0)
251 scrollingX = 0;
252 }
253 mInputText->SkipCharCount(skipChars);
254 } else if (x == -1002) {
255 // Deleted a character
256 while (-1) {
257 if (skipChars == 0) {
258 scrollingX = 0;
259 mInputText->SkipCharCount(skipChars);
260 return 0;
261 }
262 insertChar = originalValue.substr(skipChars - 1, 1);
263 displayValue.insert(0, insertChar);
264 newWidth = gr_measureEx(displayValue.c_str(), fontResource);
265 deltaText = newWidth - textWidth;
266 if (newWidth > mRenderW) {
267 scrollingX = mRenderW - textWidth;
268 if (scrollingX < 0)
269 scrollingX = 0;
270 mInputText->SkipCharCount(skipChars);
271 return 0;
272 } else {
273 textWidth = newWidth;
274 skipChars--;
275 mCursorLocation++;
276 }
277 }
278 } else
Dees_Troy2673cec2013-04-02 20:22:16 +0000279 LOGINFO("GUIInput::HandleTextLocation -> We really shouldn't ever get here...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400280 } else if (x > lastX) {
281 // Dragging to right, scrolling left
282 while (-1) {
283 deltaX = x - lastX + scrollingX;
284 if (skipChars == 0 || deltaX == 0) {
285 scrollingX = 0;
286 lastX = x;
287 mInputText->SkipCharCount(skipChars);
288 return 0;
289 }
290 insertChar = originalValue.substr(skipChars - 1, 1);
291 displayValue.insert(0, insertChar);
292 newWidth = gr_measureEx(displayValue.c_str(), fontResource);
293 deltaText = newWidth - textWidth;
294 if (deltaText < deltaX) {
295 lastX += deltaText;
296 textWidth = newWidth;
297 skipChars--;
298 } else {
299 scrollingX = deltaX;
300 lastX = x;
301 mInputText->SkipCharCount(skipChars);
302 return 0;
303 }
304 }
305 } else if (x < lastX) {
306 // Dragging to left, scrolling right
307 if (textWidth <= mRenderW) {
308 lastX = x;
309 scrollingX = mRenderW - textWidth;
310 return 0;
311 }
312 if (scrollingX) {
313 deltaX = lastX - x;
314 if (scrollingX > deltaX) {
315 scrollingX -= deltaX;
316 lastX = x;
317 return 0;
318 } else {
319 lastX -= deltaX;
320 scrollingX = 0;
321 }
322 }
323 while (-1) {
324 deltaX = lastX - x;
325 displayValue.erase(0, 1);
326 skipChars++;
327 newWidth = gr_measureEx(displayValue.c_str(), fontResource);
328 deltaText = textWidth - newWidth;
329 if (newWidth <= mRenderW) {
330 scrollingX = mRenderW - newWidth;
331 lastX = x;
332 mInputText->SkipCharCount(skipChars);
333 return 0;
334 }
335 if (deltaText < deltaX) {
336 lastX -= deltaText;
337 textWidth = newWidth;
338 } else {
339 scrollingX = deltaText - deltaX;
340 lastX = x;
341 mInputText->SkipCharCount(skipChars);
342 return 0;
343 }
344 }
345 }
346 return 0;
347}
348
349int GUIInput::Render(void)
350{
351 if (!isConditionTrue())
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200352 {
353 mRendered = false;
354 return 0;
355 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400356
357 void* fontResource = NULL;
358 if (mFont) fontResource = mFont->GetResource();
359
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200360 // First step, fill background
Dees_Troy51a0e822012-09-05 15:24:24 -0400361 gr_color(mBackgroundColor.red, mBackgroundColor.green, mBackgroundColor.blue, 255);
362 gr_fill(mRenderX, mRenderY, mRenderW, mRenderH);
363
364 // Next, render the background resource (if it exists)
365 if (mBackground && mBackground->GetResource())
366 {
367 mBackgroundX = mRenderX + ((mRenderW - mBackgroundW) / 2);
368 mBackgroundY = mRenderY + ((mRenderH - mBackgroundH) / 2);
369 gr_blit(mBackground->GetResource(), 0, 0, mBackgroundW, mBackgroundH, mBackgroundX, mBackgroundY);
370 }
371
372 int ret = 0;
373
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200374 // Render the text
Dees_Troy51a0e822012-09-05 15:24:24 -0400375 mInputText->SetRenderPos(mRenderX + scrollingX, mFontY);
376 mInputText->SetMaxWidth(mRenderW - scrollingX);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200377 if (mInputText) ret = mInputText->Render();
378 if (ret < 0) return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400379
380 if (HasInputFocus && DrawCursor) {
381 // Render the cursor
382 string displayValue;
383 int cursorX;
384 DataManager::GetValue(mVariable, displayValue);
385 if (HasMask) {
386 int index, string_size = displayValue.size();
387 string maskedValue;
388 for (index=0; index<string_size; index++)
389 maskedValue += mMask;
390 displayValue = maskedValue;
391 }
392 if (displayValue.size() == 0) {
393 skipChars = 0;
394 mCursorLocation = -1;
395 cursorX = mRenderX;
396 } else {
397 if (skipChars && skipChars < displayValue.size()) {
398 displayValue.erase(0, skipChars);
399 }
400 if (mCursorLocation == 0) {
401 // Cursor is at the beginning
402 cursorX = mRenderX;
403 } else if (mCursorLocation > 0) {
404 // Cursor is in the middle
405 if (displayValue.size() > (unsigned)mCursorLocation) {
406 string cursorDisplay;
407
408 cursorDisplay = displayValue;
409 cursorDisplay.resize(mCursorLocation);
410 cursorX = gr_measureEx(cursorDisplay.c_str(), fontResource) + mRenderX;
411 } else {
412 // Cursor location is after the end of the text - reset to -1
413 mCursorLocation = -1;
414 cursorX = gr_measureEx(displayValue.c_str(), fontResource) + mRenderX;
415 }
416 } else {
417 // Cursor is at the end (-1)
418 cursorX = gr_measureEx(displayValue.c_str(), fontResource) + mRenderX;
419 }
420 }
421 cursorX += scrollingX;
422 // Make sure that the cursor doesn't go past the boundaries of the box
423 if (cursorX + (int)CursorWidth > mRenderX + mRenderW)
424 cursorX = mRenderX + mRenderW - CursorWidth;
425
426 // Set the color for the cursor
427 gr_color(mCursorColor.red, mCursorColor.green, mCursorColor.blue, 255);
428 gr_fill(cursorX, mFontY, CursorWidth, mFontHeight);
429 }
430
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200431 mRendered = true;
432 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400433}
434
435int GUIInput::Update(void)
436{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200437 if (!isConditionTrue()) return (mRendered ? 2 : 0);
438 if (!mRendered) return 2;
Dees_Troy51a0e822012-09-05 15:24:24 -0400439
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200440 int ret = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400441
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200442 if (mInputText) ret = mInputText->Update();
443 if (ret < 0) return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400444
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200445 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400446}
447
448int GUIInput::GetSelection(int x, int y)
449{
450 if (x < mRenderX || x - mRenderX > mRenderW || y < mRenderY || y - mRenderY > mRenderH) return -1;
451 return (x - mRenderX);
452}
453
454int GUIInput::NotifyTouch(TOUCH_STATE state, int x, int y)
455{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200456 static int startSelection = -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400457 int textWidth;
458 string displayValue, originalValue;
459 void* fontResource = NULL;
460
461 if (mFont) fontResource = mFont->GetResource();
462
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200463 if (!isConditionTrue())
464 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400465
466 if (!HasInputFocus) {
467 if (state != TOUCH_RELEASE)
468 return 0; // Only change focus if touch releases within the input box
469 if (GetSelection(x, y) >= 0) {
470 // When changing focus, we don't scroll or change the cursor location
471 PageManager::SetKeyBoardFocus(0);
472 PageManager::NotifyKeyboard(0);
473 SetInputFocus(1);
474 DrawCursor = true;
475 mRendered = false;
476 }
477 } else {
478 switch (state) {
479 case TOUCH_HOLD:
480 case TOUCH_REPEAT:
481 break;
482 case TOUCH_START:
483 startSelection = GetSelection(x,y);
484 lastX = x;
485 DrawCursor = false;
486 mRendered = false;
487 break;
488
489 case TOUCH_DRAG:
490 // Check if we dragged out of the selection window
491 if (GetSelection(x, y) == -1) {
492 lastX = 0;
493 break;
494 }
495
496 DrawCursor = false;
497
498 // Provide some debounce on initial touches
499 if (startSelection != -1 && abs(x - lastX) < 6) {
500 break;
501 }
502
503 startSelection = -1;
504 if (lastX != x)
505 HandleTextLocation(x);
506 break;
507
508 case TOUCH_RELEASE:
509 // We've moved the cursor location
510 int relativeX = x - mRenderX;
511
512 mRendered = false;
513 DrawCursor = true;
514 DataManager::GetValue(mVariable, displayValue);
515 if (HasMask) {
516 int index, string_size = displayValue.size();
517 string maskedValue;
518 for (index=0; index<string_size; index++)
519 maskedValue += mMask;
520 displayValue = maskedValue;
521 }
522 if (displayValue.size() == 0) {
523 skipChars = 0;
524 mCursorLocation = -1;
525 return 0;
526 } else if (skipChars && skipChars < displayValue.size()) {
527 displayValue.erase(0, skipChars);
528 }
529
530 string cursorString;
531 int cursorX = 0;
532 unsigned index = 0;
533
534 for(index=0; index<displayValue.size(); index++)
535 {
536 cursorString = displayValue.substr(0, index);
537 cursorX = gr_measureEx(cursorString.c_str(), fontResource) + mRenderX;
538 if (cursorX > x) {
539 if (index > 0)
540 mCursorLocation = index - 1;
541 else
542 mCursorLocation = index;
543 return 0;
544 }
545 }
546 mCursorLocation = -1;
547 break;
548 }
549 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200550 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400551}
552
Vojtech Bocek07220562014-02-08 02:05:33 +0100553int GUIInput::NotifyVarChange(const std::string& varName, const std::string& value)
Dees_Troy51a0e822012-09-05 15:24:24 -0400554{
Vojtech Bocek07220562014-02-08 02:05:33 +0100555 GUIObject::NotifyVarChange(varName, value);
556
Dees_Troy51a0e822012-09-05 15:24:24 -0400557 if (varName == mVariable && !isLocalChange) {
558 HandleTextLocation(-1003);
559 return 0;
560 }
561 return 0;
562}
563
564int GUIInput::NotifyKeyboard(int key)
565{
566 string variableValue;
567
568 if (HasInputFocus) {
569 if (key == KEYBOARD_BACKSPACE) {
570 //Backspace
571 DataManager::GetValue(mVariable, variableValue);
572 if (variableValue.size() > 0 && (mCursorLocation + skipChars != 0 || mCursorLocation == -1)) {
573 if (mCursorLocation == -1) {
574 variableValue.resize(variableValue.size() - 1);
575 } else {
576 variableValue.erase(mCursorLocation + skipChars - 1, 1);
577 if (mCursorLocation > 0)
578 mCursorLocation--;
579 else if (skipChars > 0)
580 skipChars--;
581 }
582 isLocalChange = true;
583 DataManager::SetValue(mVariable, variableValue);
584 isLocalChange = false;
585
586 if (HasMask) {
587 int index, string_size = variableValue.size();
588 string maskedValue;
589 for (index=0; index<string_size; index++)
590 maskedValue += mMask;
591 DataManager::SetValue(mMaskVariable, maskedValue);
592 }
593 HandleTextLocation(-1002);
594 }
595 } else if (key == KEYBOARD_SWIPE_LEFT) {
596 // Delete all
597 isLocalChange = true;
598 if (mCursorLocation == -1) {
599 DataManager::SetValue (mVariable, "");
600 if (HasMask)
601 DataManager::SetValue(mMaskVariable, "");
602 mCursorLocation = -1;
603 } else {
604 DataManager::GetValue(mVariable, variableValue);
605 variableValue.erase(0, mCursorLocation + skipChars);
606 DataManager::SetValue(mVariable, variableValue);
607 if (HasMask) {
608 DataManager::GetValue(mMaskVariable, variableValue);
609 variableValue.erase(0, mCursorLocation + skipChars);
610 DataManager::SetValue(mMaskVariable, variableValue);
611 }
612 mCursorLocation = 0;
613 }
614 skipChars = 0;
615 scrollingX = 0;
616 mInputText->SkipCharCount(skipChars);
617 isLocalChange = false;
618 mRendered = false;
619 return 0;
620 } else if (key == KEYBOARD_ARROW_LEFT) {
621 if (mCursorLocation == 0 && skipChars == 0)
622 return 0; // we're already at the beginning
623 if (mCursorLocation == -1) {
624 DataManager::GetValue(mVariable, variableValue);
625 if (variableValue.size() == 0)
626 return 0;
627 mCursorLocation = variableValue.size() - skipChars - 1;
628 } else if (mCursorLocation == 0) {
629 skipChars--;
630 HandleTextLocation(-1002);
631 } else {
632 mCursorLocation--;
633 HandleTextLocation(-1002);
634 }
635 mRendered = false;
636 return 0;
637 } else if (key == KEYBOARD_ARROW_RIGHT) {
638 if (mCursorLocation == -1)
639 return 0; // we're already at the end
640 mCursorLocation++;
641 DataManager::GetValue(mVariable, variableValue);
642 if (variableValue.size() <= mCursorLocation + skipChars)
643 mCursorLocation = -1;
644 HandleTextLocation(-1001);
645 mRendered = false;
646 return 0;
647 } else if (key == KEYBOARD_HOME || key == KEYBOARD_ARROW_UP) {
648 DataManager::GetValue(mVariable, variableValue);
649 if (variableValue.size() == 0)
650 return 0;
651 mCursorLocation = 0;
652 skipChars = 0;
653 mRendered = false;
654 HandleTextLocation(-1002);
655 return 0;
656 } else if (key == KEYBOARD_END || key == KEYBOARD_ARROW_DOWN) {
657 mCursorLocation = -1;
658 mRendered = false;
659 HandleTextLocation(-1003);
660 return 0;
661 } else if (key < KEYBOARD_SPECIAL_KEYS && key > 0) {
662 // Regular key
663 if (HasAllowed && AllowedList.find((char)key) == string::npos) {
664 return 0;
665 }
666 if (HasDisabled && DisabledList.find((char)key) != string::npos) {
667 return 0;
668 }
669 DataManager::GetValue(mVariable, variableValue);
670 if (MaxLen != 0 && variableValue.size() >= MaxLen) {
671 return 0;
672 }
673 if (mCursorLocation == -1) {
674 variableValue += key;
675 } else {
that5fa54ce2015-02-01 16:15:29 +0100676 variableValue.insert(mCursorLocation + skipChars, 1, key);
Dees_Troy51a0e822012-09-05 15:24:24 -0400677 mCursorLocation++;
678 }
679 isLocalChange = true;
680 DataManager::SetValue(mVariable, variableValue);
681 HandleTextLocation(-1001);
682 isLocalChange = false;
683
684 if (HasMask) {
685 int index, string_size = variableValue.size();
686 string maskedValue;
687 for (index=0; index<string_size; index++)
688 maskedValue += mMask;
689 DataManager::SetValue(mMaskVariable, maskedValue);
690 }
691 } else if (key == KEYBOARD_ACTION) {
692 // Action
693 DataManager::GetValue(mVariable, variableValue);
694 if (mAction) {
695 unsigned inputLen = variableValue.length();
696 if (inputLen < MinLen)
697 return 0;
698 else if (MaxLen != 0 && inputLen > MaxLen)
699 return 0;
700 else
701 return (mAction ? mAction->NotifyTouch(TOUCH_RELEASE, mRenderX, mRenderY) : 1);
702 }
703 }
704 return 0;
705 } else {
706 if (key == 0) {
707 // Somewhat ugly hack-ish way to tell the box to redraw after losing focus to remove the cursor
708 mRendered = false;
709 return 1;
710 }
711 }
712 return 1;
713}