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