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