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