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