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