• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_FIELD_TEXT_FIELD_EVENT_HUB_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_FIELD_TEXT_FIELD_EVENT_HUB_H
18 
19 #include <cstdint>
20 #include <utility>
21 
22 #include "base/memory/ace_type.h"
23 #include "base/utils/noncopyable.h"
24 #include "base/utils/utf_helper.h"
25 #include "core/common/ime/text_range.h"
26 #include "core/components_ng/event/event_hub.h"
27 #include "core/components_ng/pattern/scrollable/scrollable_properties.h"
28 
29 namespace OHOS::Ace {
30 enum class TextDeleteDirection { BACKWARD = 0, FORWARD = 1 };
31 
32 struct InsertValueInfo {
33     int32_t insertOffset = 0;
34     std::u16string insertValue;
35 };
36 
37 struct DeleteValueInfo {
38     int32_t deleteOffset = 0;
39     TextDeleteDirection direction = TextDeleteDirection::BACKWARD;
40     std::u16string deleteValue;
41 };
42 
43 struct PreviewText {
44     int32_t offset;
45     std::u16string value;
46 
47     bool operator==(const PreviewText& other) const
48     {
49         return this->offset == other.offset && this->value == other.value;
50     }
51 
52     bool operator!=(const PreviewText& other) const
53     {
54         return this->offset != other.offset || this->value != other.value;
55     }
56 };
57 
58 struct ChangeValueInfo {
59     std::u16string value;
60     PreviewText previewText;
61     TextRange rangeBefore;
62     TextRange rangeAfter;
63     std::u16string oldContent;
64     PreviewText oldPreviewText;
65 };
66 } // namespace OHOS::Ace
67 
68 namespace OHOS::Ace::NG {
69 class TextFieldCommonEvent : public BaseEventInfo {
DECLARE_RELATIONSHIP_OF_CLASSES(TextFieldCommonEvent,BaseEventInfo)70     DECLARE_RELATIONSHIP_OF_CLASSES(TextFieldCommonEvent, BaseEventInfo)
71 public:
72     TextFieldCommonEvent() : BaseEventInfo("TextFieldCommonEvent") {}
73     ~TextFieldCommonEvent() override = default;
74 
IsKeepEditable()75     bool IsKeepEditable() const
76     {
77         return keepEditable_;
78     }
SetKeepEditable(bool keepEditable)79     void SetKeepEditable(bool keepEditable)
80     {
81         keepEditable_ = keepEditable;
82     }
GetText()83     std::u16string GetText() const
84     {
85         return text_;
86     }
SetText(std::u16string text)87     void SetText(std::u16string text)
88     {
89         text_ = text;
90     }
91 private:
92     bool keepEditable_ = false;
93     std::u16string text_;
94 };
95 
96 class TextFieldEventHub : public EventHub {
97     DECLARE_ACE_TYPE(TextFieldEventHub, EventHub)
98 
99 public:
100     TextFieldEventHub() = default;
101     ~TextFieldEventHub() override = default;
102 
SetOnInputFilterError(const std::function<void (const std::u16string &)> & onInputFilterError)103     void SetOnInputFilterError(const std::function<void(const std::u16string&)>& onInputFilterError)
104     {
105         onInputFilterError_ = onInputFilterError;
106     }
107 
FireOnInputFilterError(const std::u16string & value)108     void FireOnInputFilterError(const std::u16string& value) const
109     {
110         if (onInputFilterError_) {
111             TAG_LOGI(AceLogTag::ACE_TEXT_FIELD, "On filter error size %{public}zu",
112                 UtfUtils::Str16DebugToStr8(value).size());
113             onInputFilterError_(value);
114         }
115     }
116 
SetOnEditChanged(std::function<void (bool)> && func)117     void SetOnEditChanged(std::function<void(bool)>&& func)
118     {
119         onEditChanged_ = std::move(func);
120     }
121 
SetOnSecurityStateChange(std::function<void (bool)> && func)122     void SetOnSecurityStateChange(std::function<void(bool)>&& func)
123     {
124         onSecurityStateChanged_ = std::move(func);
125     }
126 
FireOnSecurityStateChanged(bool value)127     void FireOnSecurityStateChanged(bool value)
128     {
129         if (onSecurityStateChanged_) {
130             TAG_LOGI(AceLogTag::ACE_TEXT_FIELD, "FireOnSecurityStateChanged %{public}d", value);
131             onSecurityStateChanged_(value);
132         }
133     }
134 
FireOnEditChanged(bool value)135     void FireOnEditChanged(bool value)
136     {
137         if (onEditChanged_) {
138             TAG_LOGI(AceLogTag::ACE_TEXT_FIELD, "On edit change %{private}d", value);
139             onEditChanged_(value);
140         }
141     }
142 
SetOnSubmit(std::function<void (int32_t,NG::TextFieldCommonEvent &)> && func)143     void SetOnSubmit(std::function<void(int32_t, NG::TextFieldCommonEvent&)>&& func)
144     {
145         onSubmit_ = std::move(func);
146     }
147 
FireOnSubmit(int32_t value,NG::TextFieldCommonEvent & event)148     void FireOnSubmit(int32_t value, NG::TextFieldCommonEvent& event)
149     {
150         if (onSubmit_) {
151             TAG_LOGI(AceLogTag::ACE_TEXT_FIELD, "On submit %{private}d", value);
152             onSubmit_(value, event);
153         }
154     }
155 
SetOnChange(std::function<void (const ChangeValueInfo &)> && func)156     void SetOnChange(std::function<void(const ChangeValueInfo&)>&& func)
157     {
158         onChange_ = std::move(func);
159     }
160 
GetOnChange()161     const std::function<void(const ChangeValueInfo&)>& GetOnChange() const
162     {
163         return onChange_;
164     }
165 
FireOnChange(const ChangeValueInfo & info)166     void FireOnChange(const ChangeValueInfo& info)
167     {
168         if (lastValue_.has_value() && lastValue_.value() == info.value && lastPreviewText_ == info.previewText) {
169             return;
170         }
171         if (onValueChangeEvent_) {
172             TAG_LOGI(
173                 AceLogTag::ACE_TEXT_FIELD, "On change event, len:%{public}d",
174                 static_cast<int32_t>(info.value.length()));
175             onValueChangeEvent_(info.value);
176         }
177         if (onChange_) {
178             TAG_LOGI(AceLogTag::ACE_TEXT_FIELD, "On change previewText, len:%{public}d, index:%{private}d",
179                 static_cast<int32_t>(info.previewText.value.length()), info.previewText.offset);
180             // Not all in one, in order to fix the cppcrash bug
181             auto onChange = onChange_;
182             onChange(info);
183         }
184         lastValue_ = info.value;
185         lastPreviewText_ = info.previewText;
186     }
187 
SetOnContentSizeChange(std::function<void (float,float)> && func)188     void SetOnContentSizeChange(std::function<void(float, float)>&& func)
189     {
190         onContentSizeChange_ = std::move(func);
191     }
192 
GetOnContentSizeChange()193     const std::function<void(float, float)>& GetOnContentSizeChange() const
194     {
195         return onContentSizeChange_;
196     }
197 
FireOnContentSizeChange(float width,float height)198     void FireOnContentSizeChange(float width, float height)
199     {
200         if (onContentSizeChange_) {
201             onContentSizeChange_(width, height);
202         }
203     }
204 
SetOnSelectionChange(std::function<void (int32_t,int32_t)> && func)205     void SetOnSelectionChange(std::function<void(int32_t, int32_t)>&& func)
206     {
207         onSelectionChange_ = std::move(func);
208     }
209 
FireOnSelectionChange(int32_t selectionStart,int32_t selectionEnd)210     void FireOnSelectionChange(int32_t selectionStart, int32_t selectionEnd)
211     {
212         if (onSelectionChange_) {
213             TAG_LOGI(AceLogTag::ACE_TEXT_FIELD, "On selection change start %{private}d, end %{private}d",
214                 selectionStart, selectionEnd);
215             onSelectionChange_(selectionStart, selectionEnd);
216         }
217     }
218 
SetOnCopy(std::function<void (const std::u16string &)> && func)219     void SetOnCopy(std::function<void(const std::u16string&)>&& func)
220     {
221         onCopy_ = std::move(func);
222     }
223 
FireOnCopy(const std::u16string & value)224     void FireOnCopy(const std::u16string& value)
225     {
226         if (onCopy_) {
227             TAG_LOGI(AceLogTag::ACE_TEXT_FIELD, "On copy size %{public}zu", UtfUtils::Str16DebugToStr8(value).size());
228             onCopy_(value);
229         }
230     }
231 
SetOnCut(std::function<void (const std::u16string &)> && func)232     void SetOnCut(std::function<void(const std::u16string&)>&& func)
233     {
234         onCut_ = std::move(func);
235     }
236 
FireOnCut(const std::u16string & value)237     void FireOnCut(const std::u16string& value)
238     {
239         if (onCut_) {
240             TAG_LOGI(AceLogTag::ACE_TEXT_FIELD, "On cut size %{public}zu", UtfUtils::Str16DebugToStr8(value).size());
241             onCut_(value);
242         }
243     }
244 
SetOnPaste(std::function<void (const std::u16string &)> && func)245     void SetOnPaste(std::function<void(const std::u16string&)>&& func)
246     {
247         onPaste_ = std::move(func);
248     }
249 
FireOnPaste(const std::u16string & value)250     void FireOnPaste(const std::u16string& value)
251     {
252         if (onPaste_) {
253             TAG_LOGI(AceLogTag::ACE_TEXT_FIELD, "On paste size %{public}zu", UtfUtils::Str16DebugToStr8(value).size());
254             onPaste_(value);
255         }
256     }
257 
SetOnPasteWithEvent(std::function<void (const std::u16string &,NG::TextCommonEvent &)> && func)258     void SetOnPasteWithEvent(std::function<void(const std::u16string&, NG::TextCommonEvent&)>&& func)
259     {
260         onPasteWithEvent_ = std::move(func);
261     }
262 
FireOnPasteWithEvent(const std::u16string & value,NG::TextCommonEvent & event)263     void FireOnPasteWithEvent(const std::u16string& value, NG::TextCommonEvent& event)
264     {
265         if (onPasteWithEvent_) {
266             onPasteWithEvent_(value, event);
267         }
268     }
269 
SetOnScroll(OnScrollEvent && onScroll)270     void SetOnScroll(OnScrollEvent&& onScroll)
271     {
272         onScrollEvent_ = std::move(onScroll);
273     }
274 
GetOnScroll()275     const OnScrollEvent& GetOnScroll() const
276     {
277         return onScrollEvent_;
278     }
279 
SetOnScrollBegin(OnScrollBeginEvent && onScrollBegin)280     void SetOnScrollBegin(OnScrollBeginEvent&& onScrollBegin)
281     {
282         onScrollBeginEvent_ = std::move(onScrollBegin);
283     }
284 
GetOnScrollBegin()285     const OnScrollBeginEvent& GetOnScrollBegin() const
286     {
287         return onScrollBeginEvent_;
288     }
289 
SetOnScrollFrameBegin(OnScrollFrameBeginEvent && onScrollFrameBegin)290     void SetOnScrollFrameBegin(OnScrollFrameBeginEvent&& onScrollFrameBegin)
291     {
292         onScrollFrameBeginEvent_ = std::move(onScrollFrameBegin);
293     }
294 
GetOnScrollFrameBegin()295     const OnScrollFrameBeginEvent& GetOnScrollFrameBegin() const
296     {
297         return onScrollFrameBeginEvent_;
298     }
299 
SetOnScrollStart(OnScrollStartEvent && onScrollStart)300     void SetOnScrollStart(OnScrollStartEvent&& onScrollStart)
301     {
302         onScrollStartEvent_ = std::move(onScrollStart);
303     }
304 
GetOnScrollStart()305     const OnScrollStartEvent& GetOnScrollStart() const
306     {
307         return onScrollStartEvent_;
308     }
309 
SetOnScrollStop(OnScrollStopEvent && onScrollStop)310     void SetOnScrollStop(OnScrollStopEvent&& onScrollStop)
311     {
312         onScrollStopEvent_ = std::move(onScrollStop);
313     }
314 
GetOnScrollStop()315     const OnScrollStopEvent& GetOnScrollStop() const
316     {
317         return onScrollStopEvent_;
318     }
319 
SetOnScrollIndex(OnScrollIndexEvent && onScrollIndex)320     void SetOnScrollIndex(OnScrollIndexEvent&& onScrollIndex)
321     {
322         onScrollIndexEvent_ = std::move(onScrollIndex);
323     }
324 
GetOnScrollIndex()325     const OnScrollIndexEvent& GetOnScrollIndex() const
326     {
327         return onScrollIndexEvent_;
328     }
329 
SetOnWillChangeEvent(std::function<bool (const ChangeValueInfo &)> && func)330     void SetOnWillChangeEvent(std::function<bool(const ChangeValueInfo&)>&& func)
331     {
332         onWillChangeEvent_ = std::move(func);
333     }
334 
FireOnWillChangeEvent(const ChangeValueInfo & info)335     bool FireOnWillChangeEvent(const ChangeValueInfo& info)
336     {
337         if (onWillChangeEvent_) {
338             return onWillChangeEvent_(info);
339         }
340         return true;
341     }
342 
SetOnChangeEvent(std::function<void (const std::u16string &)> && func)343     void SetOnChangeEvent(std::function<void(const std::u16string&)>&& func)
344     {
345         onValueChangeEvent_ = std::move(func);
346     }
347 
SetOnScrollChangeEvent(std::function<void (float,float)> && func)348     void SetOnScrollChangeEvent(std::function<void(float, float)>&& func)
349     {
350         onScrollChangeEvent_ = std::move(func);
351     }
352 
FireOnScrollChangeEvent(float offsetX,float offsetY)353     void FireOnScrollChangeEvent(float offsetX, float offsetY)
354     {
355         if (onScrollChangeEvent_) {
356             onScrollChangeEvent_(offsetX, offsetY);
357         }
358     }
359 
SetOnWillInsertValueEvent(std::function<bool (const InsertValueInfo &)> && func)360     void SetOnWillInsertValueEvent(std::function<bool(const InsertValueInfo&)>&& func)
361     {
362         onWillInsertValueEvent_ = std::move(func);
363     }
364 
FireOnWillInsertValueEvent(const InsertValueInfo & info)365     bool FireOnWillInsertValueEvent(const InsertValueInfo& info)
366     {
367         if (onWillInsertValueEvent_) {
368             TAG_LOGI(AceLogTag::ACE_TEXT_FIELD, "OnWillInsertValueEvent len:%{public}d,offset:%{public}d",
369                 static_cast<int32_t>(info.insertValue.length()), info.insertOffset);
370             return onWillInsertValueEvent_(info);
371         }
372         return true;
373     }
374 
SetOnDidInsertValueEvent(std::function<void (const InsertValueInfo &)> && func)375     void SetOnDidInsertValueEvent(std::function<void(const InsertValueInfo&)>&& func)
376     {
377         onDidInsertValueEvent_ = std::move(func);
378     }
379 
FireOnDidInsertValueEvent(const InsertValueInfo & info)380     void FireOnDidInsertValueEvent(const InsertValueInfo& info)
381     {
382         if (onDidInsertValueEvent_) {
383             TAG_LOGI(AceLogTag::ACE_TEXT_FIELD, "OnDidInsertValueEvent len:%{public}d,offset:%{public}d",
384                 static_cast<int32_t>(info.insertValue.length()), info.insertOffset);
385             onDidInsertValueEvent_(info);
386         }
387     }
388 
SetOnWillDeleteEvent(std::function<bool (const DeleteValueInfo &)> && func)389     void SetOnWillDeleteEvent(std::function<bool(const DeleteValueInfo&)>&& func)
390     {
391         onWillDeleteEvent_ = std::move(func);
392     }
393 
FireOnWillDeleteEvent(const DeleteValueInfo & info)394     bool FireOnWillDeleteEvent(const DeleteValueInfo& info)
395     {
396         if (onWillDeleteEvent_) {
397             TAG_LOGI(AceLogTag::ACE_TEXT_FIELD, "OnWillDeleteEvent len:%{public}d,offset:%{public}d",
398                 static_cast<int32_t>(info.deleteValue.length()), info.deleteOffset);
399             return onWillDeleteEvent_(info);
400         }
401         return true;
402     }
403 
SetOnDidDeleteEvent(std::function<void (const DeleteValueInfo &)> && func)404     void SetOnDidDeleteEvent(std::function<void(const DeleteValueInfo&)>&& func)
405     {
406         onDidDeleteEvent_ = std::move(func);
407     }
408 
FireOnDidDeleteValueEvent(const DeleteValueInfo & info)409     void FireOnDidDeleteValueEvent(const DeleteValueInfo& info)
410     {
411         if (onDidDeleteEvent_) {
412             TAG_LOGI(AceLogTag::ACE_TEXT_FIELD, "OnDidDeleteValueEvent len:%{public}d,offset:%{public}d",
413                 static_cast<int32_t>(info.deleteValue.length()), info.deleteOffset);
414             onDidDeleteEvent_(info);
415         }
416     }
417 
418 private:
419     std::optional<std::u16string> lastValue_;
420     PreviewText lastPreviewText_ {};
421 
422     OnScrollEvent onScrollEvent_;
423     OnScrollBeginEvent onScrollBeginEvent_;
424     OnScrollFrameBeginEvent onScrollFrameBeginEvent_;
425     OnScrollStartEvent onScrollStartEvent_;
426     OnScrollStopEvent onScrollStopEvent_;
427     OnScrollIndexEvent onScrollIndexEvent_;
428     std::function<void(float, float)> onScrollChangeEvent_;
429 
430     std::function<void(const std::u16string&)> onInputFilterError_;
431     std::function<void(bool)> onEditChanged_;
432     std::function<void(bool)> onSecurityStateChanged_;
433     std::function<void(int32_t, NG::TextFieldCommonEvent&)> onSubmit_;
434     std::function<void(const ChangeValueInfo&)> onChange_;
435     std::function<void(float, float)> onContentSizeChange_;
436     std::function<void(int32_t, int32_t)> onSelectionChange_;
437 
438     std::function<void(const std::u16string&)> onCopy_;
439     std::function<void(const std::u16string&)> onCut_;
440     std::function<void(const std::u16string&)> onPaste_;
441     std::function<void(const std::u16string&, NG::TextCommonEvent&)> onPasteWithEvent_;
442     std::function<bool(const ChangeValueInfo&)> onWillChangeEvent_;
443     std::function<void(const std::u16string&)> onValueChangeEvent_;
444 
445     std::function<bool(const InsertValueInfo&)> onWillInsertValueEvent_;
446     std::function<void(const InsertValueInfo&)> onDidInsertValueEvent_;
447     std::function<bool(const DeleteValueInfo&)> onWillDeleteEvent_;
448     std::function<void(const DeleteValueInfo&)> onDidDeleteEvent_;
449     ACE_DISALLOW_COPY_AND_MOVE(TextFieldEventHub);
450 };
451 
452 } // namespace OHOS::Ace::NG
453 
454 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_FIELD_TEXT_FIELD_EVENT_HUB_H
455