1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "components/ui_edit_text.h"
17
18 #include <codecvt>
19 #include <locale>
20
21 #include "font/ui_font.h"
22 #include "gfx_utils/graphic_log.h"
23 #include "securec.h"
24 #include "themes/theme_manager.h"
25 #include "common/typed_text.h"
26
27 namespace OHOS {
28 class CursorAnimator : public Animator, public AnimatorCallback {
29 public:
CursorAnimator(UIEditText * view)30 explicit CursorAnimator(UIEditText* view) : Animator(this, view, 0, true), editText_(view) {}
31
~CursorAnimator()32 virtual ~CursorAnimator() {}
33
Callback(UIView * view)34 void Callback(UIView* view) override
35 {
36 if ((view == nullptr) || (editText_ == nullptr)) {
37 return;
38 }
39
40 uint32_t curTime = GetRunTime();
41 if (curTime == preTime_) {
42 return;
43 }
44 uint32_t duration = (curTime > preTime_) ? (curTime - preTime_) : (UINT32_MAX - preTime_ + curTime);
45 if (duration < CURSOR_ANIMATOT_DURATION) {
46 return;
47 }
48 preTime_ = curTime;
49 editText_->drawCursor_ = !editText_->drawCursor_;
50 view->Invalidate();
51 }
52
StartAnimator()53 void StartAnimator()
54 {
55 if (editText_ == nullptr) {
56 return;
57 }
58 Start();
59 preTime_ = GetRunTime();
60 editText_->drawCursor_ = false;
61 }
62
StopAnimator()63 void StopAnimator()
64 {
65 if (editText_ == nullptr) {
66 return;
67 }
68 Stop();
69 editText_->drawCursor_ = false;
70 editText_->Invalidate();
71 }
72
73 private:
74 uint32_t preTime_ = 0;
75 UIEditText* editText_ = nullptr;
76 static constexpr uint16_t CURSOR_ANIMATOT_DURATION = 650;
77 };
78
UIEditText()79 UIEditText::UIEditText()
80 : inputText_(nullptr),
81 placeholderText_(nullptr),
82 offsetX_(DEFAULT_TEXT_OFFSET),
83 cursorIndex_(0),
84 deleteTextWidth_(0),
85 insertTextWidth_(0),
86 offsetState_(UPDATE_OFFSET_UNKNOW),
87 needRefresh_(false),
88 useTextColor_(false),
89 isFocused_(false),
90 drawCursor_(false),
91 maxLength_(MAX_TEXT_LENGTH),
92 placeholderEllipsisIndex_(Text::TEXT_ELLIPSIS_END_INV),
93 cursorPosX_(0),
94 textColor_(Color::White()),
95 placeholderColor_(Color::Gray()),
96 cursorColor_(Color::White()),
97 onChangeListener_(nullptr),
98 cursorAnimator_(nullptr)
99 {
100 touchable_ = true;
101 focusable_ = true;
102 Theme* theme = ThemeManager::GetInstance().GetCurrent();
103 Style& style = (theme != nullptr) ? (theme->GetEditTextStyle()) : (StyleDefault::GetEditTextStyle());
104 UIView::SetStyle(style);
105 SetDraggable(true);
106 }
107
~UIEditText()108 UIEditText::~UIEditText()
109 {
110 if (cursorAnimator_ != nullptr) {
111 delete cursorAnimator_;
112 cursorAnimator_ = nullptr;
113 }
114 if (inputText_ != nullptr) {
115 delete inputText_;
116 inputText_ = nullptr;
117 }
118 if (placeholderText_ != nullptr) {
119 delete placeholderText_;
120 placeholderText_ = nullptr;
121 }
122 }
123
OnPressEvent(const PressEvent & event)124 bool UIEditText::OnPressEvent(const PressEvent& event)
125 {
126 DealPressEvents(false, event);
127 return UIView::OnPressEvent(event);
128 }
129
OnLongPressEvent(const LongPressEvent & event)130 bool UIEditText::OnLongPressEvent(const LongPressEvent &event)
131 {
132 DealPressEvents(true, event);
133 return UIView::OnLongPressEvent(event);
134 }
135
DealPressEvents(bool longPressEvent,const Event & event)136 void UIEditText::DealPressEvents(bool longPressEvent, const Event &event)
137 {
138 if (touchable_) {
139 if (!longPressEvent) {
140 Point pressPos = event.GetCurrentPos();
141 pressPos.x = pressPos.x - GetOrigRect().GetX();
142 pressPos.y = pressPos.y - GetOrigRect().GetY();
143 Style style = GetStyleConst();
144 cursorIndex_ = inputText_->GetLetterIndexByLinePosition(style,
145 GetContentRect().GetWidth(), pressPos.x, offsetX_);
146 offsetState_ = UPDATE_OFFSET_PRESS_EVENT;
147 UpdateOffsetX();
148 }
149 RequestFocus();
150 Invalidate();
151 }
152 }
153
OnDragEvent(const DragEvent & event)154 bool UIEditText::OnDragEvent(const DragEvent& event)
155 {
156 DealPressEvents(false, event);
157 return UIView::OnDragEvent(event);
158 }
159
Focus()160 void UIEditText::Focus()
161 {
162 if (focusable_) {
163 if (cursorAnimator_ == nullptr) {
164 cursorAnimator_ = new CursorAnimator(this);
165 }
166 static_cast<CursorAnimator*>(cursorAnimator_)->StartAnimator();
167 isFocused_ = true;
168 }
169 Invalidate();
170 UIView::Focus();
171 }
172
Blur()173 void UIEditText::Blur()
174 {
175 if (cursorAnimator_ != nullptr) {
176 static_cast<CursorAnimator*>(cursorAnimator_)->StopAnimator();
177 }
178 isFocused_ = false;
179 Invalidate();
180 UIView::Blur();
181 }
182
InitText()183 void UIEditText::InitText()
184 {
185 if (inputText_ == nullptr) {
186 inputText_ = new Text();
187 inputText_->SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER);
188 inputText_->SetExpandWidth(true);
189 inputText_->SetExpandHeight(false);
190 }
191
192 if (placeholderText_ == nullptr) {
193 placeholderText_ = new Text();
194 placeholderText_->SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER);
195 placeholderText_->SetExpandWidth(false);
196 placeholderText_->SetExpandHeight(false);
197 }
198 }
199
SetStyle(Style & style)200 void UIEditText::SetStyle(Style& style)
201 {
202 UIView::SetStyle(style);
203 RefreshText();
204 }
205
SetStyle(uint8_t key,int64_t value)206 void UIEditText::SetStyle(uint8_t key, int64_t value)
207 {
208 UIView::SetStyle(key, value);
209 RefreshText();
210 }
211
SetText(const char * text)212 void UIEditText::SetText(const char* text)
213 {
214 InitText();
215 if (text == nullptr) {
216 return;
217 }
218
219 std::string inputText = std::string(text);
220 SetText(inputText);
221 cursorIndex_ = TypedText::GetUTF8CharacterSize(text, inputText.length());
222 offsetState_ = UPDATE_OFFSET_INTERFACE;
223 }
224
SetText(std::string text)225 void UIEditText::SetText(std::string text)
226 {
227 UpdateTextString(text);
228 UpdateInnerText();
229 }
230
GetText()231 const char* UIEditText::GetText()
232 {
233 return textStr_.c_str();
234 }
235
UpdateTextString(std::string text)236 void UIEditText::UpdateTextString(std::string text)
237 {
238 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convert;
239 std::wstring wideText = convert.from_bytes(text);
240 uint32_t textLen = wideText.length();
241 uint16_t maxLength = GetMaxLength();
242 if (textLen > maxLength) {
243 textLen = maxLength;
244 }
245 std::wstring newWideText = wideText.substr(0, textLen);
246 std::string newText = convert.to_bytes(newWideText);
247 CheckValueChange(newText);
248 textStr_ = newText;
249 passwordStr_ = std::string(newWideText.length(), *PASSWORD_DOT.c_str());
250 }
251
GetInnerText()252 std::string UIEditText::GetInnerText()
253 {
254 return textStr_;
255 }
256
GetInnerPassword()257 std::string UIEditText::GetInnerPassword()
258 {
259 return passwordStr_;
260 }
261
SetPlaceholder(const char * text)262 void UIEditText::SetPlaceholder(const char* text)
263 {
264 InitText();
265 placeholderText_->SetText(text);
266 if (placeholderText_->IsNeedRefresh()) {
267 RefreshText();
268 }
269 }
270
GetPlaceholder()271 const char* UIEditText::GetPlaceholder()
272 {
273 if ((placeholderText_ == nullptr) || placeholderText_->GetText() == nullptr) {
274 return "";
275 } else {
276 return placeholderText_->GetText();
277 }
278 }
279
SetFontId(uint16_t fontId)280 void UIEditText::SetFontId(uint16_t fontId)
281 {
282 InitText();
283 inputText_->SetFontId(fontId);
284 placeholderText_->SetFontId(fontId);
285 if (inputText_->IsNeedRefresh()) {
286 RefreshText();
287 }
288 }
289
SetFont(const char * name,uint8_t size)290 void UIEditText::SetFont(const char* name, uint8_t size)
291 {
292 InitText();
293 inputText_->SetFont(name, size);
294 placeholderText_->SetFont(name, size);
295 if (inputText_->IsNeedRefresh()) {
296 RefreshText();
297 }
298 }
299
GetTextWidth()300 uint16_t UIEditText::GetTextWidth()
301 {
302 InitText();
303 if (inputText_->IsNeedRefresh()) {
304 ReMeasure();
305 }
306 return inputText_->GetTextSize().x;
307 }
308
GetTextHeight()309 uint16_t UIEditText::GetTextHeight()
310 {
311 InitText();
312 if (inputText_->IsNeedRefresh()) {
313 ReMeasure();
314 }
315 return inputText_->GetTextSize().y;
316 }
317
RefreshText()318 void UIEditText::RefreshText()
319 {
320 Invalidate();
321 placeholderEllipsisIndex_ = Text::TEXT_ELLIPSIS_END_INV;
322 if (!needRefresh_) {
323 needRefresh_ = true;
324 }
325 }
326
ReMeasure()327 void UIEditText::ReMeasure()
328 {
329 if (!needRefresh_) {
330 return;
331 }
332 needRefresh_ = false;
333 InitText();
334 Style style = GetStyleConst();
335 style.textColor_ = GetTextColor();
336 Rect contentRect = GetContentRect();
337 int16_t width = contentRect.GetWidth() - BOTH_SIDE_TEXT_OFFSET;
338 contentRect.SetWidth(width > 0 ? width : 0);
339 inputText_->ReMeasureTextSize(contentRect, style);
340 placeholderText_->ReMeasureTextSize(contentRect, style);
341 placeholderEllipsisIndex_ = placeholderText_->GetEllipsisIndex(contentRect, style);
342 placeholderText_->ReMeasureTextWidthInEllipsisMode(contentRect, style, placeholderEllipsisIndex_);
343
344 UpdateOffsetX();
345 }
346
UpdateOffsetX()347 void UIEditText::UpdateOffsetX()
348 {
349 if (!inputText_) {
350 return;
351 }
352
353 Rect contentRect = GetContentRect();
354 Style style = GetStyleConst();
355
356 uint16_t textLength = GetTextLength();
357 uint16_t firstVisibleIndex = GetFirstVisibleIndex();
358 uint16_t lastVisibleIndex = GetLastVisibleIndex();
359 if (textLength == 0 || (firstVisibleIndex == 0 && lastVisibleIndex == textLength)) {
360 offsetX_ = DEFAULT_TEXT_OFFSET;
361 offsetState_ = UPDATE_OFFSET_UNKNOW;
362 deleteTextWidth_ = 0;
363 insertTextWidth_ = 0;
364 return;
365 }
366
367 switch (offsetState_) {
368 case UPDATE_OFFSET_INTERFACE:
369 offsetX_ = DEFAULT_TEXT_OFFSET;
370 break;
371 case UPDATE_OFFSET_PRESS_EVENT:
372 UpdateExtraOffsetX(firstVisibleIndex, lastVisibleIndex);
373 break;
374 case UPDATE_OFFSET_DELETE:
375 case UPDATE_OFFSET_INSERT:
376 UpdateInsertDeletedOffset();
377 break;
378 case UPDATE_OFFSET_SET_CURSOR:
379 UpdateOffsetBySetCursorIndex();
380 break;
381 case UPDATE_OFFSET_INPUT_TYPE:
382 UpdateOffsetByInputType();
383 break;
384 default:
385 break;
386 }
387 offsetState_ = UPDATE_OFFSET_UNKNOW;
388 deleteTextWidth_ = 0;
389 insertTextWidth_ = 0;
390 }
391
GetFirstVisibleIndex()392 uint16_t UIEditText::GetFirstVisibleIndex()
393 {
394 if (!inputText_) {
395 return 0;
396 }
397 Rect contentRect = GetContentRect();
398 Style style = GetStyleConst();
399 uint16_t firstVisibleIndex = 0;
400 if (inputText_->GetDirect() == UITextLanguageDirect::TEXT_DIRECT_LTR) {
401 if (offsetX_ > 0) {
402 return 0;
403 }
404 // Returns the number of characters that can be skipped by the offset.
405 firstVisibleIndex = inputText_->GetLetterIndexByLinePosition(style, contentRect.GetWidth(),
406 0, offsetX_) + 1;
407 }
408 return firstVisibleIndex;
409 }
410
GetLastVisibleIndex()411 uint16_t UIEditText::GetLastVisibleIndex()
412 {
413 if (!inputText_) {
414 return 0;
415 }
416 Rect contentRect = GetContentRect();
417 Style style = GetStyleConst();
418 uint16_t lastVisibleIndex = 0;
419 if (inputText_->GetDirect() == UITextLanguageDirect::TEXT_DIRECT_LTR) {
420 lastVisibleIndex = inputText_->GetLetterIndexByLinePosition(style, contentRect.GetWidth(),
421 contentRect.GetWidth(), offsetX_);
422 }
423 return lastVisibleIndex;
424 }
425
UpdateExtraOffsetX(const uint16_t firstVisibleIndex,const uint16_t lastVisibleIndex)426 void UIEditText::UpdateExtraOffsetX(const uint16_t firstVisibleIndex,
427 const uint16_t lastVisibleIndex)
428 {
429 if (!inputText_) {
430 return;
431 }
432 Rect contentRect = GetContentRect();
433 Style style = GetStyleConst();
434 uint16_t characterSize = 0;
435 uint16_t textLength = GetTextLength();
436 if (cursorIndex_ - firstVisibleIndex < 1 && firstVisibleIndex != 0) {
437 characterSize = inputText_->GetNextCharacterFullDispalyOffset(contentRect, style, firstVisibleIndex - 1, 1);
438 offsetX_ += characterSize + DEFAULT_TEXT_OFFSET;
439 if (GetFirstVisibleIndex() == 0) {
440 offsetX_ = DEFAULT_TEXT_OFFSET;
441 }
442 } else if (lastVisibleIndex - cursorIndex_ < 1 && lastVisibleIndex != textLength) {
443 characterSize = inputText_->GetNextCharacterFullDispalyOffset(contentRect, style, lastVisibleIndex, 1);
444 offsetX_ -= characterSize + DEFAULT_TEXT_OFFSET;
445 if (GetLastVisibleIndex() == textLength) {
446 offsetX_ = -(GetTextWidth() - GetRect().GetWidth() + BOTH_SIDE_TEXT_OFFSET);
447 }
448 }
449 }
450
GetTextWidthByCursorIndex(const uint16_t cursorIndex)451 uint16_t UIEditText::GetTextWidthByCursorIndex(const uint16_t cursorIndex)
452 {
453 if (!inputText_ || cursorIndex == 0) {
454 return 0;
455 }
456
457 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convert;
458 std::wstring wideText = convert.from_bytes(textStr_);
459 wideText = wideText.substr(0, cursorIndex);
460 std::string clipText = convert.to_bytes(wideText);
461
462 return TypedText::GetTextWidth(clipText.c_str(), GetFontId(), inputText_->GetFontSize(),
463 clipText.length(), GetStyleConst().letterSpace_);
464 }
465
UpdateInsertDeletedOffset()466 void UIEditText::UpdateInsertDeletedOffset()
467 {
468 if (deleteTextWidth_ > 0) {
469 if (offsetX_ + DEFAULT_TEXT_OFFSET < 0) {
470 offsetX_ += deleteTextWidth_;
471 if (GetFirstVisibleIndex() == 0 && GetLastVisibleIndex() == GetTextLength()) {
472 offsetX_ = DEFAULT_TEXT_OFFSET;
473 }
474 } else {
475 offsetX_ = DEFAULT_TEXT_OFFSET;
476 }
477 } else if (insertTextWidth_ > 0) {
478 if (cursorIndex_ == GetTextLength()) {
479 offsetX_ = -(GetTextWidth() - GetRect().GetWidth() + BOTH_SIDE_TEXT_OFFSET);
480 } else {
481 offsetX_ -= insertTextWidth_;
482 }
483 }
484 }
485
OnDraw(BufferInfo & gfxDstBuffer,const Rect & invalidatedArea)486 void UIEditText::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
487 {
488 InitText();
489 UIView::OnDraw(gfxDstBuffer, invalidatedArea);
490
491 bool drawPlaceholder = false;
492 if (inputText_->GetText() != nullptr && strlen(inputText_->GetText()) > 0) {
493 Style style = GetStyleConst();
494 style.textColor_ = GetTextColor();
495 OpacityType opa = GetMixOpaScale();
496 inputText_->OnDraw(gfxDstBuffer, invalidatedArea, GetOrigRect(), GetContentRect(), offsetX_, style,
497 Text::TEXT_ELLIPSIS_END_INV, opa);
498 drawPlaceholder = false;
499 } else {
500 Style style = GetStyleConst();
501 style.textColor_ = GetPlaceholderColor();
502 OpacityType opa = GetMixOpaScale();
503 placeholderText_->OnDraw(gfxDstBuffer, invalidatedArea, GetOrigRect(), GetContentRect(), DEFAULT_TEXT_OFFSET,
504 style, placeholderEllipsisIndex_, opa);
505 drawPlaceholder = true;
506 }
507
508 DrawCursor(gfxDstBuffer, invalidatedArea, drawPlaceholder);
509 }
510
DrawCursor(BufferInfo & gfxDstBuffer,const Rect & invalidatedArea,bool drawPlaceholder)511 void UIEditText::DrawCursor(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea, bool drawPlaceholder)
512 {
513 if (!(isFocused_ && drawCursor_)) {
514 return;
515 }
516
517 CalculatedCursorPos(drawPlaceholder);
518
519 Style* cursorStyle = new Style();
520 cursorStyle->SetStyle(STYLE_BACKGROUND_COLOR, cursorColor_.full);
521 cursorStyle->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE);
522
523 int16_t left = 0;
524 UITextLanguageDirect direct = drawPlaceholder ? placeholderText_->GetDirect() : inputText_->GetDirect();
525 if (direct == UITextLanguageDirect::TEXT_DIRECT_LTR) {
526 left = cursorPosX_ - DEFAULT_CURSOR_OFFSET;
527 } else if (direct == UITextLanguageDirect::TEXT_DIRECT_RTL) {
528 left = cursorPosX_ + DEFAULT_CURSOR_OFFSET;
529 }
530
531 Rect viewRect;
532 viewRect.SetLeft(left);
533 viewRect.SetTop(GetOrigRect().GetTop() + (GetRect().GetHeight() - inputText_->GetFontSize()) / 2); // 2: harf size
534 viewRect.SetHeight(inputText_->GetFontSize());
535 viewRect.SetWidth(DEFAULT_CURSOR_WIDTH);
536
537 BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, viewRect, invalidatedArea, *cursorStyle, OPA_OPAQUE);
538 delete cursorStyle;
539 }
540
InsertText(std::string text)541 void UIEditText::InsertText(std::string text)
542 {
543 InitText();
544 InsertTextByCursorIndex(text);
545 }
546
InsertTextByCursorIndex(std::string text)547 void UIEditText::InsertTextByCursorIndex(std::string text)
548 {
549 if (!inputText_) {
550 return;
551 }
552 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convert;
553 std::wstring wideText = convert.from_bytes(textStr_);
554 std::wstring insertWText = convert.from_bytes(text);
555 uint32_t textLen = wideText.length();
556 uint32_t insertWTextLen = insertWText.length();
557 if (cursorIndex_ > textLen || insertWTextLen + textLen > maxLength_) {
558 return;
559 }
560
561 std::wstring newWideText = wideText.insert(cursorIndex_, insertWText);
562 std::string newText = convert.to_bytes(newWideText);
563 cursorIndex_ += insertWTextLen;
564 SetText(newText);
565
566 Style style = GetStyleConst();
567 Rect contentRect = GetContentRect();
568 cursorPosX_ = inputText_->GetPosXByLetterIndex(contentRect, style, 0, cursorIndex_);
569 if (cursorPosX_ >= contentRect.GetWidth() - DEFAULT_TEXT_OFFSET) {
570 insertTextWidth_ = inputText_->GetNextCharacterFullDispalyOffset(contentRect,
571 style, cursorIndex_ - insertWTextLen, insertWTextLen) + style.letterSpace_;
572 offsetState_ = UPDATE_OFFSET_INSERT;
573 }
574
575 if (isFocused_) {
576 if (cursorAnimator_ != nullptr) {
577 static_cast<CursorAnimator*>(cursorAnimator_)->StartAnimator();
578 }
579 }
580 }
581
CalculatedCursorPos(bool drawPlaceholder)582 void UIEditText::CalculatedCursorPos(bool drawPlaceholder)
583 {
584 if (!inputText_ || !placeholderText_) {
585 return;
586 }
587
588 Style style = GetStyleConst();
589 Rect contentRect = GetContentRect();
590 UITextLanguageDirect direct = drawPlaceholder ? placeholderText_->GetDirect() : inputText_->GetDirect();
591 if (direct == UITextLanguageDirect::TEXT_DIRECT_LTR) {
592 cursorPosX_ = contentRect.GetX() + inputText_->GetPosXByLetterIndex(contentRect,
593 style, 0, cursorIndex_) + offsetX_;
594 } else if (direct == UITextLanguageDirect::TEXT_DIRECT_RTL) {
595 cursorPosX_ = GetRect().GetRight() - style.borderWidth_ - style.paddingRight_
596 - inputText_->GetPosXByLetterIndex(contentRect, style, 0, cursorIndex_)
597 - offsetX_;
598 }
599 }
600
GetCursorIndex()601 uint16_t UIEditText::GetCursorIndex()
602 {
603 return cursorIndex_;
604 }
605
SetCursorIndex(uint16_t cursorIndex)606 void UIEditText::SetCursorIndex(uint16_t cursorIndex)
607 {
608 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convert;
609 std::wstring wideText = convert.from_bytes(textStr_);
610 if (cursorIndex > wideText.length()) {
611 cursorIndex_ = wideText.length();
612 } else {
613 cursorIndex_ = cursorIndex;
614 }
615
616 offsetState_ = UPDATE_OFFSET_SET_CURSOR;
617 RefreshText();
618 if (cursorAnimator_ != nullptr) {
619 static_cast<CursorAnimator*>(cursorAnimator_)->StartAnimator();
620 }
621 }
622
UpdateOffsetBySetCursorIndex()623 void UIEditText::UpdateOffsetBySetCursorIndex()
624 {
625 if (!inputText_) {
626 return;
627 }
628
629 uint16_t textWidth = GetTextWidthByCursorIndex(cursorIndex_);
630 Rect contentRect = GetContentRect();
631 int16_t newPosX = 0;
632 if (inputText_->GetDirect() == UITextLanguageDirect::TEXT_DIRECT_LTR) {
633 newPosX = contentRect.GetX() + textWidth + offsetX_;
634 if (newPosX <= contentRect.GetX()) {
635 offsetX_ = -(textWidth - DEFAULT_TEXT_OFFSET);
636 } else if (newPosX >= GetRect().GetRight()) {
637 offsetX_ = -(textWidth - GetRect().GetWidth() + BOTH_SIDE_TEXT_OFFSET);
638 }
639 }
640 }
641
DeleteBackward(uint32_t length)642 void UIEditText::DeleteBackward(uint32_t length)
643 {
644 if ((length == 0) || (textStr_.length() == 0) || (cursorIndex_ == 0)) {
645 return;
646 }
647 if (!inputText_) {
648 return;
649 }
650
651 std::string newText;
652 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convert;
653 std::wstring wideText = convert.from_bytes(textStr_);
654 if (length > wideText.size()) {
655 cursorIndex_ = 0;
656 } else {
657 uint32_t deleteLength = cursorIndex_ >= length ? length : length - cursorIndex_;
658 if (wideText.size() >= cursorIndex_) {
659 wideText.erase(cursorIndex_ - deleteLength, deleteLength);
660 }
661 newText = convert.to_bytes(wideText);
662 cursorIndex_ -= deleteLength;
663 deleteTextWidth_ = inputText_->GetNextCharacterFullDispalyOffset(GetContentRect(),
664 GetStyleConst(), cursorIndex_, deleteLength);
665 offsetState_ = UPDATE_OFFSET_DELETE;
666 }
667
668 SetText(newText);
669 if (cursorAnimator_ != nullptr) {
670 static_cast<CursorAnimator*>(cursorAnimator_)->StartAnimator();
671 }
672 }
673
UpdateInnerText()674 void UIEditText::UpdateInnerText()
675 {
676 InitText();
677 if (inputType_ == InputType::TEXT_TYPE) {
678 inputText_->SetText(GetInnerText().c_str());
679 } else {
680 inputText_->SetText(GetInnerPassword().c_str());
681 }
682 RefreshText();
683 }
684
SetMaxLength(uint16_t maxLength)685 void UIEditText::SetMaxLength(uint16_t maxLength)
686 {
687 InitText();
688 if (maxLength > MAX_TEXT_LENGTH) {
689 maxLength = MAX_TEXT_LENGTH;
690 }
691 maxLength_ = maxLength;
692 if (textStr_.length() > maxLength) {
693 SetText(textStr_.substr(0, maxLength));
694 }
695 }
696
GetMaxLength()697 uint16_t UIEditText::GetMaxLength()
698 {
699 return maxLength_;
700 }
701
SetInputType(InputType inputType)702 void UIEditText::SetInputType(InputType inputType)
703 {
704 if (inputType_ == inputType) {
705 return;
706 }
707 inputType_ = inputType;
708
709 // update view
710 UpdateInnerText();
711
712 offsetState_ = UPDATE_OFFSET_INPUT_TYPE;
713 }
714
UpdateOffsetByInputType()715 void UIEditText::UpdateOffsetByInputType()
716 {
717 if (!inputText_) {
718 return;
719 }
720
721 Rect contentRect = GetContentRect();
722 if (GetTextWidth() <= contentRect.GetWidth() - DEFAULT_TEXT_OFFSET) {
723 offsetX_ = DEFAULT_TEXT_OFFSET;
724 return;
725 }
726
727 if (cursorIndex_ == GetTextLength()) {
728 offsetX_ = -(GetTextWidth() - GetRect().GetWidth() + BOTH_SIDE_TEXT_OFFSET);
729 return;
730 }
731
732 if (offsetX_ + GetTextWidth() < contentRect.GetWidth() - DEFAULT_TEXT_OFFSET) {
733 offsetX_ = contentRect.GetWidth() - DEFAULT_TEXT_OFFSET - GetTextWidth();
734 return;
735 }
736
737 UpdateOffsetBySetCursorIndex();
738 }
739
CheckValueChange(std::string text)740 void UIEditText::CheckValueChange(std::string text)
741 {
742 if (onChangeListener_ == nullptr) {
743 return;
744 }
745
746 if (textStr_.compare(text) != 0) {
747 onChangeListener_->OnChange(*this, text.c_str());
748 }
749 }
750
GetTextLength()751 uint16_t UIEditText::GetTextLength()
752 {
753 if (inputText_ == nullptr) {
754 return 0;
755 }
756 return TypedText::GetUTF8CharacterSize(inputText_->GetText(),
757 std::string(inputText_->GetText()).length());
758 }
759 } // namespace OHOS
760