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_SELECT_OVERLAY_PROPERTY_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SELECT_OVERLAY_PROPERTY_H 18 19 #include <cstdint> 20 #include <functional> 21 #include <vector> 22 23 #include "base/geometry/ng/offset_t.h" 24 #include "base/geometry/ng/point_t.h" 25 #include "base/geometry/ng/rect_t.h" 26 #include "core/components_ng/event/gesture_event_hub.h" 27 #include "core/components_ng/pattern/text/text_menu_extension.h" 28 #include "core/event/ace_events.h" 29 #include "core/event/touch_event.h" 30 #include "frameworks/core/components_ng/pattern/pattern.h" 31 #include "frameworks/core/components_ng/manager/safe_area/safe_area_manager.h" 32 33 namespace OHOS::Ace::NG { 34 35 constexpr int32_t MENU_SHOW_ANIMATION_DURATION = 250; 36 constexpr int32_t MENU_HIDE_ANIMATION_DURATION = 200; 37 constexpr int32_t HANDLE_ANIMATION_DURATION = 150; 38 39 struct OnMenuItemCallback { 40 OnCreateMenuCallback onCreateMenuCallback; 41 OnMenuItemClickCallback onMenuItemClick; 42 OnPrepareMenuCallback onPrepareMenuCallback; 43 std::function<void(int32_t&, int32_t&)> textRangeCallback; 44 std::function<void()> beforeOnPrepareMenuCallback; 45 }; 46 47 struct SelectHandlePaintInfo { 48 OffsetF startPoint; 49 OffsetF endPoint; 50 float width = 0.0f; 51 52 SelectHandlePaintInfo operator-(const OffsetF& offset) const 53 { 54 return { 55 .startPoint = startPoint - offset, 56 .endPoint = endPoint - offset, 57 .width = width 58 }; 59 } 60 61 SelectHandlePaintInfo operator+(const OffsetF& offset) const 62 { 63 return { 64 .startPoint = startPoint + offset, 65 .endPoint = endPoint + offset, 66 .width = width 67 }; 68 } 69 70 bool operator==(const SelectHandlePaintInfo& info) const 71 { 72 return (startPoint == info.startPoint) && (endPoint == info.endPoint) && (width == info.width); 73 } 74 75 bool operator!=(const SelectHandlePaintInfo& info) const 76 { 77 return !(*this == info); 78 } 79 }; 80 81 struct SelectHandleInfo { 82 bool isShow = true; 83 bool needLayout = false; 84 bool isPaintHandleWithPoints = false; 85 bool isCircleShow = true; 86 bool forceDraw = false; 87 bool isTouchable = true; 88 // in Global coordinates. 89 RectF paintRect; 90 RectF localPaintRect; 91 SelectHandlePaintInfo paintInfo; 92 std::function<RectF(const SelectHandlePaintInfo&)> paintInfoConverter; 93 94 bool operator==(const SelectHandleInfo& info) const 95 { 96 return (isShow == info.isShow) && (paintRect == info.paintRect) && (paintInfo == info.paintInfo) && 97 (localPaintRect == info.localPaintRect); 98 } 99 100 bool operator!=(const SelectHandleInfo& info) const 101 { 102 return !(*this == info); 103 } 104 GetPaintRectSelectHandleInfo105 const RectF GetPaintRect() const 106 { 107 if (isPaintHandleWithPoints) { 108 auto offsetX = std::max(paintInfo.startPoint.GetX(), paintInfo.endPoint.GetX()); 109 auto offsetY = std::min(paintInfo.startPoint.GetY(), paintInfo.endPoint.GetY()); 110 auto height = paintInfo.endPoint.GetY() - paintInfo.startPoint.GetY(); 111 return RectF(OffsetF(offsetX, offsetY), SizeF(paintInfo.width, std::abs(height))); 112 } 113 return paintRect; 114 } 115 116 static Dimension GetDefaultLineWidth(); 117 ToStringSelectHandleInfo118 std::string ToString() const 119 { 120 auto jsonValue = JsonUtil::Create(true); 121 JSON_STRING_PUT_BOOL(jsonValue, isShow); 122 JSON_STRING_PUT_BOOL(jsonValue, needLayout); 123 JSON_STRING_PUT_STRINGABLE(jsonValue, paintRect); 124 JSON_STRING_PUT_STRINGABLE(jsonValue, localPaintRect); 125 return jsonValue->ToString(); 126 } 127 }; 128 129 using SelectOverlayDirtyFlag = uint32_t; 130 inline constexpr SelectOverlayDirtyFlag DIRTY_FIRST_HANDLE = 1; 131 inline constexpr SelectOverlayDirtyFlag DIRTY_SECOND_HANDLE = 1 << 1; 132 inline constexpr SelectOverlayDirtyFlag DIRTY_SELECT_AREA = 1 << 2; 133 inline constexpr SelectOverlayDirtyFlag DIRTY_ALL_MENU_ITEM = 1 << 3; 134 inline constexpr SelectOverlayDirtyFlag DIRTY_COPY_ALL_ITEM = 1 << 4; 135 inline constexpr SelectOverlayDirtyFlag DIRTY_SELECT_TEXT = 1 << 5; 136 inline constexpr SelectOverlayDirtyFlag DIRTY_VIEWPORT = 1 << 6; 137 inline constexpr SelectOverlayDirtyFlag DIRTY_HANDLE_COLOR_FLAG = 1 << 7; 138 inline constexpr SelectOverlayDirtyFlag DIRTY_AI_MENU_ITEM = 1 << 8; 139 inline constexpr SelectOverlayDirtyFlag DIRTY_ASK_CELIA = 1 << 9; 140 inline constexpr SelectOverlayDirtyFlag DIRTY_DOUBLE_HANDLE = DIRTY_FIRST_HANDLE | DIRTY_SECOND_HANDLE; 141 inline constexpr SelectOverlayDirtyFlag DIRTY_ALL = 142 DIRTY_DOUBLE_HANDLE | DIRTY_ALL_MENU_ITEM | DIRTY_SELECT_AREA | DIRTY_SELECT_TEXT | DIRTY_VIEWPORT; 143 144 inline constexpr int32_t REQUEST_RECREATE = 1; 145 146 using SystemServiceMenuDisableFlag = uint32_t; 147 inline constexpr SystemServiceMenuDisableFlag DISABLE_NORMAL_FLAG = 0; 148 inline constexpr SystemServiceMenuDisableFlag DISABLE_ALL_FLAG = 1; 149 inline constexpr SystemServiceMenuDisableFlag DISABLE_TRANSLATE_FLAG = 1 << 1; 150 inline constexpr SystemServiceMenuDisableFlag DISABLE_SEARCH_FLAG = 1 << 2; 151 inline constexpr SystemServiceMenuDisableFlag DISABLE_SHARE_FLAG = 1 << 3; 152 inline constexpr SystemServiceMenuDisableFlag DISABLE_CAMERA_INPUT_FLAG = 1 << 4; 153 inline constexpr SystemServiceMenuDisableFlag DISABLE_AI_WRITER_FLAG = 1 << 5; 154 inline constexpr SystemServiceMenuDisableFlag DISABLE_COLLABORATION_SERVICE_FLAG = 1 << 6; 155 inline constexpr SystemServiceMenuDisableFlag DISABLE_AI_MENU_PHONE_FLAG = 1 << 7; 156 inline constexpr SystemServiceMenuDisableFlag DISABLE_AI_MENU_URL_FLAG = 1 << 8; 157 inline constexpr SystemServiceMenuDisableFlag DISABLE_AI_MENU_EMAIL_FLAG = 1 << 9; 158 inline constexpr SystemServiceMenuDisableFlag DISABLE_AI_MENU_ADDRESS_FLAG = 1 << 10; 159 inline constexpr SystemServiceMenuDisableFlag DISABLE_AI_MENU_DATETIME_FLAG = 1 << 11; 160 inline constexpr SystemServiceMenuDisableFlag DISABLE_ASK_CELIA_FLAG = 1 << 12; 161 162 inline constexpr char OH_DEFAULT_CUT[] = "OH_DEFAULT_CUT"; 163 inline constexpr char OH_DEFAULT_COPY[] = "OH_DEFAULT_COPY"; 164 inline constexpr char OH_DEFAULT_PASTE[] = "OH_DEFAULT_PASTE"; 165 inline constexpr char OH_DEFAULT_SELECT_ALL[] = "OH_DEFAULT_SELECT_ALL"; 166 inline constexpr char OH_DEFAULT_TRANSLATE[] = "OH_DEFAULT_TRANSLATE"; 167 inline constexpr char OH_DEFAULT_SEARCH[] = "OH_DEFAULT_SEARCH"; 168 inline constexpr char OH_DEFAULT_SHARE[] = "OH_DEFAULT_SHARE"; 169 inline constexpr char OH_DEFAULT_CAMERA_INPUT[] = "OH_DEFAULT_CAMERA_INPUT"; 170 inline constexpr char OH_DEFAULT_AI_WRITE[] = "OH_DEFAULT_AI_WRITE"; 171 inline constexpr char OH_DEFAULT_AI_MENU_PHONE[] = "OH_DEFAULT_AI_MENU_PHONE"; 172 inline constexpr char OH_DEFAULT_AI_MENU_URL[] = "OH_DEFAULT_AI_MENU_URL"; 173 inline constexpr char OH_DEFAULT_AI_MENU_EMAIL[] = "OH_DEFAULT_AI_MENU_EMAIL"; 174 inline constexpr char OH_DEFAULT_AI_MENU_ADDRESS[] = "OH_DEFAULT_AI_MENU_ADDRESS"; 175 inline constexpr char OH_DEFAULT_AI_MENU_DATETIME[] = "OH_DEFAULT_AI_MENU_DATETIME"; 176 inline constexpr char OH_DEFAULT_ASK_CELIA[] = "OH_DEFAULT_ASK_CELIA"; 177 178 inline constexpr char OH_DEFAULT_COLLABORATION_SERVICE[] = "OH_DEFAULT_COLLABORATION_SERVICE"; 179 180 enum class OptionMenuType { NO_MENU, MOUSE_MENU, TOUCH_MENU }; 181 enum class OptionMenuActionId { 182 COPY, 183 CUT, 184 PASTE, 185 SELECT_ALL, 186 TRANSLATE, 187 SHARE, 188 SEARCH, 189 CAMERA_INPUT, 190 AI_WRITE, 191 APPEAR, 192 DISAPPEAR, 193 AI_MENU_OPTION, 194 ASK_CELIA 195 }; 196 enum class CloseReason { 197 CLOSE_REASON_NORMAL = 1, 198 CLOSE_REASON_HOLD_BY_OTHER, 199 CLOSE_REASON_BY_RECREATE, 200 CLOSE_REASON_TOOL_BAR, 201 CLOSE_REASON_BACK_PRESSED, 202 CLOSE_REASON_CLICK_OUTSIDE, 203 CLOSE_REASON_DRAG_FLOATING, 204 CLOSE_REASON_WINDOW_SIZE_CHANGE, 205 CLOSE_REASON_SELECT_ALL 206 }; 207 208 struct HoldSelectionInfo { 209 std::function<bool(const PointF&, bool)> checkTouchInArea; 210 std::function<void()> resetSelectionCallback; 211 std::function<bool(SourceType, TouchType)> eventFilter; 212 IsAcceptEventHoldSelectionInfo213 bool IsAcceptEvent(SourceType sourceType, TouchType touchType) 214 { 215 if (eventFilter) { 216 return eventFilter(sourceType, touchType); 217 } 218 return sourceType == SourceType::MOUSE && touchType == TouchType::DOWN; 219 } 220 }; 221 222 // end SelectOverlayManagerNG 223 224 struct SelectMenuInfo { 225 bool menuDisable = false; 226 bool menuIsShow = false; 227 bool singleHandleMenuIsShow = false; 228 bool showCopy = true; 229 bool showPaste = true; 230 bool showCopyAll = true; 231 bool showCut = true; 232 bool showTranslate = false; 233 bool showShare = false; 234 bool showSearch = false; 235 bool showCameraInput = false; 236 bool showAIWrite = false; 237 bool hasOnPrepareMenuCallback = false; 238 OHOS::Ace::TextDataDetectType aiMenuOptionType = TextDataDetectType::INVALID; 239 std::optional<OffsetF> menuOffset; 240 OptionMenuType menuType = OptionMenuType::TOUCH_MENU; 241 bool isAskCeliaEnabled = false; 242 bool isShowAIMenuOptionChanged = false; 243 244 // Customize menu information. 245 std::optional<int32_t> responseType; 246 std::optional<int32_t> editorType; 247 std::function<void()> menuBuilder; 248 IsIconChangedSelectMenuInfo249 bool IsIconChanged(const SelectMenuInfo& info) const 250 { 251 if (menuBuilder != nullptr || info.menuBuilder != nullptr) { 252 return true; 253 } 254 return !((showCopy == info.showCopy) && (showPaste == info.showPaste) && (showCopyAll == info.showCopyAll) && 255 (showCut == info.showCut) && (showTranslate == info.showTranslate) && 256 (showSearch == info.showSearch) && (showShare == info.showShare) && 257 (showCameraInput == info.showCameraInput) && (showAIWrite == info.showAIWrite) && 258 (aiMenuOptionType == info.aiMenuOptionType) && !info.hasOnPrepareMenuCallback && 259 (isAskCeliaEnabled == info.isAskCeliaEnabled)); 260 } 261 ToStringSelectMenuInfo262 std::string ToString() const 263 { 264 auto jsonValue = JsonUtil::Create(true); 265 JSON_STRING_PUT_BOOL(jsonValue, menuDisable); 266 JSON_STRING_PUT_BOOL(jsonValue, menuIsShow); 267 JSON_STRING_PUT_BOOL(jsonValue, singleHandleMenuIsShow); 268 JSON_STRING_PUT_BOOL(jsonValue, showCopy); 269 JSON_STRING_PUT_BOOL(jsonValue, showPaste); 270 JSON_STRING_PUT_BOOL(jsonValue, showCopyAll); 271 JSON_STRING_PUT_BOOL(jsonValue, showCut); 272 JSON_STRING_PUT_BOOL(jsonValue, showTranslate); 273 JSON_STRING_PUT_BOOL(jsonValue, showSearch); 274 JSON_STRING_PUT_BOOL(jsonValue, showShare); 275 JSON_STRING_PUT_BOOL(jsonValue, showCameraInput); 276 JSON_STRING_PUT_INT(jsonValue, aiMenuOptionType); 277 JSON_STRING_PUT_INT(jsonValue, hasOnPrepareMenuCallback); 278 JSON_STRING_PUT_INT(jsonValue, isAskCeliaEnabled); 279 return jsonValue->ToString(); 280 } 281 }; 282 283 struct SelectMenuCallback { 284 std::function<void()> onCopy; 285 std::function<void()> onPaste; 286 std::function<void()> onSelectAll; 287 std::function<void()> onCut; 288 std::function<void()> onTranslate; 289 std::function<void()> onSearch; 290 std::function<void()> onShare; 291 std::function<void()> onCameraInput; 292 std::function<void()> onAIWrite; 293 std::function<void(std::string)> onAIMenuOption; 294 std::function<void()> onAskCelia; 295 296 std::function<void()> onAppear; 297 std::function<void()> onDisappear; 298 std::function<void()> onMenuShow; 299 std::function<void()> onMenuHide; 300 std::function<bool()> showMenuOnMoveDone; 301 }; 302 303 struct SelectedByMouseInfo { 304 WeakPtr<FrameNode> selectedNode; 305 std::function<void()> onResetSelection; 306 307 bool operator!=(const SelectedByMouseInfo& info) const 308 { 309 CHECK_NULL_RETURN(selectedNode.Upgrade(), true); 310 CHECK_NULL_RETURN(info.selectedNode.Upgrade(), true); 311 return selectedNode.Upgrade() != info.selectedNode.Upgrade(); 312 } 313 clearSelectedByMouseInfo314 void clear() 315 { 316 selectedNode.Reset(); 317 onResetSelection = nullptr; 318 } 319 }; 320 321 struct CallerFrameNodeInfo { 322 RectF paintFrameRect; 323 OffsetF paintOffset; 324 }; 325 326 enum class SelectOverlayMode { 327 ALL, MENU_ONLY, HANDLE_ONLY 328 }; 329 330 enum class HandleLevelMode { 331 OVERLAY, EMBED 332 }; 333 334 struct SelectOverlayInfo { 335 WeakPtr<Pattern> pattern; 336 bool isUsingMouse = false; 337 bool isSingleHandle = false; 338 // when handleReverse is true, The first one is on the right side of the second. 339 bool handleReverse = false; 340 // Used to determine the range of judgment that is parallel to the first and second handles. 341 float singleLineHeight = 10.0f; 342 bool isSelectRegionVisible = false; 343 bool isNewAvoid = false; 344 bool recreateOverlay = false; 345 bool isUseOverlayNG = false; 346 SelectHandleInfo firstHandle; 347 SelectHandleInfo secondHandle; 348 std::function<bool(const RectF&, const RectF&)> checkHandleReverse; 349 std::optional<Color> handlerColor; 350 HitTestMode hitTestMode = HitTestMode::HTMTRANSPARENT_SELF; 351 352 // show area 353 bool useFullScreen = true; 354 RectF showArea; 355 RectF selectArea; 356 357 OffsetF rightClickOffset; 358 359 // handle touch event 360 std::function<void(const TouchEventInfo&)> onTouchDown; 361 std::function<void(const TouchEventInfo&)> onTouchUp; 362 std::function<void(const TouchEventInfo&)> onTouchMove; 363 std::function<void(const GestureEvent&, bool isFirst)> onClick; 364 std::function<void(const GestureEvent&, bool isFirst)> afterOnClick; 365 std::function<void(const MouseInfo&)> onMouseEvent; 366 367 // handle move callback. 368 std::function<void(const GestureEvent&, bool isFirst)> onHandleMoveStart; 369 std::function<void(const RectF&, bool isFirst)> onHandleMove; 370 std::function<void(const RectF&, bool isFirst)> onHandleMoveDone; 371 std::function<void(bool)> onHandleReverse; 372 373 std::function<void(const GestureEvent&, bool isFirst)> onHandlePanMove; 374 std::function<void(const GestureEvent&, bool isFirst)> onHandlePanEnd; 375 std::function<OffsetF()> getDeltaHandleOffset; 376 377 // menu info. 378 SelectMenuInfo menuInfo; 379 SelectMenuCallback menuCallback; 380 381 std::vector<MenuOptionsParam> menuOptionItems; 382 OnMenuItemCallback onCreateCallback; 383 384 // force hide callback, which may be called when other textOverlay shows. 385 std::function<void(bool)> onClose; 386 387 std::function<bool(const PointF&)> checkIsTouchInHostArea; 388 std::function<void()> onHandleIsHidden; 389 390 OHOS::Ace::WeakPtr<FrameNode> callerFrameNode; 391 std::optional<CallerFrameNodeInfo> callerNodeInfo; 392 std::optional<RectF> ancestorViewPort; 393 394 bool isHandleLineShow = true; 395 std::string selectText; 396 bool isSingleLine = false; 397 398 HandleLevelMode handleLevelMode = HandleLevelMode::OVERLAY; 399 bool enableHandleLevel = false; 400 VectorF scale = VectorF(1.0f, 1.0f); 401 bool clipHandleDrawRect = false; 402 std::optional<RectF> clipViewPort; 403 ToStringSelectOverlayInfo404 std::string ToString() const 405 { 406 auto jsonValue = JsonUtil::Create(true); 407 JSON_STRING_PUT_INT(jsonValue, handleLevelMode); 408 JSON_STRING_PUT_BOOL(jsonValue, isUsingMouse); 409 JSON_STRING_PUT_BOOL(jsonValue, isSingleHandle); 410 JSON_STRING_PUT_BOOL(jsonValue, handleReverse); 411 JSON_STRING_PUT_BOOL(jsonValue, isSelectRegionVisible); 412 JSON_STRING_PUT_BOOL(jsonValue, isNewAvoid); 413 JSON_STRING_PUT_BOOL(jsonValue, recreateOverlay); 414 JSON_STRING_PUT_BOOL(jsonValue, isUseOverlayNG); 415 JSON_STRING_PUT_STRINGABLE(jsonValue, firstHandle); 416 JSON_STRING_PUT_STRINGABLE(jsonValue, secondHandle); 417 JSON_STRING_PUT_STRINGABLE(jsonValue, showArea); 418 JSON_STRING_PUT_STRINGABLE(jsonValue, selectArea); 419 JSON_STRING_PUT_STRINGABLE(jsonValue, rightClickOffset); 420 JSON_STRING_PUT_STRING(jsonValue, selectText); 421 return jsonValue->ToString(); 422 } 423 424 void GetCallerNodeAncestorViewPort(RectF& viewPort); 425 const RectF& GetFirstHandlePaintRect(); 426 const RectF& GetSecondHandlePaintRect(); 427 bool enableSubWindowMenu = false; 428 OffsetF containerModalOffset; 429 430 // menu avoid keyboard adjust ark_ui and web 431 std::function<bool(LayoutWrapper *, OffsetF &, const RectF, OffsetF &, std::shared_ptr<SelectOverlayInfo> &)> 432 computeMenuOffset = nullptr; 433 }; 434 435 enum class TextMenuShowMode { 436 BEGIN = -1, 437 UNSPECIFIED = BEGIN, 438 // Display the text selection menu in the current window 439 DEFAULT = 0, 440 /** 441 * Prefer to display the text selection menu in a separate window 442 * and continue to display it within the current window if a separate window is not supported 443 */ 444 PREFER_WINDOW = 1, 445 END = PREFER_WINDOW, 446 }; 447 448 TextMenuShowMode CastToTextMenuShowMode(int32_t value); 449 450 struct TextMenuOptions { 451 std::optional<TextMenuShowMode> showMode; 452 }; 453 454 #define DEFINE_MENU_CHECK_METHOD(name) bool IsShow##name() 455 456 #define DEFINE_MENU_CHECK_METHOD_IMPL(name, flag) \ 457 bool IsShow##name() { \ 458 return !IsDisableMenuItem(flag); \ 459 } \ 460 461 namespace TextSystemMenu { 462 bool IsDisableMenuItem(SystemServiceMenuDisableFlag flag); 463 DEFINE_MENU_CHECK_METHOD(Translate); 464 DEFINE_MENU_CHECK_METHOD(Search); 465 DEFINE_MENU_CHECK_METHOD(Share); 466 DEFINE_MENU_CHECK_METHOD(CameraInput); 467 DEFINE_MENU_CHECK_METHOD(AIWriter); 468 DEFINE_MENU_CHECK_METHOD(CollaborationService); 469 DEFINE_MENU_CHECK_METHOD(AIUrl); 470 DEFINE_MENU_CHECK_METHOD(AIPhone); 471 DEFINE_MENU_CHECK_METHOD(AIEmail); 472 DEFINE_MENU_CHECK_METHOD(AIAddress); 473 DEFINE_MENU_CHECK_METHOD(AIDatetime); 474 DEFINE_MENU_CHECK_METHOD(AskCelia); 475 } // namespace TextSystemMenu 476 } // namespace OHOS::Ace::NG 477 478 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SELECT_OVERLAY_PROPERTY_H 479