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