| 313 | } |
| 314 | |
| 315 | void TextFieldTTF::deleteBackward(size_t numChars) |
| 316 | { |
| 317 | size_t len = _inputText.length(); |
| 318 | if (!len) |
| 319 | { |
| 320 | // there is no string |
| 321 | return; |
| 322 | } |
| 323 | |
| 324 | // Length of characters to delete is based on input editor, but the actual |
| 325 | // length of the displayed text may be less |
| 326 | numChars = std::min(numChars, len); |
| 327 | |
| 328 | size_t totalDeleteLen = 0; |
| 329 | for (auto i = 0; i < numChars; ++i) |
| 330 | { |
| 331 | // get the delete byte number |
| 332 | size_t deleteLen = 1; // default, erase 1 byte |
| 333 | |
| 334 | // Calculate the actual number of bytes to delete for a specific character |
| 335 | while (0x80 == (0xC0 & _inputText.at(len - totalDeleteLen - deleteLen))) |
| 336 | { |
| 337 | ++deleteLen; |
| 338 | } |
| 339 | totalDeleteLen += deleteLen; |
| 340 | } |
| 341 | |
| 342 | if (_delegate && |
| 343 | _delegate->onTextFieldDeleteBackward(this, _inputText.c_str() + len - totalDeleteLen, static_cast<int>(totalDeleteLen))) |
| 344 | { |
| 345 | // delegate doesn't want to delete backwards |
| 346 | return; |
| 347 | } |
| 348 | |
| 349 | // if all text deleted, show placeholder string |
| 350 | if (len <= totalDeleteLen) |
| 351 | { |
| 352 | _inputText = ""; |
| 353 | _charCount = 0; |
| 354 | setCursorPosition(0); |
| 355 | setString(_inputText); |
| 356 | return; |
| 357 | } |
| 358 | |
| 359 | // set new input text |
| 360 | if (_cursorEnabled) |
| 361 | { |
| 362 | if (_cursorPosition) |
| 363 | { |
| 364 | setCursorPosition(_cursorPosition - 1); |
| 365 | |
| 366 | std::string sText(_inputText); |
| 367 | auto nb = StringUtils::eraseUTF8CharAt(sText, _cursorPosition); |
| 368 | if (nb) |
| 369 | --_charCount; |
| 370 | |
| 371 | setString(sText); |
| 372 | } |
no test coverage detected