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