1 /*
2 * Copyright (c) 2021 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 "core/components/text_field/on_text_changed_listener_impl.h"
17
18 namespace OHOS::Ace {
19
InsertText(const std::u16string & text)20 void OnTextChangedListenerImpl::InsertText(const std::u16string& text)
21 {
22 if (text.length() <= 0) {
23 LOGE("the text is null");
24 return;
25 }
26
27 auto task = [textField = field_, text] {
28 auto client = textField.Upgrade();
29 if (!client) {
30 LOGE("text field is null");
31 return;
32 }
33 ContainerScope scope(client->instanceId_);
34 auto value = client->GetEditingValue();
35 auto textEditingValue = std::make_shared<TextEditingValue>();
36 textEditingValue->text =
37 value.GetBeforeSelection() + StringUtils::Str16ToStr8(text) + value.GetAfterSelection();
38 textEditingValue->UpdateSelection(std::max(value.selection.GetStart(), 0) + text.length());
39 client->UpdateEditingValue(textEditingValue, true);
40 };
41 PostTaskToUI(task);
42 }
43
DeleteBackward(int32_t length)44 void OnTextChangedListenerImpl::DeleteBackward(int32_t length)
45 {
46 LOGI("[OnTextChangedListenerImpl] DeleteBackward length: %{public}d", length);
47 if (length <= 0) {
48 LOGE("Delete nothing.");
49 return;
50 }
51
52 auto task = [textField = field_, length] {
53 auto client = textField.Upgrade();
54 if (!client) {
55 LOGE("text field is null");
56 return;
57 }
58 ContainerScope scope(client->instanceId_);
59 auto value = client->GetEditingValue();
60 auto start = value.selection.GetStart();
61 auto end = value.selection.GetEnd();
62 auto textEditingValue = std::make_shared<TextEditingValue>();
63 textEditingValue->text = value.text;
64 textEditingValue->UpdateSelection(start, end);
65 textEditingValue->Delete(start, start == end ? end + length : end);
66 client->UpdateEditingValue(textEditingValue, true);
67 };
68 PostTaskToUI(task);
69 }
70
DeleteForward(int32_t length)71 void OnTextChangedListenerImpl::DeleteForward(int32_t length)
72 {
73 LOGI("[OnTextChangedListenerImpl] DeleteForward length: %{public}d", length);
74 if (length <= 0) {
75 LOGE("Delete nothing.");
76 return;
77 }
78
79 auto task = [textField = field_, length] {
80 auto client = textField.Upgrade();
81 if (!client) {
82 LOGE("text field is null");
83 return;
84 }
85 ContainerScope scope(client->instanceId_);
86 auto value = client->GetEditingValue();
87 auto start = value.selection.GetStart();
88 auto end = value.selection.GetEnd();
89 auto textEditingValue = std::make_shared<TextEditingValue>();
90 textEditingValue->text = value.text;
91 textEditingValue->UpdateSelection(start, end);
92 textEditingValue->Delete(start == end ? start - length : start, end);
93 client->UpdateEditingValue(textEditingValue, true);
94 };
95 PostTaskToUI(task);
96 }
97
SetKeyboardStatus(bool status)98 void OnTextChangedListenerImpl::SetKeyboardStatus(bool status)
99 {
100 LOGI("[OnTextChangedListenerImpl] SetKeyboardStatus status: %{public}d", status);
101 auto task = [textField = field_, status] {
102 auto client = textField.Upgrade();
103 if (client) {
104 ContainerScope scope(client->instanceId_);
105 client->SetInputMethodStatus(status);
106 }
107 };
108 PostTaskToUI(task);
109 }
110
SendKeyEventFromInputMethod(const MiscServices::KeyEvent & event)111 void OnTextChangedListenerImpl::SendKeyEventFromInputMethod(const MiscServices::KeyEvent& event) {}
112
SendKeyboardInfo(const MiscServices::KeyboardInfo & info)113 void OnTextChangedListenerImpl::SendKeyboardInfo(const MiscServices::KeyboardInfo& info)
114 {
115 HandleKeyboardStatus(info.GetKeyboardStatus());
116 HandleFunctionKey(info.GetFunctionKey());
117 }
118
HandleKeyboardStatus(MiscServices::KeyboardStatus status)119 void OnTextChangedListenerImpl::HandleKeyboardStatus(MiscServices::KeyboardStatus status)
120 {
121 LOGI("[OnTextChangedListenerImpl] HandleKeyboardStatus status: %{public}d", status);
122 if (status == MiscServices::KeyboardStatus::NONE) {
123 return;
124 }
125 SetKeyboardStatus(status == MiscServices::KeyboardStatus::SHOW);
126 }
127
HandleFunctionKey(MiscServices::FunctionKey functionKey)128 void OnTextChangedListenerImpl::HandleFunctionKey(MiscServices::FunctionKey functionKey)
129 {
130 auto task = [textField = field_, functionKey] {
131 auto client = textField.Upgrade();
132 if (!client) {
133 LOGE("text field is null");
134 return;
135 }
136 ContainerScope scope(client->instanceId_);
137 TextInputAction action_ = static_cast<TextInputAction>(functionKey);
138 switch (action_) {
139 case TextInputAction::DONE:
140 case TextInputAction::NEXT:
141 case TextInputAction::SEARCH:
142 case TextInputAction::SEND:
143 case TextInputAction::GO:
144 client->PerformAction(action_);
145 break;
146 default:
147 LOGE("TextInputAction is not support: %{public}d", action_);
148 break;
149 }
150 };
151 PostTaskToUI(task);
152 }
153
MoveCursor(MiscServices::Direction direction)154 void OnTextChangedListenerImpl::MoveCursor(MiscServices::Direction direction)
155 {
156 auto task = [textField = field_, direction] {
157 auto client = textField.Upgrade();
158 if (!client) {
159 return;
160 }
161 ContainerScope scope(client->instanceId_);
162 switch (direction) {
163 case MiscServices::Direction::UP:
164 client->CursorMoveUp();
165 break;
166 case MiscServices::Direction::DOWN:
167 client->CursorMoveDown();
168 break;
169 case MiscServices::Direction::LEFT:
170 client->CursorMoveLeft();
171 break;
172 case MiscServices::Direction::RIGHT:
173 client->CursorMoveRight();
174 break;
175 default:
176 LOGE("direction is not support: %{public}d", direction);
177 break;
178 }
179 };
180 PostTaskToUI(task);
181 }
182
PostTaskToUI(const std::function<void ()> & task)183 void OnTextChangedListenerImpl::PostTaskToUI(const std::function<void()>& task)
184 {
185 if (!task) {
186 LOGE("task is empty");
187 return;
188 }
189 auto renderTextField = field_.Upgrade();
190 if (!renderTextField) {
191 LOGE("text field is null");
192 return;
193 }
194
195 auto context = renderTextField->GetContext().Upgrade();
196 if (!context) {
197 LOGE("context is null");
198 return;
199 }
200
201 auto taskExecutor = context->GetTaskExecutor();
202 if (!taskExecutor) {
203 LOGE("task executor is null");
204 return;
205 }
206
207 taskExecutor->PostTask(task, TaskExecutor::TaskType::UI);
208 }
209
210 } // namespace OHOS::Ace
211